最可靠的方式是在 nginx 服务器本地用 openssl s_client 命令直连实测:运行 openssl s_client -connect domain.com:443 -servername domain.com -showcerts,检查 -----begin certificate----- 出现次数及顺序——仅1次表示链不完整,2次且第二段 issuer 与第一段 subject 匹配则正常,3次及以上可能混入根证书或私钥;同时需人工确认 ssl_certificate 文件中域名证书后紧接中间证书、无空行、无根证书或私钥。

最可靠的方式是在 Nginx 服务器本地用 openssl s_client 命令直连实测,看它实际发给客户端的是什么——这决定了安卓、微信小程序、Python requests 等严格校验环境能否信任你的 HTTPS 站点。
用 OpenSSL 检查 Nginx 实际返回的证书链
运行这条命令:
openssl s_client -connect your-domain.com:443 -servername your-domain.com -showcerts 2>/dev/null
重点观察输出中 -----BEGIN CERTIFICATE----- 出现几次:
- 只出现 1 次 → 仅发了域名证书,中间证书缺失,链不完整
- 出现 2 次 → 第一段是你的域名证书,第二段应是中间 CA(如 Let’s Encrypt R3),顺序正确
- 出现 3 次或更多 → 可能混入了根证书或私钥,属于错误配置
再加过滤快速核对签发关系:
openssl s_client -connect your-domain.com:443 -showcerts 2>/dev/null | grep "subject\|issuer"
第一段 subject= 应含你的域名;第二段 issuer= 应与第一段 subject= 完全一致(说明中间证书确实签发了你的证书)。
人工检查 ssl_certificate 文件内容
Nginx 不会自动补链,它只原样发送你指定的 PEM 文件。打开 ssl_certificate 指向的文件,确认:
- 第一段是以
-----BEGIN CERTIFICATE-----开头的域名证书(subject含你的域名) - 紧接着是且仅是中间 CA 证书(不能是根证书,也不能是私钥或注释)
- 两段之间不能有空行,每段都以
-----END CERTIFICATE-----结尾 - 常见错误:把
ca-bundle.crt单独当 fullchain 用,或误把根证书也拼进去
验证链是否被系统信任
执行带验证的命令,看返回码:
openssl s_client -connect your-domain.com:443 -servername your-domain.com 2>/dev/null | grep "Verify return code"
若显示 Verify return code: 0 (ok),说明当前链能被本地 OpenSSL 信任(即含完整中间证书);若为非零值(如 21),大概率是中间证书缺失或顺序错乱。
辅助用在线工具交叉比对
访问 decoder.link/sslchecker 或 SSL Checker,输入域名,关注三点:
- Certificate Chain 是否标 “OK”
- Chain issues 是否提示 “Incomplete” 或 “Extra certs”
- 列出的层级是否为:Domain → Intermediate →(Root,但不应由 Nginx 发送)
注意:在线工具可能自动补全链,结果仅供参考,最终以 s_client 实测为准。











