openssl s_client是定位TLS握手失败的首选工具:可绕过应用层直击底层协商,通过逐协议探测、证书链验证、吊销检查及-debug抓帧,精准诊断协议不匹配、证书吊销、链不完整等硬性问题。

直接用 openssl s_client 连上 Nginx 的 443 端口,就能绕过浏览器和应用层封装,看到最底层的 TLS 握手细节。它不依赖日志、不经过代理、不触发缓存,是定位证书链、协议兼容、密钥匹配等硬性问题的第一工具。
快速连通与基础验证
先确认服务可达且能建立 TLS 连接:
- 运行
openssl s_client -connect your-domain.com:443 -servername your-domain.com,观察是否输出CONNECTED(00000003)和证书信息;若卡在连接或立即退出,检查防火墙、云安全组、Nginx 是否监听 443 及ssl on配置是否生效 - 加
-verify_return_error强制校验证书链完整性,失败时会明确提示verify error:num=20:unable to get local issuer certificate等错误 - 用
curl -vkI https://your-domain.com对比:若 curl 能通而 s_client 失败,大概率是 SNI 或 ALPN 协商差异;若两者都失败,问题更底层(如证书路径错、私钥权限不足)
逐协议探测握手兼容性
很多“SSL handshake failed”其实不是证书问题,而是客户端与 Nginx 支持的 TLS 版本不交集:
- 分别测试各版本:
echo | openssl s_client -tls1_2 -connect your-domain.com:443 -servername your-domain.com 2>/dev/null | grep "Protocol\|Cipher"echo | openssl s_client -tls1_3 -connect your-domain.com:443 -servername your-domain.com 2>/dev/null | grep "Protocol\|Cipher" - 若某条命令返回空或仅
CONNECTED后断开,说明该协议被拒绝;重点看Protocol : TLSv1.3是否出现、Cipher是否为空 - Nginx 若配置了
ssl_protocols TLSv1.2 TLSv1.3,但系统 OpenSSL 版本太旧(如 CentOS 7 默认 1.0.2),会导致 TLS 1.3 不可用,需升级 OpenSSL 并重编译 Nginx
验证证书链与密钥配对
证书链缺失、中间证书不可达、私钥不匹配,都会导致握手在 ServerHelloDone 后中断:
- 查看实际下发的证书链:
openssl s_client -connect your-domain.com:443 -showcerts -servername your-domain.com 2>/dev/null | openssl x509 -noout -text | grep -A1 "CA Issuers",确认 URI 可访问(如http://cert.int-x3.letsencrypt.org/能 curl 通) - 校验证书与私钥是否同源:
提取证书模数:openssl x509 -noout -modulus -in server.crt | openssl md5
提取私钥模数:openssl rsa -noout -modulus -in server.key | openssl md5
两个 MD5 值必须完全一致 - 若用 Let’s Encrypt,确保 Nginx 配置的是
fullchain.pem(含域名证书 + 中间证书),而非单独的cert.pem
强制触发吊销与深度诊断
部分客户端(如 Java 应用、企业浏览器)默认启用 OCSP/CRL 检查,而服务器未正确响应时,握手会静默失败:
- 加
-crl_check强制走吊销验证:openssl s_client -connect your-domain.com:443 -crl_check -servername your-domain.com,关注输出中是否有verify error:num=23:certificate revoked或unable to get certificate CRL - 加
-debug查看完整握手帧:openssl s_client -connect your-domain.com:443 -debug -servername your-domain.com,可定位到 ClientHello 是否携带 key_share、ServerHello 是否返回 supported_groups 等关键协商字段 - 配合抓包进一步分析:
sudo tcpdump -ni any -s0 -w ssl.pcap port 443,用 Wireshark 打开后过滤tls.handshake.type == 1(ClientHello)和== 2(ServerHello),比对双方支持的扩展与曲线


















