nginx 在 tls 握手时不应发送根证书,只需发送域名证书+中间证书;若 openssl s_client 显示三块及以上证书且末块 subject 为 isrg root x1 等根 ca 名称,即误含根证书。

Nginx 不应该在 TLS 握手时发送根证书,它只需发送**域名证书 + 中间证书**。发送根证书不仅多余,还可能被部分客户端(如安卓、Java、Python requests)拒绝或触发警告。验证是否误含根证书,关键不是看文件里有没有,而是看 Nginx 实际发出去了什么。
用 openssl s_client 直接查看 Nginx 发送的内容
在 Nginx 服务器本地执行:
openssl s_client -connect your-domain.com:443 -servername your-domain.com -showcerts 2>/dev/null观察输出中所有以 -----BEGIN CERTIFICATE----- 开头的块:
- 只出现 1 次 → 仅发了域名证书,中间证书缺失
- 出现 2 次 → 第一块是域名证书,第二块应是中间证书(如 CN=Let's Encrypt R3),正常
- 出现 3 次或更多 → 需逐块检查 subject:若最后一块的 subject 是 CN=ISRG Root X1 或 CN=DigiCert Global Root CA 等根 CA 名称,说明误包含了根证书
快速过滤并识别根证书行
加 grep 过滤 subject 字段,更直观:
openssl s_client -connect your-domain.com:443 -showcerts 2>/dev/null | grep "subject="输出示例(正常):
subject=C = CN, ST = Beijing, L = Beijing, O = Your Org, CN = your-domain.comsubject=C = US, O = Let's Encrypt, CN = R3
如果看到第三行类似:
→ 就是根证书被错误发送了。
检查 fullchain.pem 文件本身是否混入根证书
Nginx 的 ssl_certificate 指向的 PEM 文件必须人工核对:
- 用 cat /path/to/fullchain.pem 查看内容
- 确认只有 2 个(或最多 2–3 个)证书块,且最后一个块的 subject 不是知名根 CA
- 中间证书的 issuer 应与上一块的 subject 匹配,而它的 issuer 才应指向根(但该根证书本身不能出现在文件里)
- 常见错误:把 ca-bundle.crt 或系统 ca-certificates.crt 直接当 fullchain 用,它们通常含数十个根证书
用 verify 命令辅助判断信任路径
这个命令不检查 Nginx 发了什么,但能确认你的证书链是否“逻辑完整且不含根”:
openssl verify -CAfile返回 OK 表示:域名证书可被中间证书正确签发,无需根证书参与验证 —— 这正是 Nginx 应该提供的最小有效链。
若你强行把根证书也塞进 fullchain.pem,verify 可能仍返回 OK,但实际传输已违规。











