最准排查方式是直接在服务器运行openssl s_client查看nginx实际发送的证书链:正常应输出至少两行subject,第一行为cn=域名(终端证书),第二行为cn=中间ca(如let's encrypt r3);若仅一行或第二行为根证书(如isrg root x1),则链缺失或顺序错误。

直接在服务器上运行 OpenSSL 命令,查看 Nginx 实际发送的证书内容,这是最准的排查方式。浏览器报 NET::ERR_CERT_AUTHORITY_INVALID,尤其是安卓、Python requests 或 Java 程序报错,大概率是中间 CA 证书没发出去,而不是证书本身无效。
用 openssl s_client 看真实发送的证书链
在 Nginx 服务器上执行:
openssl s_client -connect your-domain.com:443 -servername your-domain.com -showcerts 2>/dev/null | grep "subject="
观察输出结果:
- 正常应有至少两行:第一行含 CN=your-domain.com(你的域名证书),第二行含中间 CA 名称,例如
CN=Let's Encrypt R3或CN=DigiCert TLS RSA SHA256 2020 CA1 - 如果只有一行,说明 Nginx 只发了域名证书,中间证书缺失
- 如果第二行是
CN=ISRG Root X1或其他根证书,说明文件里混入了根证书,或顺序颠倒
检查 fullchain.pem 文件是否拼对
Nginx 的 ssl_certificate 必须指向一个已拼好的 PEM 文件,不是单独的 cert.pem。运行:
cat /path/to/fullchain.pem
确认以下几点:
- 文件中至少有两个
-----BEGIN CERTIFICATE-----块 - 第一块 Subject 必须是你自己的域名(如
CN=example.com) - 第二块起必须是中间证书,不能是根证书;多级中间证书需按信任路径从近到远排列(例如 R3 → E1 是对的,R3 → ISRG Root X1 是错的)
- 两段之间不能有空行,不能含私钥、注释、Windows 换行符或乱码
验证配置是否真正生效
改完配置并 reload 后,别依赖浏览器图标或缓存:
- 重跑上面的
openssl s_client命令,确认输出中明确出现两段证书,且第二段 Subject 显示中间 CA 名称 - 用 SSL Labs 测试,看 “Certificate Chain” 是否标绿、“Chain issues” 是否为
None - 若仍报错,可能是 CDN 缓存或客户端 HSTS 缓存干扰:安卓用户可访问
chrome://net-internals/#hsts删除域名;iOS 用户进设置 → Safari → 清除历史记录和网站数据
特别注意 ssl_trusted_certificate 的误区
这个指令不会发给浏览器,它只用于 Nginx 内部:
- 配合
ssl_stapling_verify on验证 OCSP stapling 响应签名 - 启用
ssl_verify_client on时,校验客户端提交的证书 - 把它当成“补全证书链”的手段完全无效,改它对修复
NET::ERR_CERT_AUTHORITY_INVALID没有任何作用











