SSL/TLS握手失败是什么?
SSL/TLS 握手失败(TLS Handshake Failed)是指客户端与服务器在建立 HTTPS 加密连接的过程中未能完成 TLS 握手。 常见表现包括浏览器提示 ERR_SSL_PROTOCOL_ERROR、SSL_ERROR_HANDSHAKE_FAILURE_ALERT,或者 CDN 返回 Cloudflare 525 等错误。
TLS 握手并不是单纯检查 SSL 证书。客户端与服务器需要协商 TLS 协议版本、密码套件、SNI、证书以及其他连接参数。如果其中某个环节无法满足双方要求,就可能导致握手失败。
排查这类问题时,不建议一开始就反复更换 SSL 证书。首先应该确定失败发生在哪一段连接,然后检查证书、证书链、SNI、TLS 协议和密码套件。
一、先判断TLS握手失败发生在哪里
网站如果接入了 CDN、WAF 或负载均衡,HTTPS 实际上可能存在两段甚至多段 TLS 连接:
用户浏览器
│
│ HTTPS / TLS
▼
CDN / WAF / 负载均衡
│
│ HTTPS / TLS
▼
源站服务器
因此,同样是“SSL握手失败”,故障位置可能完全不同。
1. 用户直接连接源站失败
如果用户绕过 CDN 后访问源站,或者网站本身没有使用 CDN,浏览器直接与 Nginx、Apache、IIS 等服务器建立 TLS 连接。
这时重点检查:
- SSL 证书是否有效;
- 证书域名是否匹配;
- 证书链是否完整;
- SNI 配置是否正确;
- TLS 版本是否兼容;
- 密码套件是否存在共同支持项;
- 服务器 443 端口是否正常监听。
2. CDN连接源站失败
如果用户访问 CDN 节点正常,但 CDN 无法通过 HTTPS 连接源站,则问题发生在CDN → 源站这一段。
Cloudflare 等 CDN 可能返回 525、526 等错误。这时直接在浏览器上反复检查客户端证书通常没有意义,应重点检查源站的 HTTPS 配置。
二、SSL/TLS握手失败的常见原因
1. TLS协议版本不兼容
客户端和服务器必须至少存在一个共同支持的 TLS 协议版本。
例如服务器只允许 TLS 1.3,而某个老旧客户端只能使用 TLS 1.2,那么双方就无法按照 TLS 1.3 建立连接。
反过来,如果服务器只支持过时的 TLS 1.0/1.1,而现代客户端已经禁用这些协议,同样可能导致连接失败。
可以检查 Nginx 等服务器的 TLS 配置,例如:
ssl_protocols TLSv1.2 TLSv1.3;
实际启用哪些协议,应根据服务器软件版本、客户端兼容性和安全要求确定,不建议为了兼容极旧客户端而重新开启已经不推荐使用的 TLS 版本。
2. 密码套件没有共同支持项
除了 TLS 版本,客户端和服务器还需要协商密码套件(Cipher Suite)。
如果服务器配置过于严格,或者客户端过于老旧,可能出现双方没有共同密码套件的情况。
这种情况下,OpenSSL 等工具可能返回:
handshake failure
排查时应检查服务器配置中的密码套件限制,并确认客户端实际支持的 TLS 版本和密码套件。
需要注意的是,TLS 1.3 使用的密码套件与 TLS 1.2 的配置方式有所不同,因此不能简单地认为修改 ssl_ciphers 就能解决所有 TLS 握手问题。
三、检查SSL证书和证书链
1. 证书已经过期
如果服务器向客户端提供的证书已经超过 Not After 时间,客户端可能拒绝连接。
可以使用 OpenSSL 检查:
openssl s_client -connect yourdomain.com:443 -servername yourdomain.com
也可以通过 SSL 检测工具检查公网实际返回的证书。
这里需要注意:服务器磁盘上的证书文件是否有效,并不代表公网用户拿到的证书就是这张证书。
例如:
- 新证书已经上传;
- Nginx 没有 reload;
- CDN 仍然缓存旧证书;
- 负载均衡某个节点没有更新。
最终用户仍然可能看到旧证书。
2. 证书域名不匹配
例如访问:
api.example.com
服务器却返回:
www.example.com
对应的证书,那么客户端会检查失败。
使用通配符证书时也要注意匹配层级。例如:
*.example.com
可以匹配:
api.example.com
shop.example.com
但不能匹配:
a.api.example.com
如果服务器部署了多个 HTTPS 站点,还需要重点检查 SNI。
3. 证书链不完整
服务器通常不仅需要发送自己的服务器证书,还需要提供客户端建立信任链所需的中间证书。
例如:
服务器证书
↓
中间CA证书
↓
受信任根CA
如果服务器没有正确发送中间证书,一些客户端可能无法建立完整的信任链。
使用 OpenSSL 检查时,如果看到:
verify error:num=20:unable to get local issuer certificate
一般说明证书链验证存在问题,但还需要结合服务器返回的证书链和客户端本地信任库进一步判断,不能仅凭这一条信息断定服务器一定缺少中间证书。
四、SNI配置错误也会导致SSL异常
SNI(Server Name Indication)允许客户端在 TLS 握手过程中告诉服务器自己访问的域名。
这对于一台服务器部署多个 HTTPS 网站非常重要。
例如同一个 IP 地址上同时运行:
www.example.com
api.example.com
shop.example.com
服务器需要根据客户端提供的 SNI 选择对应的证书。
如果 SNI 配置异常,服务器可能向客户端返回默认站点的证书。
例如:
用户访问:api.example.com
实际返回:
www.example.com 的证书
最终客户端会因为证书中的域名与访问域名不匹配而拒绝连接。
因此,多站点 HTTPS 环境出现 ERR_SSL_PROTOCOL_ERROR、证书域名不匹配等问题时,应检查:
- Nginx
server_name; listen 443 ssl配置;- 默认 HTTPS server;
- 证书文件路径;
- 私钥文件路径;
- CDN/WAF 回源时使用的 Host/SNI 配置。
五、Cloudflare 525和526怎么排查?
如果网站使用 Cloudflare,首先要区分 525 和 526。
Cloudflare 525:SSL Handshake Failed
525 表示 Cloudflare 与源站服务器建立 SSL/TLS 握手失败。
此时用户到 Cloudflare 的连接并不一定有问题,故障主要发生在:
Cloudflare
│
X TLS握手失败
│
源站服务器
重点检查:
- 源站 443 端口是否正常开放;
- 源站 Web 服务是否正常监听 HTTPS;
- 防火墙是否允许 Cloudflare IP 地址段访问;
- 源站 TLS 版本是否与 Cloudflare 兼容;
- 源站密码套件是否存在共同支持项;
- 源站是否正确配置 SNI;
- 源站是否存在异常 TLS 配置。
Cloudflare 526:Invalid SSL Certificate
526 通常表示 Cloudflare 无法验证源站证书。
这类问题尤其需要检查源站证书是否满足严格验证要求,例如:
- 证书是否已经过期;
- 证书是否由受信任 CA 签发;
- 证书域名是否与回源主机名匹配;
- 证书链是否完整;
- 源站返回的是否是正确证书。
如果 Cloudflare 使用 Full (strict) 模式,源站证书的验证要求会更加严格。
因此,遇到 526 时,重点不是重新申请一张 Cloudflare 边缘证书,而是检查源站实际返回的 SSL 证书。
六、如果只有部分用户访问失败怎么办?
如果绝大多数用户访问正常,只有某些设备出现 TLS 握手失败,应优先检查客户端环境,而不是立即修改服务器配置。
常见原因包括:
系统时间错误
证书具有明确的有效时间范围。
如果设备系统时间严重错误,即使服务器证书本身完全正常,客户端也可能将其判断为尚未生效或已经过期。
操作系统或客户端过旧
旧版操作系统、浏览器、Java SDK 或其他 TLS 客户端可能不支持服务器当前使用的 TLS 版本或密码套件。
这种情况下,现代设备正常、旧设备异常是一个重要线索。
HTTPS流量被安全软件拦截
企业网络、防火墙或安全软件可能启用 TLS Inspection,对 HTTPS 流量进行中间代理。
如果客户端不信任该代理使用的根证书,可能出现证书验证异常甚至 TLS 连接失败。
七、使用curl和OpenSSL快速定位
对于服务器运维人员,命令行工具往往比浏览器错误页面提供的信息更有价值。
使用curl查看HTTPS连接
curl -v -I https://yourdomain.com
可以观察:
- DNS解析;
- TCP连接;
- TLS握手;
- 服务器返回的证书信息;
- HTTP响应。
如果需要测试指定 TLS 版本,也可以进一步使用:
curl -v --tlsv1.2 https://yourdomain.com
用于判断 TLS 1.2 是否能够正常建立连接。
使用OpenSSL检查TLS握手
openssl s_client \
-connect yourdomain.com:443 \
-servername yourdomain.com
其中:
-connect
指定目标服务器和端口;
-servername
显式指定 SNI。
这对于一台服务器部署多个 HTTPS 域名的环境尤其重要。
如果需要测试 TLS 1.2,可以:
openssl s_client \
-connect yourdomain.com:443 \
-servername yourdomain.com \
-tls1_2
通过分别测试不同协议版本,可以快速判断问题是否与 TLS 版本协商有关。
八、SSL/TLS握手失败排查顺序
如果无法确定从哪里开始,建议按照下面的顺序排查:
① 确认故障位置
↓
客户端 → CDN?
CDN → 源站?
客户端 → 源站?
↓
② 查看服务器实际返回的证书
↓
③ 检查证书有效期和域名匹配
↓
④ 检查证书链
↓
⑤ 检查SNI和多站点配置
↓
⑥ 检查TLS协议版本
↓
⑦ 检查密码套件
↓
⑧ 检查防火墙、CDN和WAF
↓
⑨ 最后再检查客户端环境
这个顺序的好处是先确定**“哪一段连接出了问题”**,再检查具体配置,避免把 CDN 回源问题误判成浏览器问题。
九、如何避免SSL/TLS握手故障反复发生?
对于生产环境,不建议等到用户报告 ERR_SSL_PROTOCOL_ERROR 后再排查。
可以建立以下几项基础运维机制:
第一,监控公网实际证书。
不要只监控服务器上的 .pem 或 .crt 文件,而应该从公网真实发起 TLS 连接,检查最终用户实际拿到的证书。
第二,监控证书有效期。
在证书到期前设置 30 天、14 天、7 天等多级告警。
第三,自动化证书续期。
对于支持 ACME 的 DV 证书,可以使用 Certbot、acme.sh 等工具自动续期,并将证书更新、服务 reload 和部署结果纳入自动化流程。
第四,CDN和源站分别监控。
如果网站存在 CDN、WAF、SLB 等多个 TLS 终端,需要分别检查边缘证书和源站证书,不能只检查其中一端。
第五,对关键站点定期进行TLS探测。
通过 OpenSSL、监控平台或 SSL 检测工具定期检查实际 TLS 握手结果,可以在用户发现问题之前发现证书过期、链不完整、SNI错误等配置异常。
技术总结
SSL/TLS 握手失败并不等于 SSL 证书一定有问题。它可能发生在 TLS 协议协商、密码套件协商、SNI选择、证书验证、证书链验证以及 CDN 回源等多个环节。排查时应先确定客户端到 CDN、CDN 到源站,还是客户端直连源站出现问题,再检查证书、证书链、SNI、TLS版本和密码套件。对于生产环境,自动续期、证书到期监控和公网 TLS 探测能够显著降低握手故障风险。
常见问题 FAQ
Q:SSL/TLS握手失败一定是SSL证书过期了吗?
A:不一定。证书过期只是原因之一。TLS 版本不兼容、密码套件没有共同支持项、SNI配置错误、证书链问题、CDN回源失败以及客户端环境异常,都可能造成 TLS 握手或后续证书验证失败。
Q:Cloudflare 525和526有什么区别?
A:525主要表示 Cloudflare 与源站建立 TLS 握手失败;526主要表示 Cloudflare 无法通过严格模式验证源站证书。排查 525 应重点检查源站 TLS 服务、端口和协议配置;排查 526 则应重点检查源站证书有效期、域名匹配、信任链等问题。
Q:浏览器提示ERR_SSL_PROTOCOL_ERROR怎么解决?
A:首先确认其他设备是否也出现相同问题。如果所有设备都无法访问,应重点检查服务器的 TLS 配置、证书、SNI和443端口;如果只有个别旧设备异常,则需要检查客户端支持的 TLS 协议和密码套件。
Q:证书已经更新,为什么仍然提示SSL握手失败?
A:可能是新证书没有真正部署到公网 TLS 终端。例如 Nginx 更新证书后没有 reload,CDN 或负载均衡仍然使用旧证书,或者部分后端节点没有同步更新。应通过 OpenSSL 或公网 SSL 检测工具查看服务器实际返回的证书,而不是只检查本地证书文件。
京公网安备11010502031690号
网站经营企业工商营业执照