nginx 作为 ssl 终结透明网关,通过变量或 include 解耦证书路径,配合 certbot deploy-hook 自动 reload,实现 https 无缝生效;需确保 nginx -t 验证、权限正确及避免软链接断裂。

不需要修改后端服务代码或配置,就能让后端 HTTP 服务“自动支持 HTTPS”,还能在 Let's Encrypt 证书更新时无缝生效——关键在于把 Nginx 做成一个 SSL 终结+动态重载的透明网关。
核心思路:SSL 终结 + 反向代理 + 证书热加载
Nginx 不把证书绑定到 upstream,而是自己处理 TLS 握手(SSL Termination),后端始终走 HTTP;证书文件由外部工具(如 certbot)更新,Nginx 通过 reload 轻量级重载配置,不中断连接、不丢请求。
重点不是“自动续期”,而是“续期后 Nginx 能立刻用新证书响应新连接”——这靠的是 Nginx 的平滑 reload 机制,而非长连接复用旧证书(TLS 会话复用不影响证书切换)。
关键配置:用变量和 include 实现证书路径解耦
避免硬编码证书路径,便于脚本更新后触发 reload:
- 在 nginx.conf 主配置中定义变量,例如:
set $ssl_cert_path "/etc/letsencrypt/live/example.com/fullchain.pem";<br>set $ssl_key_path "/etc/letsencrypt/live/example.com/privkey.pem";
- server 块中引用:
ssl_certificate $ssl_cert_path;<br>ssl_certificate_key $ssl_key_path;
- 更推荐做法:把证书路径单独抽成 ssl_params.conf,用
include ssl_params.conf;引入,续期脚本只改这个文件再 reload
自动化衔接:certbot hook + nginx reload 安全闭环
certbot 续期成功后,通过 --deploy-hook 触发 Nginx 重载:
- 写一个 deploy hook 脚本(如 /opt/reload-nginx.sh):
#!/bin/sh<br>nginx -t && nginx -s reload || exit 1
- 确保该脚本有权限读取 nginx 配置、发送信号给 master 进程(通常需 root 或 nginx 所属用户执行)
- 在 certbot 定时任务中加入:
certbot renew --deploy-hook "/opt/reload-nginx.sh" - 可选增强:hook 中加日志记录、失败告警(如 curl 推送企业微信)、或校验证书是否真正生效(openssl s_client 测试)
生产注意点:避免 reload 失败导致服务中断
reload 看似安全,但配置错误或权限问题会直接让新 worker 启动失败,master 会回滚并保持旧配置——表面无感知,实则新证书未生效。
- 每次更新证书前,先运行
nginx -t验证语法和文件可读性 - 检查证书文件属主和权限:
chown root:root /etc/letsencrypt/live/*/fullchain.pem /etc/letsencrypt/live/*/privkey.pem,且 privkey.pem 权限必须是600 - 不要在 server 块里用
ssl_certificate指向软链接目录(如 live → latest),Let's Encrypt 更新时可能短暂出现链接断裂;应指向具体域名目录,或确保 softlink 原子更新 - 观察 Nginx error log,重点关注 reload 时刻是否有
SSL_CTX_use_PrivateKey_file() failed类报错
不复杂但容易忽略:真正的“透明”,是后端完全无感;真正的“自动”,是续期、校验、重载、验证形成闭环。Nginx 在这里不是万能胶,而是可控、可观、可编排的 TLS 边界守门人。











