Linux 下 OpenSSL 握手失败(handshake failure) 是非常常见的问题,原因很多。下面按最常见 → 较少见的顺序给你系统梳理一下,并给出排查方法。
服务端和客户端支持的 TLS 版本不一致。
典型表现
SSL_connect: error:0A000126:SSL routines::unexpected eof while reading
SSL handshake has read N bytes and written M bytes
检查
openssl s_client -connect host:443 -tls1_2
openssl s_client -connect host:443 -tls1_3
解决
客户端支持的 cipher 服务端一个都不支持。
典型表现
no shared cipher
handshake failure
检查
openssl s_client -connect host:443 -ciphers 'HIGH:!aNULL'
解决
ECDHE-RSA-AES256-GCM-SHA384)检查
openssl s_client -connect host:443 -showcerts
看重点
Verify return codesubject 和 issuer解决
-CAfileopenssl s_client -connect host:443 -CAfile ca.crt
HTTPS 多域名服务器必须发 SNI。
失败表现
解决
openssl s_client -connect host:443 -servername www.example.com
表现
排查
curl -v https://host
tcpdump -i any -n port 443
老 Linux(CentOS 6/7 老版本):
检查
openssl version
证书是“时间敏感”的。
检查
date
表现
tlsv1 alert certificate required
解决
openssl s_client \
-connect host:443 \
-cert client.crt \
-key client.key
某些服务必须 ALPN。
测试
openssl s_client -connect host:443 -alpn h2
openssl s_client -connect host:443 -servername host -debug
重点看:
你可以贴出:
openssl s_client 的完整输出我可以直接告诉你是哪一条导致的握手失败。