您正在查看 Apigee Edge 文档。
前往 Apigee X 文档。 信息
问题
当客户端和服务器无法使用 TLS/SSL 协议建立通信时,就会发生 TLS/SSL 握手失败。如果 Apigee Edge 中出现此错误,客户端应用会收到 HTTP 状态 503,并显示消息 Service Unavailable。在发生任何 TLS/SSL 握手失败的 API 调用后,您都会看到此错误。
错误消息
HTTP/1.1 503 Service Unavailable
当 TLS/SSL 握手失败时,您也可能会看到此错误消息:
Received fatal alert: handshake_failure
可能的原因
TLS(传输层安全协议,其前身是 SSL)是一种标准的安全技术,用于在网络服务器与网络客户端(例如浏览器或应用)之间建立加密链接。握手是一种流程,可让 TLS/SSL 客户端和服务器建立一组可用于通信的密钥。在此过程中,客户端和服务器:
- 就使用的协议版本达成一致。
- 选择要使用的加密算法。
- 通过交换和验证数字证书来相互验证身份。
如果 TLS/SSL 握手成功,则 TLS/SSL 客户端和服务器会安全地相互传输数据。否则,如果发生 TLS/SSL 握手失败,连接将被终止,并且客户端会收到 503 Service Unavailable 错误。
TLS/SSL 握手失败的可能原因包括:
| 原因 | 说明 | 谁可以执行问题排查步骤 |
|---|---|---|
| 协议不匹配 | 客户端使用的协议不受服务器支持。 | 私有云和公有云用户 |
| 加密套件不匹配 | 客户端使用的加密套件不受服务器支持。 | 私有云和公有云用户 |
| 证书不正确 | 客户端所用网址中的主机名与存储在服务器端证书中的主机名不匹配。 | 私有云和公有云用户 |
| 客户端或服务器端存储的证书链不完整或无效。 | 私有云和公有云用户 | |
| 客户端向服务器发送或服务器向客户端发送的证书不正确或已过期。 | 私有云和公有云用户 | |
| 已启用 SNI 的服务器 | 后端服务器已启用服务器名称指示 (SNI);但是,客户端无法与 SNI 服务器通信。 | 仅限私有云用户 |
协议不匹配
如果客户端使用的协议在入站(北向)或出站(南向)连接中不受服务器支持,则会发生 TLS/SSL 握手失败。另请参阅 了解北向连接和南向连接。
诊断
- 确定错误是发生在北向连接还是南向连接中。如需有关如何做出此判定的进一步指导,请参阅 确定问题来源。
- 运行
tcpdump 实用程序以收集更多信息:
- 如果您是私有云用户,则可以在相关客户端或服务器上收集
tcpdump数据。客户端可以是客户端应用(对于入站或北向连接),也可以是消息处理器(对于出站或南向连接)。根据您在第 1 步中的确定,服务器可以是边缘路由器(用于入站或北向连接),也可以是后端服务器(用于出站或南向连接)。 - 如果您是公共云用户,则只能在客户端应用(对于入站或北向连接)或后端服务器(对于出站或南向连接)上收集
tcpdump数据,因为您无权访问边缘路由器或消息处理器。
如需详细了解如何使用tcpdump -i any -s 0 host IP address -w File name
tcpdump命令,请参阅 tcpdump 数据。 - 如果您是私有云用户,则可以在相关客户端或服务器上收集
- 使用 Wireshark 工具或类似工具分析
tcpdump数据。 - 下面是使用 Wireshark 对
tcpdump 进行的分析示例:
- 在此示例中,TLS/SSL 握手失败发生在消息处理器和后端服务器(传出或南向连接)之间。
- 以下
tcpdump输出中的消息 4 显示,消息处理器(来源)向后端服务器(目的地)发送了“Client Hello”消息。

如果您选择
Client Hello消息,则表示消息处理器正在使用 TLSv1.2 协议,如下所示:
- 消息 5 显示,后端服务器确认了来自消息处理器的“Client Hello”消息。
- 后端服务器立即向消息处理器发送 Fatal Alert : Close Notify(消息 #6)。这意味着 TLS/SSL 握手失败,连接将被关闭。
进一步查看消息 #6,发现 TLS/SSL 握手失败的原因是后端服务器仅支持 TLSv1.0 协议,如下所示:

- 由于消息处理器和后端服务器使用的协议不匹配,后端服务器发送了消息:Fatal Alert Message: Close Notify。
分辨率
消息处理器在 Java 8 上运行,默认使用 TLSv1.2 协议。如果后端服务器不支持 TLSv1.2 协议,您可以采取以下任一步骤来解决此问题:
- 升级您的后端服务器,以支持 TLSv1.2 协议。我们推荐采用此解决方案,因为 TLSv1.2 协议更安全。
- 如果您因某种原因无法立即升级后端服务器,可以按照以下步骤强制消息处理器使用 TLSv1.0 协议与后端服务器通信:
- 如果您未在代理的 TargetEndpoint 定义中指定目标服务器,请将
Protocol元素设置为TLSv1.0,如下所示:<TargetEndpoint name="default"> … <HTTPTargetConnection> <SSLInfo> <Enabled>true</Enabled> <Protocols> <Protocol>TLSv1.0</Protocol> </Protocols> </SSLInfo> <URL>https://myservice.com</URL> </HTTPTargetConnection> … </TargetEndpoint> - 如果您为代理配置了 目标服务器,请使用 此管理 API 将特定目标服务器配置中的协议设置为 TLSv1.0。
- 如果您未在代理的 TargetEndpoint 定义中指定目标服务器,请将
Cipher Mismatch
如果客户端使用的加密套件算法不受服务器支持,无论是在 Apigee Edge 中的入站(北向)连接还是出站(南向)连接中,您都可能会看到 TLS/SSL 握手失败。 另请参阅 了解北向连接和南向连接。
诊断
- 确定错误是发生在北向连接还是南向连接中。 如需有关如何做出此判定的进一步指导,请参阅确定问题来源。
- 运行
tcpdump 实用程序以收集更多信息:
- 如果您是私有云用户,则可以在相关客户端或服务器上收集
tcpdump数据。客户端可以是客户端应用(对于入站或北向连接),也可以是消息处理器(对于出站或南向连接)。根据您在第 1 步中的确定,服务器可以是边缘路由器(用于入站或北向连接),也可以是后端服务器(用于出站或南向连接)。 - 如果您是公共云用户,则只能在客户端应用(对于入站或北向连接)或后端服务器(对于出站或南向连接)上收集
tcpdump数据,因为您无权访问边缘路由器或消息处理器。
如需详细了解如何使用tcpdump -i any -s 0 host IP address -w File name
tcpdump命令,请参阅 tcpdump 数据。 - 如果您是私有云用户,则可以在相关客户端或服务器上收集
- 使用 Wireshark 工具或您熟悉的任何其他工具分析
tcpdump数据。 - 下面是使用 Wireshark 对
tcpdump输出进行的分析示例:- 在此示例中,TLS/SSL 握手失败发生在客户端应用和 Edge 路由器(北向连接)之间。
tcpdump输出是在 Edge 路由器上收集的。 以下
tcpdump输出中的消息 #4 显示,客户端应用(来源)向 Edge 路由器(目的地)发送了“Client Hello”消息。
选择“Client Hello”消息可显示客户端应用正在使用 TLSv1.2 协议。

- 消息 5 表明边缘路由器确认了来自客户端应用的“Client Hello”消息。
- Edge 路由器立即向客户端应用发送 Fatal Alert : Handshake Failure(消息 #6)。这意味着 TLS/SSL 握手失败,连接将被关闭。
- 进一步查看消息 #6,会显示以下信息:
- Edge 路由器支持 TLSv1.2 协议。这意味着客户端应用与边缘路由器之间的协议匹配。
不过,Edge 路由器仍会向客户端应用发送 Fatal Alert: Handshake Failure(严重警告:握手失败),如下面的屏幕截图所示:

- 此错误可能是由以下某个问题造成的:
- 客户端应用未使用 Edge 路由器支持的加密套件算法。
- Edge 路由器已启用 SNI,但客户端应用未发送服务器名称。
tcpdump输出中的消息 4 列出了客户端应用支持的加密套件算法,如下所示:
- Edge 路由器支持的加密套件算法列表位于
/opt/nginx/conf.d/0-default.conf文件中。在此示例中,边缘路由器仅支持高加密加密套件算法。 - 客户端应用未使用任何高加密加密套件算法。这种不匹配是导致 TLS/SSL 握手失败的原因。
- 由于 Edge 路由器已启用 SNI,请向下滚动到
tcpdump输出中的消息 #4,并确认客户端应用正在正确发送服务器名称,如下图所示:

- 如果此名称有效,您可以推断出 TLS/SSL 握手失败是因为客户端应用使用的加密套件算法不受 Edge 路由器的支持。
- 在此示例中,TLS/SSL 握手失败发生在客户端应用和 Edge 路由器(北向连接)之间。
分辨率
您必须确保客户端使用服务器支持的加密套件算法。如需解决上一个“诊断”部分中所述的问题,请下载并安装 Java 加密扩展 (JCE) 软件包,并将其包含在 Java 安装中,以支持高加密加密套件算法。
证书不正确
如果在密钥库/信任库中存在不正确的证书,则会在 Apigee Edge 中发生 TLS/SSL 握手失败,无论是在入站(北向)连接还是出站(南向)连接中。 另请参阅 了解北向连接和南向连接。
如果问题是北向的,那么您可能会看到不同的错误消息,具体取决于根本原因。
以下部分列出了示例错误消息,以及用于诊断和解决此问题的步骤。
错误消息
您可能会看到不同的错误消息,具体取决于 TLS/SSL 握手失败的原因。 以下是您在调用 API 代理时可能会看到的错误消息示例:
* SSL certificate problem: Invalid certificate chain * Closing connection 0 curl: (60) SSL certificate problem: Invalid certificate chain More details here: http://curl.haxx.se/docs/sslcerts.html
可能的原因
此问题的典型原因包括:
| 原因 | 说明 | 谁可以执行问题排查步骤 |
| 主机名不一致 |
网址中使用的主机名与路由器密钥库中的证书不一致。例如,如果网址中使用的主机名为 myorg.domain.com,而证书的 CN 中的主机名为 CN=something.domain.com.,则会发生不匹配的情况
|
Edge Private Cloud 和 Public Cloud 用户 |
| 证书链不完整或不正确 | 证书链不完整或不正确。 | 仅限 Edge Private Cloud 和 Public Cloud 用户 |
| 服务器或客户端发送的证书已过期或未知 | 服务器或客户端在北向或南向连接中发送了过期或未知证书。 | Edge Private Cloud 和 Edge Public Cloud 用户 |
主机名不一致
诊断
- 请注意以下 Edge 管理 API 调用返回的网址中使用的主机名:
例如:curl -v https://myorg.domain.com/v1/getinfo
curl -v https://api.enterprise.apigee.com/v1/getinfo
- 获取存储在特定密钥库中的证书所使用的 CN。您可以使用以下 Edge 管理 API 获取证书的详细信息:
-
获取密钥库中的证书名称:
如果您是私有云用户,请按如下方式使用 Management API:
如果您是公共云用户,请按如下方式使用 Management API:curl -v https://management-server-ip:port/v1/organizations/org-name/environments/env-name/keystores/keystore-name/certs
curl -v https://api.enterprise.apigee.com/v1/organizations/org-name/environments/env-name/keystores/keystore-name/certs
-
使用 Edge Management API 获取密钥库中证书的详细信息。
如果您是 Private Cloud 用户:
如果您是公有云用户:curl -v https://management-server-ip:port/v1/organizations/org-name/environments/env-name/keystores/keystore-name/certs/cert-name
curl -v https://api.enterprise.apigee.com/v1/organizations/org-name/environments/env-name/keystores/keystore-name/certs/cert-name
示例证书:
"certInfo": [ { "basicConstraints": "CA:FALSE", "expiryDate": 1456258950000, "isValid": "No", "issuer": "SERIALNUMBER=07969287, CN=Go Daddy Secure Certification Authority, OU=http://certificates.godaddy.com/repository, O=\"GoDaddy.com, Inc.\", L=Scottsdale, ST=Arizona, C=US", "publicKey": "RSA Public Key, 2048 bits", "serialNumber": "07:bc:a7:39:03:f1:56", "sigAlgName": "SHA1withRSA", "subject": "CN=something.domain.com, OU=Domain Control Validated, O=something.domain.com", "validFrom": 1358287055000, "version": 3 },
主证书中的正文名称的 CN 为
something.domain.com.由于 API 请求网址(请参阅上文中的第 1 步)中使用的主机名与证书中的主题名称不匹配,因此您会收到 TLS/SSL 握手失败错误。
-
获取密钥库中的证书名称:
分辨率
您可以通过以下两种方式之一解决此问题:
- 获取一个主题 CN 具有通配符证书的证书(如果您还没有),然后将新的完整证书链上传到密钥库。例如:
"subject": "CN=*.domain.com, OU=Domain Control Validated, O=*.domain.com",
- 获取具有现有主题 CN 的证书(如果您还没有),但使用 your-org。your-domain 作为正文备用名称,然后将完整的证书链上传到密钥库。
参考
证书链不完整或不正确
诊断
- 获取存储在特定密钥库中的证书所使用的 CN。您可以使用以下 Edge 管理 API 获取证书的详细信息:
-
获取密钥库中的证书名称:
如果您是 Private Cloud 用户:
如果您是公有云用户:curl -v https://management-server-ip:port/v1/organizations/org-name/environments/env-name/keystores/keystore-name/certs
curl -v https://api.enterprise.apigee.com/v1/organizations/org-name/environments/env-name/keystores/keystore-name/certs
-
获取密钥库中证书的详细信息:
如果您是 Private Cloud 用户:
如果您是公有云用户:curl -v https://management-server-ip:port/v1/organizations/org-name/environments/env-name/keystores/keystore-name/certs/cert-name
curl -v https://api.enterprise.apigee.com/v1/organizations/org-name/environments/env-name/keystores/keystore-name/certs/cert-name
- 验证证书及其链,并验证其是否符合 证书链的工作原理一文中所述的准则,以确保其是有效且完整的证书链。如果密钥库中存储的证书链不完整或无效,您会看到 TLS/SSL 握手失败。
- 下图显示了一个证书链无效的示例证书,其中中间证书和根证书不匹配:
签发者与正文不一致的中间证书和根证书示例

-
获取密钥库中的证书名称:
分辨率
- 获取包含完整有效证书链的证书(如果您还没有证书)。
- 运行以下 openssl 命令,验证证书链是否正确且完整:
openssl verify -CAfile root-cert -untrusted intermediate-cert main-cert
- 将经过验证的证书链上传到密钥库。
服务器或客户端发送的证书已过期或未知
如果服务器/客户端在北向或南向连接中发送了错误/过期的证书,则另一端(服务器/客户端)会拒绝该证书,从而导致 TLS/SSL 握手失败。
诊断
- 确定错误是发生在北向连接还是南向连接中。如需有关如何做出此判定的进一步指导,请参阅 确定问题来源。
- 运行
tcpdump 实用程序以收集更多信息:
- 如果您是私有云用户,则可以在相关客户端或服务器上收集
tcpdump数据。客户端可以是客户端应用(对于入站或北向连接),也可以是消息处理器(对于出站或南向连接)。根据您在第 1 步中的确定,服务器可以是边缘路由器(用于入站或北向连接),也可以是后端服务器(用于出站或南向连接)。 - 如果您是公共云用户,则只能在客户端应用(对于入站或北向连接)或后端服务器(对于出站或南向连接)上收集
tcpdump数据,因为您无权访问边缘路由器或消息处理器。
如需详细了解如何使用tcpdump -i any -s 0 host IP address -w File name
tcpdump命令,请参阅 tcpdump 数据。 - 如果您是私有云用户,则可以在相关客户端或服务器上收集
- 使用 Wireshark 或类似工具分析
tcpdump数据。 - 从
tcpdump输出中,确定在验证步骤中拒绝证书的主机(客户端或服务器)。 - 如果数据未加密,您可以从
tcpdump输出中检索另一端发送的证书。这有助于比较此证书是否与信任库中提供的证书相匹配。 - 查看消息处理器与后端服务器之间 SSL 通信的示例
tcpdump。示例
tcpdump显示“证书未知”错误
- 消息处理器(客户端)在消息 #59 中向后端服务器(服务器)发送“Client Hello”。
- 后端服务器在消息 #61 中向消息处理器发送“Server Hello”。
- 它们会相互验证所使用的协议和加密套件算法。
- 后端服务器在消息 #68 中将证书和 Server Hello Done 消息发送到消息处理器。
- 消息处理器在消息 #70 中发送严重警报 “说明:证书未知”。
- 进一步查看消息 #70,除了提醒消息之外,没有其他详细信息,如下所示:

- 查看消息 #68,详细了解后端服务器发送的证书,如下图所示:

- 后端服务器的证书及其完整链条均可在“证书”部分下找到,如上图所示。
- 如果路由器(北向)或消息处理器(南向)发现证书未知(如上例所示),请按以下步骤操作:
- 获取存储在特定信任库中的证书及其链。(请参阅路由器的虚拟主机配置和消息处理器的目标端点配置)。您可以使用以下 API 获取证书的详细信息:
-
获取信任库中的证书名称:
curl -v https://management-server-ip:port/v1/organizations/org-name/environments/env-name/keystores/truststore-name/certs
-
获取信任库中证书的详细信息:
curl -v https://management-server-ip:port/v1/organizations/org-name/environments/env-name/keystores/truststore-name/certs/cert-name
-
获取信任库中的证书名称:
- 检查路由器(北向)或消息处理器(南向)的信任库中存储的证书是否与客户端应用(北向)或目标服务器(南向)的密钥库中存储的证书相匹配,或者是否与从
tcpdump输出中获得的证书相匹配。如果存在不匹配的情况,则会导致 TLS/SSL 握手失败。
- 获取存储在特定信任库中的证书及其链。(请参阅路由器的虚拟主机配置和消息处理器的目标端点配置)。您可以使用以下 API 获取证书的详细信息:
- 如果客户端应用(北向)或目标服务器(南向)发现证书未知,请按以下步骤操作:
- 获取存储在特定密钥库中的证书所使用的完整证书链。(请参阅路由器的虚拟主机配置和消息处理器的目标端点配置。)您可以使用以下 API 获取证书的详细信息:
-
获取密钥库中的证书名称:
curl -v https://management-server-ip:port/v1/organizations/org-name/environments/env-name/keystores/keystore-name/certs
-
获取密钥库中证书的详细信息:
curl -v https://management-server-ip:port/v1/organizations/org-name/environments/env-name/keystores/keystore-name/certs/cert-name
-
获取密钥库中的证书名称:
- 检查路由器(北向)或消息处理器(南向)的密钥库中存储的证书是否与客户端应用(北向)或目标服务器(南向)的信任库中存储的证书相匹配,或者是否与从
tcpdump输出中获得的证书相匹配。如果存在不一致的情况,则会导致 SSL 握手失败。
- 获取存储在特定密钥库中的证书所使用的完整证书链。(请参阅路由器的虚拟主机配置和消息处理器的目标端点配置。)您可以使用以下 API 获取证书的详细信息:
- 如果发现服务器/客户端发送的证书已过期,接收客户端/服务器会拒绝该证书,并且您会在
tcpdump中看到以下提醒消息:提醒(级别:严重,说明:证书已过期)
- 验证相应主机的密钥库中的证书是否已过期。
分辨率
如需解决上述示例中指出的问题,请将有效的后端服务器证书上传到消息处理器的信任库。
下表总结了解决问题所需的步骤,具体取决于问题的原因。
| 原因 | 说明 | 解决方法 |
| 证书已过期 |
NorthBound
|
将新证书及其完整链上传到相应主机上的密钥库。 |
SouthBound
|
将新证书及其完整链上传到相应主机上的密钥库。 | |
| 未知证书 |
NorthBound
|
将有效证书上传到相应主机上的信任库。 |
SouthBound
|
将有效证书上传到相应主机上的信任库。 |
已启用 SNI 的服务器
当客户端与启用了服务器名称指示 (SNI) 的服务器通信时,如果客户端未启用 SNI,则可能会发生 TLS/SSL 握手失败。这种情况可能发生在 Edge 的北向或南向连接中。
首先,您需要确定所用服务器的主机名和端口号,并检查该服务器是否已启用 SNI。
启用 SNI 的服务器的标识
- 执行
openssl命令,然后尝试连接到相关的服务器主机名(Edge 路由器或后端服务器),但不要传递服务器名称,如下所示: 您可能会获得证书,有时可能会在 openssl 命令中观察到握手失败,如下所示:openssl s_client -connect hostname:port
CONNECTED(00000003) 9362:error:14077410:SSL routines:SSL23_GET_SERVER_HELLO:sslv3 alert handshake failure:/BuildRoot/Library/Caches/com.apple.xbs/Sources/OpenSSL098/OpenSSL098-64.50.6/src/ssl/s23_clnt.c:593
- 执行
openssl命令,然后尝试通过传递服务器名称来连接到相关的服务器主机名(Edge 路由器或后端服务器),如下所示:openssl s_client -connect hostname:port -servername hostname
- 如果您在第 1 步中遇到握手失败,或者在第 1 步和第 2 步中获得不同的证书,则表明指定的服务器已启用 SNI。
确定服务器已启用 SNI 后,您可以按照以下步骤检查 TLS/SSL 握手失败是否是由客户端无法与 SNI 服务器通信引起的。
诊断
- 确定错误是发生在北向连接还是南向连接中。如需有关如何做出此判定的进一步指导,请参阅 确定问题来源。
- 运行
tcpdump 实用程序以收集更多信息:
- 如果您是私有云用户,则可以在相关客户端或服务器上收集
tcpdump数据。客户端可以是客户端应用(对于入站或北向连接),也可以是消息处理器(对于出站或南向连接)。根据您在第 1 步中的确定,服务器可以是边缘路由器(用于入站或北向连接),也可以是后端服务器(用于出站或南向连接)。 - 如果您是公共云用户,则只能在客户端应用(对于入站或北向连接)或后端服务器(对于出站或南向连接)上收集
tcpdump数据,因为您无权访问边缘路由器或消息处理器。
如需详细了解如何使用tcpdump -i any -s 0 host IP address -w File name
tcpdump命令,请参阅 tcpdump 数据。 - 如果您是私有云用户,则可以在相关客户端或服务器上收集
- 使用 Wireshark 或类似工具分析
tcpdump输出。 - 下面是使用 Wireshark 对
tcpdump进行的分析示例:- 在此示例中,TLS/SSL 握手失败发生在 Edge 消息处理器和后端服务器(南向连接)之间。
- 以下
tcpdump输出中的消息 #4 显示,消息处理器(来源)向后端服务器(目的地)发送了“Client Hello”消息。
- 选择“Client Hello”消息可显示消息处理器正在使用 TLSv1.2 协议。

- 消息 #4 表明后端服务器确认了来自消息处理器的“Client Hello”消息。
- 后端服务器立即向消息处理器发送 Fatal Alert : Handshake Failure(消息 #5)。这意味着 TLS/SSL 握手失败,连接将被关闭。
- 查看消息 6,了解以下信息
- 后端服务器支持 TLSv1.2 协议。这意味着消息处理器和后端服务器之间的协议匹配。
- 不过,后端服务器仍会向消息处理器发送严重提醒:握手失败,如下图所示:

- 此错误可能是由以下某种原因造成的:
- 消息处理器未使用后端服务器支持的加密套件算法。
- 后端服务器已启用 SNI,但客户端应用未发送服务器名称。
- 更详细地查看
tcpdump输出中的消息 #3(客户端 Hello)。请注意,如下所示,缺少 Extension: server_name:
- 这确认了消息处理器未将 server_name 发送到启用 SNI 的后端服务器。
- 这是导致 TLS/SSL 握手失败的原因,也是后端服务器向消息处理器发送严重提醒:握手失败的原因。
- 验证消息处理器上
system.properties中的jsse.enableSNIExtension property是否设置为 false,以确认消息处理器未启用与启用 SNI 的服务器通信。
分辨率
通过执行以下步骤,使消息处理器能够与启用 SNI 的服务器通信:
- 创建
/opt/apigee/customer/application/message-processor.properties文件(如果尚不存在)。 - 将以下代码行添加到此文件中:
conf_system_jsse.enableSNIExtension=true - 将此文件的所有者更改为
apigee:apigee:chown apigee:apigee /opt/apigee/customer/application/message-processor.properties
- 重启消息处理器。
/opt/apigee/apigee-service/bin/apigee-service message-processor restart
- 如果您有多个消息处理器,请在所有消息处理器上重复执行第 1 步到第 4 步。
如果您无法确定 TLS/SSL 握手失败的原因并解决问题,或者需要任何进一步的帮助,请与 Apigee Edge 支持团队联系。分享有关问题的完整详细信息以及 tcpdump 输出。