绝大多数“不安全”提示源于nginx未发送中间证书,需将域名证书与中间证书严格按序拼接为fullchain.pem,并在ssl_certificate中指向它,确保openssl输出含至少两段证书且ssl labs显示无链路问题。

浏览器提示“不安全”或“证书链不完整”,绝大多数情况不是证书没装上,而是 Nginx 没把中间证书一起发给客户端。现代浏览器(尤其是 Chrome、Safari、安卓 Chrome)和严格验证的工具(如 curl、Python requests)会拒绝构建不了信任链的连接,而你可能只配置了域名证书,漏掉了关键的中间证书。
确认是不是证书链真有问题
别信浏览器图标或缓存,用命令直接看服务器实际发了什么:
- 在 Nginx 服务器上运行:openssl s_client -connect your-domain.com:443 -servername your-domain.com -showcerts
- 观察输出中是否有至少两段 -----BEGIN CERTIFICATE----- 内容
- 第一段应是你的域名证书(含 CN=your-domain.com)
- 第二段必须是中间证书(如 CN=Let's Encrypt R3 或 CN=DigiCert SHA2 Secure Server CA),不能是 “self signed certificate”
正确拼接 fullchain.pem 文件
这个文件必须严格按顺序包含:你的域名证书 + 中间证书(不含根证书,也不含私钥):
- 用文本编辑器打开你的域名证书(如 example.com.crt),复制全部内容(含首尾 BEGIN/END 行)
- 换一行,粘贴中间证书(CA Bundle,通常名为 intermediate.crt 或 ca-bundle.crt)
- 两段之间不能有空行、不能有多余空格、不能混入私钥或根证书
- 保存为 fullchain.pem,推荐用 nano 或 VS Code 编辑,避免 Windows 记事本编码异常
- 验证:执行 grep -c "BEGIN CERTIFICATE" fullchain.pem,结果应 ≥2
Nginx 配置中只改这两行
其他配置保持不变,重点确保:
- ssl_certificate 必须指向你刚拼好的 fullchain.pem(不是原来的 .crt)
- ssl_certificate_key 仍指向原始私钥文件(如 privkey.pem),不动它
- 删掉或注释掉旧的 ssl_certificate /xxx/old.crt 这类行
- ssl_trusted_certificate 对修复浏览器报错完全无效——它只用于客户端证书校验或 OCSP stapling,不要指望它补证书链
验证是否真正生效
重启后交叉检查,别只看浏览器:
- 再跑一遍 openssl 命令,确认输出中明确出现两段证书,且第二段 Subject 含中间 CA 名称
- 用 SSL Labs 扫描,看 “Certificate Paths” 是否绿色 ✔️,“Chain issues” 显示 None
- 特别测试 iOS Safari 和安卓 Chrome(清除 HSTS 缓存:chrome://net-internals/#hsts,用无痕模式)
- 如果这些都通过,说明证书链已完整,浏览器“不安全”警告基本就解决了











