您正在查看的是 Apigee Edge 文档。
转到 Apigee X 文档。 信息
问题
客户端应用收到 HTTP 400 - Bad request 响应以及消息“SSL Certificate error”。此错误通常由边缘路由器通过为到 Apigee Edge 的传入连接启用双向 TLS 设置发送。
错误消息
客户端应用会获得以下响应代码:
HTTP/1.1 400 Bad Request
接下来是以下 HTML 错误页面:
<html> <head> <title>400 The SSL certificate error</title> </head> <body bgcolor="white"> <center> <h1>400 Bad Request</h1> </center> <center>The SSL certificate error</center> <hr> <center>nginx</center> </body> </html>
可能的原因
导致此问题的可能原因如下:
原因 | 说明 | 问题排查说明适用于 |
客户端证书已过期 | 客户端发送的证书已过期。 | Edge Private 和公有云用户 |
客户端发送的证书不正确 | 如果客户端应用发送的证书与存储在 Edge 路由器信任库中的证书不匹配,则会引发此错误。 | Edge Private 和公有云用户 |
Truststore 中缺少客户端根证书 | 如果 Edge 路由器的信任库中缺少客户端 CA 签名的根证书,则会抛出此错误。 | Edge Private 和公有云用户 |
未在边缘路由器中加载的客户端证书 | 如果上传到信任库的客户端证书未加载到路由器上,则会抛出此错误。 | Edge Private Cloud 用户 |
原因:客户端证书已过期
当客户端发送的证书已过期时,双向 TLS 通常会出现此问题。在双向 TLS 中,客户端和服务器会交换其公共证书以完成握手。客户端会验证服务器证书,服务器会验证客户端证书。
在 Edge 中,双向 TLS 在虚拟主机上实现,在这种情况下,服务器证书会添加到密钥库,而客户端证书会添加到信任存储区。
在 TLS 握手期间,如果发现客户端证书已过期,服务器将发送 400 - Bad request 以及消息“SSL Certificate error”。
诊断
登录 Edge 界面并查看正在为其发出 API 请求的特定虚拟主机配置 (Admin > Virtual Hosts),或使用 Get virtual host API Management API 获取特定虚拟主机的定义。
通常,用于双向 TLS 通信的虚拟主机如下所示:
<VirtualHost name="myTLSVHost"> <HostAliases> <HostAlias>api.myCompany.com</HostAlias> </HostAliases> <Port>443</Port> <SSLInfo> <Enabled>true</Enabled> <ClientAuthEnabled>true</ClientAuthEnabled> <KeyStore>ref://myKeystoreRef</KeyStore> <KeyAlias>myKeyAlias</KeyAlias> <TrustStore>ref://myTruststoreRef</TrustStore> </SSLInfo> </VirtualHost>
确定虚拟主机中使用的 Truststore 引用。在上面的示例中,Truststore 引用名称为 myTruststoreRef.
- 确定 Truststore 引用所指向的 Truststore。
- 在 Edge 界面中,依次转到管理 > 环境 > 引用,然后搜索 Truststore 引用名称。
请记下 Reference 列中特定 Truststore 引用的名称。 这将是您的信任库名称。
请注意,在上面的示例中,myTruststoreRef 引用了 myTruststore。因此,Truststore 名称为 myTruststore。
- 在边缘界面的管理 > 环境 > TLS 密钥库中,前往“TLS 密钥库”,然后查找在第 3 步中找到的信任库。
在特定 Truststore 下选择证书(在上面的第 3 步中确定),如下所示:
在上例中,别名为
client-cert-markw
的证书显示该证书已过期。- 检查信任库的证书别名的证书是否已过期。
- 如果证书未过期,请转到其他原因的常见诊断步骤。
分辨率
获取新证书并上传证书:
- 创建新的信任库,例如 myNewTruststore。
- 将新证书上传到新创建的信任库。
按照修改引用中给定的步骤,修改特定虚拟主机中使用的信任方引用,以指向新的信任库。
在上述示例中,将引用 myTruststoreRef 指向 myNewTruststore。
其他病因的常见诊断步骤
- 如需调查此问题,您需要使用 tcpdump 工具捕获 TCP/IP 数据包。
- 如果您是 Private Cloud 用户,则可以捕获客户端应用或路由器上的 TCP/IP 数据包。
- 如果您是公有云用户,请捕获客户端应用上的 TCP/IP 数据包。
在您确定要捕获 TCP/IP 数据包的位置后,请使用以下 tcpdump 命令捕获 TCP/IP 数据包:
tcpdump -i any -s 0 host <IP address> -w <File name>
注意:如果您要在路由器上接收 TCP/IP 数据包,请在
tcpdump
命令中使用客户端应用的公共 IP 地址。如果您要获取客户端应用上的 TCP/IP 数据包,请在
tcpdump
命令中使用虚拟主机中使用的主机名的公共 IP 地址。如需详细了解此工具以及此命令的其他变体,请参阅 tcpdump。
- 分析使用 Wireshark 工具或类似工具收集的 TCP/IP 数据包。
以下是使用 Wireshark 工具对示例 TCP/IP 数据包数据的分析:
- tcpdump 中的数据包 30(如下图)显示,客户端应用(来源)向路由器(目的地)发送了一条“Client Hello”消息。
- 数据包 #34 显示路由器确认来自客户端应用的客户端 Hello 消息。
- 路由器在数据包 35 中发送“服务器 Hello”,然后发送其证书,并在数据包 #38 中请求客户端应用发送其证书。
- 在数据包 #38 中,路由器会发送“Certificate Request”数据包,请查看“Distinguished Names”部分,其中提供了路由器(服务器)所接受的客户端证书、其链和证书授权机构的详细信息。
客户端应用在数据包 # 41 中发送其证书。查看数据包 # 41 中的证书验证部分,并确定客户端应用发送的证书。
- 验证客户端应用(数据包 41)发送的证书主题和颁发者及其链与路由器中接受的证书及其链(数据包 38)匹配。如果不匹配,则是导致此错误的原因。因此,路由器(服务器)向客户端应用发送加密提醒(数据包 57),接着发送 FIN、ACK(数据包 58),最终终止连接。
- 以下部分所述的场景可能会导致证书与其链不匹配。
原因:客户端发送的证书不正确
如果客户端应用发送的证书和/或其链的主题/颁发者与存储在路由器(服务器)信任库中的证书和/或其链不一致,通常就会发生这种情况。
诊断
登录 Edge 界面,并查看发出 API 请求的特定虚拟主机配置(管理 > 虚拟主机),或使用 Get virtual host API Management API 获取特定虚拟主机的定义。
通常,用于双向 TLS 通信的虚拟主机如下所示:
<VirtualHost name="myTLSVHost"> <HostAliases> <HostAlias>api.myCompany.com</HostAlias> </HostAliases> <Port>443</Port> <SSLInfo> <Enabled>true</Enabled> <ClientAuthEnabled>true</ClientAuthEnabled> <KeyStore>ref://myKeystoreRef</KeyStore> <KeyAlias>myKeyAlias</KeyAlias> <TrustStore>ref://myCompanyTruststoreRef</TrustStore> </SSLInfo> </VirtualHost>
- 确定虚拟主机中使用的 Truststore 引用。
在上面的示例中,Truststore 引用名称为 myCompanyTruststoreRef。
- 确定 Truststore 引用所指向的 Truststore。
- 在 Edge 界面中,依次转到管理 > 环境引用,然后搜索 Truststore 引用名称。
请记下 Reference 列中特定 Truststore 引用的名称。 这将是您的信任库名称。
请注意,在上面的示例中,myCompanyTruststoreRef 引用了 myCompanyTruststore。因此,Truststore 名称是 myCompanyTruststore。
- 使用以下 API 获取存储在 Truststore 中的证书(在上一步中确定):
-
此 API 会列出特定 Truststore 中的所有证书。
从密钥库或 Truststore API 获取证书详细信息。
此 API 会返回特定 Truststore 中特定证书的相关信息。
-
- 检查存储在 myCompanyTruststore 中的每个证书及其链的颁发者和主题是否与上述 TCP/IP 数据包(请参阅数据包 38)中所示的证书及其链一致。如果不一致,则表示上传到信任库的证书没有在边缘路由器中加载。移至原因:客户端证书未在边缘路由器中加载。
- 如果在第 5 步中未发现不匹配的情况,则表示客户端应用未发送正确的证书及其链。
分辨率
确保客户端应用向 Edge 发送正确的证书及其链。
原因:Truststore 中缺少客户端根证书
如果 Edge 路由器的信任库中缺少客户端 CA 签名的根证书,则会抛出此错误。
诊断
登录 Edge 界面并查看正在发出 API 请求的特定虚拟主机配置(管理 > 虚拟主机 > virtual_host),或使用 获取虚拟主机 API 获取特定虚拟主机的定义。
通常,用于双向 TLS 通信的虚拟主机如下所示:
<VirtualHost name="myTLSVHost"> <HostAliases> <HostAlias>api.myCompany.com</HostAlias> </HostAliases> <Port>443</Port> <SSLInfo> <Enabled>true</Enabled> <ClientAuthEnabled>true</ClientAuthEnabled> <KeyStore>ref://myKeystoreRef</KeyStore> <KeyAlias>myKeyAlias</KeyAlias> <TrustStore>ref://myCompanyTruststoreRef</TrustStore> </SSLInfo> </VirtualHost>
- 确定虚拟主机中使用的信任库引用。在前面的示例中,信任库引用名称为 myCompanyTruststoreRef.
- 确定信任库引用正在使用的实际信任库。
- 在 Edge 界面中,依次转到管理 > 环境 > 引用,然后搜索信任库引用名称。
特定信任库引用的信任库名称位于引用列中。
在此示例中,请注意 myCompanyTruststoreRef 在“Reference”列中有 myCompanyTruststore。因此,信任库名称为 myCompanyTruststore。
- 使用以下 API 获取存储在信任库中的证书(在上一步中确定):
- 列出密钥库或 Truststore API 的证书。此 API 列出了信任库中的所有证书。
- 从密钥库或 Truststore API 获取证书详细信息。此 API 会返回信任库中特定证书的相关信息。
检查证书是否包含完整的链,包括由特定客户端发送的根证书(如 TCP/IP 数据包中所示)(参见图 4)。信任库必须包含根证书以及客户端的叶证书(或叶证书和中间证书)。如果信任库中缺少客户端的有效根证书,这就是导致错误的原因。
但是,如果信任库中存在客户端的完整证书链(包括根证书),则表示上传到信任库的证书可能未加载到边缘路由器。在这种情况下,请参阅原因:客户端证书未在边缘路由器中加载。
分辨率
确保 Apigee Edge 路由器的信任库中提供正确的客户端证书(包括根证书)。
原因:未在边缘路由器中加载客户端证书
- 如果您是公有云用户,请与 Apigee Edge 支持团队联系。
- 如果您是 Private Cloud 用户,请在每个路由器上按照以下说明操作:
- 检查特定虚拟主机是否存在
/opt/nginx/conf.d/OrgName_envName_vhostName-client.pem
文件。如果该文件不存在,请转到下面的分辨率部分。 - 如果该文件存在,请使用以下
openssl
命令获取边缘路由器上可用证书的详细信息:openssl -in <OrgName_envName_vhostName-client.pem> -text -noout
- 请检查证书的颁发者、主题和到期日期。如果其中任何情况与在 Edge 界面中或使用管理 API 的 Truststore 中观察到的内容不一致,这就是导致错误的原因。
- 路由器可能没有重新加载上传的证书。
- 检查特定虚拟主机是否存在
分辨率
重启路由器,以确保通过以下步骤加载最新的证书:
apigee-service edge-router restart
重新运行 API 并检查结果。如果问题仍然存在,请转到收集诊断信息。
收集诊断信息
如果在按照上述说明操作后问题仍然存在,请收集以下诊断信息。 联系 Apigee Edge 支持团队并与他们分享您收集的信息:
- 如果您是公有云用户,请提供以下信息:
- 组织名称
- 环境名称
- API 代理名称
- 虚拟主机名
- 主机别名
- 完成 curl 命令以重现错误
- 客户端应用上捕获的 TCP/IP 数据包
- 如果您是 Private Cloud 用户,请提供以下信息:
- 使用获取虚拟主机 API 的虚拟主机名及其定义
- 主机别名
- 观察到了完整的错误消息
- 在客户端应用或路由器上捕获的 TCP/IP 数据包。
- List the Certificate from the keystore API API 的输出以及使用 Get cert details API 获取的每个证书的详情。
- 详细说明您尝试了本手册中的哪些部分,以及其他任何有助于我们快速解决此问题的数据分析。