温馨提示×

linux openssl为何握手失败

小樊
37
2026-09-04 16:39:39
栏目: 云计算

Linux 下 OpenSSL 握手失败(handshake failure) 是非常常见的问题,原因很多。下面按最常见 → 较少见的顺序给你系统梳理一下,并给出排查方法


一、最常见原因

1️⃣ 协议版本不匹配(TLS1.0/1.1/1.2/1.3)

服务端和客户端支持的 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

解决

  • 服务端禁用老协议(如 TLS1.0/1.1)
  • 客户端升级 OpenSSL
  • 显式指定协议

2️⃣ 加密套件(Cipher Suite)不支持

客户端支持的 cipher 服务端一个都不支持。

典型表现

no shared cipher
handshake failure

检查

openssl s_client -connect host:443 -ciphers 'HIGH:!aNULL'

解决

  • 服务端启用常见套件(如 ECDHE-RSA-AES256-GCM-SHA384
  • 客户端不使用过于老旧的 cipher

3️⃣ 证书问题(最常见之一)

  • 证书过期
  • 证书域名不匹配
  • 自签名证书未信任
  • 中间证书缺失

检查

openssl s_client -connect host:443 -showcerts

看重点

  • Verify return code
  • subjectissuer
  • 是否有完整 chain

解决

  • 更换/补全证书
  • 客户端加 -CAfile
openssl s_client -connect host:443 -CAfile ca.crt

4️⃣ SNI 未设置(虚拟主机场景)

HTTPS 多域名服务器必须发 SNI。

失败表现

  • 返回默认证书
  • handshake 直接断

解决

openssl s_client -connect host:443 -servername www.example.com

二、网络和系统级原因

5️⃣ 防火墙 / 中间设备拦截

  • WAF
  • 代理
  • 负载均衡

表现

  • TCP 能通,TLS 直接 RST
  • 握手到一半断

排查

curl -v https://host
tcpdump -i any -n port 443

6️⃣ OpenSSL 版本过旧

老 Linux(CentOS 6/7 老版本):

  • 不支持 TLS1.3
  • 不支持新 cipher

检查

openssl version

7️⃣ 时间不正确(证书校验失败)

证书是“时间敏感”的。

检查

date

三、服务端配置问题

8️⃣ 服务端要求客户端证书(双向认证)

表现

tlsv1 alert certificate required

解决

openssl s_client \
  -connect host:443 \
  -cert client.crt \
  -key client.key

9️⃣ 服务端只支持 HTTP/2 + ALPN

某些服务必须 ALPN。

测试

openssl s_client -connect host:443 -alpn h2

四、快速定位流程(强烈推荐)

openssl s_client -connect host:443 -servername host -debug

重点看:

  • 是否发送 ClientHello
  • 是否收到 ServerHello
  • 在哪一步断

五、如果你愿意,我可以直接帮你分析

你可以贴出:

  1. openssl s_client 的完整输出
  2. 服务端类型(Nginx / Apache / Java / Go / 自研)
  3. Linux 发行版 + OpenSSL 版本
  4. 报错原文

我可以直接告诉你是哪一条导致的握手失败

0