必须配全证书链,因为nginx的ssl_certificate只发一个文件,而浏览器需从域名证书逐级信任至根ca;缺失中间证书会导致旧安卓、win7等客户端报“不安全”或断连。

证书链配置自动化更新与部署,核心在于把“证书+中间证书”拼接成完整链文件,并确保 Nginx 始终加载它——不能只放域名证书,也不能每次手动合并。
为什么必须配全证书链
Nginx 的 ssl_certificate 指令只接受一个文件,而浏览器验证 HTTPS 时需要从你的域名证书一路向上信任到根 CA。如果中间证书缺失,部分客户端(尤其是旧 Android、Windows 7、某些企业防火墙)会报“不安全”或直接断连。官方推荐做法是把域名证书和中间证书按顺序拼成一个 .pem 或 .crt 文件,例如:
- 第一段:your-domain.com.crt(你的域名证书)
- 第二段:中间证书(如 R3、ISRG Root X1 等,来自 Let’s Encrypt 或其他 CA)
- 注意:不要包含根证书(root CA),它已预装在操作系统/浏览器中
用 acme.sh 自动合并证书链
acme.sh 默认生成的 fullchain.pem 就是已拼好的完整链文件(域名证书 + 中间证书),无需额外操作。只要你在 Nginx 配置里指向它,就天然满足链完整性:
- ssl_certificate /etc/letsencrypt/live/example.com/fullchain.pem;
- ssl_certificate_key /etc/letsencrypt/live/example.com/privkey.pem;
acme.sh 续期时会自动更新 fullchain.pem,内容随 CA 策略变化实时同步(比如 Let’s Encrypt 切换中间证书时,它已内置适配逻辑)。
Ansible 自动化部署时确保链文件到位
如果你用 Ansible 管理多台 Nginx,关键不是“怎么合并”,而是“怎么确保路径和内容一致”:
- 在 playbook 中明确 copy fullchain.pem(不是 cert.pem),并设为 mode: '0644'
- 禁止覆盖式写入;使用 backup: yes,防止出错后无法回退
- 加一道校验任务:用 stat 检查 fullchain.pem 是否存在且非空,再用 lineinfile 或 shell 命令确认文件开头是否为
-----BEGIN CERTIFICATE-----,结尾是否含至少两个证书块 - 若发现链文件异常(比如只剩一个证书),可触发 rescue 流程,暂停 reload 并告警
避免常见链配置陷阱
有些团队误以为“有 cert.pem 就够了”,或自己手写脚本拼接却漏掉换行、顺序颠倒、多加空格——这些都会让 Nginx 启动失败或链验证中断:
- 不要用
cat cert.pem chain.pem > bundle.crt这类裸命令,缺少容错;改用 acme.sh 的--fullchain-file输出或 Ansible 的 assemble 模块 - 别在 Nginx 配置里同时设 ssl_certificate 和 ssl_trusted_certificate 来“补链”——后者仅用于 OCSP stapling 或客户端证书验证,对浏览器信任链无效
- 测试链是否完整:运行
openssl s_client -connect example.com:443 -servername example.com 2>/dev/null | openssl x509 -noout -text,看输出中是否列出多个 Issuer,或直接用 SSL Labs 测试页 扫描











