根本原因是客户端无法通过服务器证书追溯到受信根证书,通常因证书链断裂或缺失中间证书;需用openssl检查nginx实际发送的证书段数与顺序,确认fullchain.pem拼接正确(域名证书在前、中间证书在后、不含根证书),并确保ssl_certificate指向该文件,同时验证客户端是否信任链顶端ca。

浏览器提示“未知颁发机构”,根本原因不是 Nginx 没开 HTTPS,而是客户端无法通过收到的证书向上追溯到一个它信任的根证书——这通常意味着证书链断裂或缺失关键环节。排查要聚焦“服务器发了什么”和“客户端信什么”两个层面,缺一不可。
用 OpenSSL 看清 Nginx 实际发送了哪些证书
这是最直接、最可靠的起点。别猜配置,要看真实握手时发出去的内容:
- 运行命令:openssl s_client -connect your-domain.com:443 -showcerts
- 观察输出中以 -----BEGIN CERTIFICATE----- 开头的段落数量和顺序
- 第一段必须是你的域名证书(Subject 中含 CN 或 SAN 匹配你访问的域名)
- 第二段起应为中间证书(Issuer 字段要和上一段的 Subject 匹配),且不能出现根证书
- 如果只看到一段,说明 Nginx 没发中间证书;如果顺序颠倒或夹杂根证书,也会导致验证失败
检查 fullchain.pem 是否拼接正确且被正确引用
Nginx 的 ssl_certificate 必须指向一个按序拼好的 PEM 文件,而不是单个 cert.pem:
- 确认文件内容顺序:第一段是你的域名证书(example.com.crt),第二段是中间证书(如 R3.crt 或 ca-bundle.crt),中间不能有空行
- 不要把根证书(如 ISRG Root X1)加进去——它已内置在客户端,Nginx 发送反而可能干扰
- 验证拼接结果:grep -c "BEGIN CERTIFICATE" fullchain.pem 应返回 ≥2
- 检查 Nginx 配置中 ssl_certificate 的路径是否确实指向这个 fullchain.pem,不是 cert.pem 或 bundle.crt
确认客户端是否信任该证书链的源头
即使服务端全对,客户端不认也白搭。重点分两类情况:
- 公共 CA 证书(如 Let’s Encrypt):问题大概率出在中间证书没发全,或系统/浏览器太旧未内置新根。用 SSL Labs 测试,看 “Chain issues” 是否标红
- 自签名或私有 CA 证书:浏览器默认不信任。必须手动将你的根证书(CA.crt)导入操作系统级信任库——Windows 要选“本地计算机 → 受信任的根证书颁发机构”,macOS 要在钥匙串中设为“始终信任”,Linux 需运行 sudo update-ca-certificates
- 注意:仅在浏览器里点“继续访问”或导入到“个人”证书存储,是无效的
排除其他干扰因素
有些问题看似证书,实则另有隐情:
- 系统时间错误:证书有效期校验依赖准确时间。电脑时间偏差几分钟就可能触发“证书尚未生效”或“已过期”
- 证书吊销状态:若证书已被 CA 吊销,即使链完整也会报错。可查 OCSP 响应或用浏览器开发者工具看 Security 标签页详情
- 代理或安全软件干扰:某些杀毒软件或企业网络代理会主动替换证书做 HTTPS 解密,导致浏览器看到的是代理的证书而非你的
- HSTS 缓存残留:之前访问过该域名并启用了 HSTS,浏览器会强制走 HTTPS 并拒绝任何证书异常。可尝试用隐身窗口或清除 HSTS 设置(chrome://net-internals/#hsts)











