最准方式是用openssl s_client -connect domain:443 -showcerts查看nginx实际下发的证书数量和顺序:输出-----begin certificate-----行数即链深度,1表示仅域名证书(缺中间证),2为常见完整链,≥4或含根证书则配置错误;再用grep "subject\|issuer"验证签发路径是否正确,且nginx不得下发根证书。

直接用 openssl s_client 查看 Nginx 实际发给客户端的证书数量和顺序,是最准的方式——它不依赖浏览器、不经过缓存,能真实反映安卓、Python requests、Java 等严格校验场景收到的内容。
快速确认下发证书链深度
在 Nginx 服务器上执行:
openssl s_client -connect your-domain.com:443 -servername your-domain.com -showcerts 2>/dev/null | grep "-----BEGIN CERTIFICATE-----" | wc -l
输出数字即为当前下发的证书块总数:
- 1:只发了域名证书,链深度为 1 → 缺失中间证书
- 2:域名证书 + 一级中间证书 → 常见完整链(如 Let’s Encrypt R3)
- 3:域名证书 + 多级中间证书(如 E1 → R3)→ 深度为 3,需确认顺序是否正确
- ≥4 或含 ISRG Root X1 / DigiCert Global Root 等字样:混入了根证书,属于错误配置
验证每张证书的层级关系
加过滤命令看 subject 和 issuer 字段,判断是否构成可信路径:
openssl s_client -connect your-domain.com:443 -showcerts 2>/dev/null | grep "subject\|issuer" | head -n 6
正常应呈现清晰的签发链:
- 第一段
subject=CN=your-domain.com→ 你的域名证书 - 第一段
issuer=CN=Let's Encrypt R3→ 它由 R3 签发 - 第二段
subject=CN=Let's Encrypt R3→ R3 证书本身 - 第二段
issuer=CN=ISRG Root X1→ R3 由根证书签发(但该根证书不应下发)
关键点:Nginx 只需下发到中间证书即可,根证书必须由客户端自行信任,不能包含在响应中。
检查是否真的被客户端认可
启用严格校验模式,让 OpenSSL 模拟客户端行为并报错:
openssl s_client -connect your-domain.com:443 -servername your-domain.com -verify_return_error -CAfile /etc/ssl/certs/ca-certificates.crt 2>/dev/null
若返回 verify error:num=20:unable to get local issuer certificate,说明客户端找不到 issuer 对应的中间证书,即链未下发或顺序错。
注意:-CAfile 要指向系统信任的根证书包,不是你自己的 fullchain.pem。
对比本地文件与实际下发内容
有时配置文件写对了,但 reload 后没生效,或证书文件被覆盖。可同步检查:
- 查 Nginx 配置中
ssl_certificate指向的文件里有几段证书:grep -c "BEGIN CERTIFICATE" /path/to/fullchain.pem - 再运行上面的
s_client命令,比对数量是否一致 - 不一致说明配置未生效、路径写错、或文件权限导致 Nginx 读取失败











