Nginx证书链配置必须严格满足三条件:首段为域名证书、后续仅含中间证书(禁根证书)、段间无空行且换行符为LF;需用file、xxd、grep验证格式,openssl verify校验链完整性,并确保ssl_certificate指向fullchain.pem、私钥权限600且模数匹配。

Linux 下 Nginx 的证书链配置看似简单,实则极易因文件结构、顺序、换行或权限问题导致 HTTPS 失效。关键不在“有没有配”,而在“配得干不干净”。
证书链文件必须严格符合 PEM 格式规范
fullchain.pem 不是随便拼起来的文本,它必须满足三个硬性条件:
- 第一段必须是你的域名证书(Subject=CN=your-domain.com)
- 后续段落只能是中间证书(如 Let’s Encrypt R3、Sectigo AAA),不能含根证书(如 ISRG Root X1)
- 段与段之间不能有空行,换行符必须是 Unix 风格的 LF(\n),不能是 Windows 的 CRLF(\r\n)
验证命令:
file fullchain.pem —— 应显示 ASCII text;若出现 UTF-8 Unicode (with BOM),说明开头有 BOM 头
xxd fullchain.pem | head -n 1 —— 若前三位是 ef bb bf,需清除 BOM
grep -n "^$" fullchain.pem —— 有输出即存在空行,必须删净
配置项指向与文件内容必须完全匹配
Nginx 不会自动补全或纠错,ssl_certificate 指向哪,它就原样加载哪:
- ssl_certificate 必须指向 fullchain.pem(不是 cert.pem,也不是 bundle.crt)
- ssl_certificate_key 必须指向私钥文件(.key),且权限为 600,属主为 Nginx 运行用户(如 nginx 或 www-data)
- 确认私钥与证书真正匹配:
openssl x509 -noout -modulus -in fullchain.pem | openssl md5
openssl rsa -noout -modulus -in privkey.pem | openssl md5
两行 MD5 值必须一致
用 openssl s_client 看清服务器实际发了什么
别信配置文件写了什么,要看客户端真实收到什么:
- 运行:openssl s_client -connect your-domain.com:443 -showcerts
- 观察输出中 -----BEGIN CERTIFICATE----- 块的顺序:
第一块是你域名的证书 → 第二块是中间 CA → 后续应无多余块 - 如果只看到一块,说明链没加载;
如果第一块是中间证书,就是典型顺序错误;
如果最后一块是 root CA,浏览器可能拒绝信任
典型报错与直击原因
SSL: error:0B080074:多由证书文件含 BOM、空行、CRLF 或私钥不匹配引发
unknown directive 'ssl_certificate':Nginx 编译时未启用 --with-http_ssl_module
BIO_new_file(...) failed:路径正确但 Nginx 工作目录下找不到该文件(常见于相对路径误用或 SELinux 限制)
证书不受信任(浏览器提示):大概率是链缺失、顺序错、混入根证书,或 ca.crt 未被客户端信任


















