核心是新旧worker并存过渡:证书链须按域名证书+中间ca顺序组装(不含根证书),用软链接原子替换路径,再执行nginx -t && nginx -s reload触发热重载,新连接用新证书,旧连接持续处理至自然结束。

平滑热加载更新 Nginx 证书链,核心是不中断已有连接(包括长连接、WebSocket、流式响应等),同时让新连接立即使用新证书。这靠的是 Nginx 的信号机制和进程模型,不是“重启服务”,而是“新旧 worker 并存过渡”。
证书链必须正确组装才能热加载生效
证书链顺序错误会导致热加载后部分客户端握手失败(如老 Android、某些 IoT 设备)。Nginx 要求证书文件中:域名证书在最前,中间 CA 证书依次跟在后面,根证书不能包含在内。例如:
-
正确顺序:
your-domain.crt(你的证书) +intermediate.crt(Let’s Encrypt 的 R3 或 ISRG X1) - 错误做法:只放私钥、漏中间证书、把根证书也塞进去、顺序颠倒
- 验证方式:
openssl x509 -in fullchain.pem -text -noout | grep "Issuer\|Subject",确认 Issuer 是上一级 CA,最终链能回溯到可信根
用软链接+原子替换实现零间隙证书切换
避免直接覆盖证书文件(可能被 worker 进程读到一半),推荐用符号链接解耦配置路径与实际文件:
- 配置中写:
ssl_certificate /etc/nginx/ssl/example.com/current.crt; - 上传新证书后执行:
ln -sf /etc/nginx/ssl/example.com/fullchain-202609.pem /etc/nginx/ssl/example.com/current.crt - 同理更新私钥:
ln -sf /etc/nginx/ssl/example.com/privkey-202609.pem /etc/nginx/ssl/example.com/current.key - 软链接切换是原子操作,Nginx 下次 reload 时自然读取新内容,无竞态风险
触发热重载并确认新证书已就绪
执行一行命令完成校验与加载:nginx -t && nginx -s reload。该过程会:
- 自动检查语法、证书路径是否存在、nginx 用户是否有读权限(
644或600) - 主进程 fork 新 worker,新连接即使用新证书链;旧 worker 继续处理未完成请求(含 keep-alive 长连接)
- 观察效果:
ps aux | grep nginx可见新旧 worker 共存;tail -f /var/log/nginx/error.log应无 reload 报错 - 验证是否生效:
openssl s_client -connect example.com:443 -servername example.com 2>/dev/null | openssl x509 -noout -dates,看Not After是否更新
绕过客户端缓存干扰,真实验证 TLS 握手
浏览器或 CDN 可能缓存 OCSP 响应、TLS 会话票据或证书信息,导致你看到的不是最新状态:
- 用 curl 强制刷新:
curl -vI --resolve example.com:443:YOUR_SERVER_IP https://example.com - 禁用会话复用测试:
openssl s_client -connect example.com:443 -servername example.com -no_ticket - 若用 Cloudflare,先在 DNS 设置中临时暂停代理(橙色云变灰色云),直连源站验证











