适用于 Linux 上排查客户端访问 HTTPS 时出现证书校验失败、握手中断或协议不匹配。命令基线为 OpenSSL 1.1.1+、curl 7.68+;示例域名 api.example.com、端口 443 和地址 203.0.113.10 必须替换为实际值。以下检查会主动连接目标服务,应在获准的来源网络执行。先保留错误原文,不要用 curl -k 把校验失败掩盖掉。
1. 固定客户端、时间与失败阶段
date -u
openssl version -a
curl --version | head -n 1
getent ahosts api.example.com
curl -v --connect-timeout 5 --max-time 15 \
https://api.example.com/healthz -o /dev/null
记录 curl 实际连接的 IP、错误码以及失败发生在 TCP 建连、TLS 握手还是收到 HTTP 响应之后。若 TCP 尚未建立,应先查路由、防火墙和监听;已经收到 HTTP 状态码,则 TLS 通常已经完成。curl -v 可能显示请求头和网络地址,公开日志前应脱敏。
证书有效期依赖客户端时间。使用 systemd 的主机可补充查看:
timedatectl status
时间明显错误时应先修正时间同步,再重复原请求,避免误判证书尚未生效或已经过期。
2. 显式携带 SNI 并执行证书校验
openssl s_client \
-connect api.example.com:443 \
-servername api.example.com \
-verify_hostname api.example.com \
-verify_return_error -showcerts </dev/null
重点保留协商出的协议和密码套件、服务端返回的证书链,以及末尾的校验结果。主机名不匹配时检查叶子证书的 SAN;unable to get local issuer certificate 一类错误则应区分服务端漏发中间证书与客户端信任库缺失。不要把服务端发送的中间证书直接当作新的信任根导入。
只查看叶子证书的主体、签发者、有效期和 SAN,可执行:
openssl s_client -connect api.example.com:443 \
-servername api.example.com </dev/null 2>/dev/null \
| openssl x509 -noout -subject -issuer -serial -dates -ext subjectAltName
3. 固定后端 IP,避免把 DNS 或负载均衡差异混入结果
当同一域名解析到多个地址时,应逐个后端验证,同时保留域名对应的 SNI 和主机名校验:
openssl s_client \
-connect 203.0.113.10:443 \
-servername api.example.com \
-verify_hostname api.example.com \
-verify_return_error </dev/null
curl --resolve api.example.com:443:203.0.113.10 \
-v --connect-timeout 5 --max-time 15 \
https://api.example.com/healthz -o /dev/null
只有部分地址失败,通常应继续比较各负载均衡节点的证书链、监听配置与发布版本;直接访问 IP 而不设置 SNI,可能拿到默认证书,不能代表域名入口。
4. 按证据比较 TLS 版本和 ALPN
OpenSSL 1.1.1+ 可分别限制协议版本:
openssl s_client -connect api.example.com:443 -servername api.example.com -tls1_2 </dev/null
openssl s_client -connect api.example.com:443 -servername api.example.com -tls1_3 </dev/null
openssl s_client -connect api.example.com:443 -servername api.example.com -alpn 'h2,http/1.1' </dev/null
TLS 1.2 成功而 TLS 1.3 失败,或反之,只能说明版本路径存在差异;还需结合客户端能力、服务端策略和中间代理日志定位。wrong version number 常见于把明文 HTTP 端口当成 TLS 端口,或代理协议配置不一致;no shared cipher、protocol version 才更接近协议或密码套件策略不兼容。不要在没有证据时整体降低最低 TLS 版本。
5. 闭环验证
每次只修改一个有证据支持的证书链、监听或 TLS 策略项。修复后从原失败客户端重复同一 curl 请求,并对域名解析出的每个实际后端执行固定 IP 验证。闭环至少应满足:系统时间正确、主机名校验通过、证书链能由现有信任库验证、预期 TLS 版本与 ALPN 协商成功,且原应用入口不再新增握手错误。浏览器单次成功不能替代原客户端和全部后端的验证。