不动Nginx配置完成SSL证书自动续期的落地实践

Feng 18 阅读 测试运维

跑了几年的 Linux 机器上挂着几十个站点,Nginx 主配置里一串 include,子目录层层嵌套。谁写的、为什么这么写,早没人说得清。平时风平浪静,一到证书到期,所有人开始互相推。

不是改不动,是改错的代价太大。一个实例托管上百个域名,证书路径分散在不同文件,反向代理和 rewrite 规则互相咬合。为了换一张证书去动配置,等于在运行中的系统上做外科手术。最稳的策略就是能不动就不动。

可证书不认这个逻辑,到期照样过期。

续期流程里真正卡住的是最后一步

证书自动续期的完整链路其实只有五步:查有效期、提前申请、验证域名归属、把新证书放到正确位置、让 Nginx 加载。

前四步工具化程度很高,卡点在第五步。以 certbot 为例,它默认走 webroot 或 standalone 验证,证书签发没问题,但部署依赖 –deploy-hook 脚本自己去 cp 文件、自己去 reload。脚本一旦写错路径,或者 reload 命令在 systemd 环境下没带对 unit 名,续期任务返回 0,线上却还是旧证书。acme.sh 的 –install-cert 也是同样思路,需要显式指定 –key-file、–fullchain-file 和 –reloadcmd,少一个参数就断链。

这就是“自动续期”名不副实的根源:申请自动化了,部署仍然靠人肉兜底。配置越复杂,脚本越不敢写全,最后退化成日历提醒加手工操作。

不动Nginx配置完成SSL证书自动续期的落地实践

httpsok 的思路:识别而不是重写

httpsok 切的是另一条路。它不要求你重构目录,也不重写 Nginx 配置,而是解析现有配置,定位每个站点实际引用的证书文件,再把新证书写回原位置。

具体能力包括:扫描配置目录发现站点与证书的对应关系;对接 Let’s Encrypt、ZeroSSL、Google 等 CA 完成签发;支持 DNS API 验证,泛域名也能覆盖;续期后自动替换证书文件并触发加载;多域名、多服务器统一管理;带续期状态监控和到期通知。

对历史遗留系统来说,这个顺序很关键——先适配现状,再谈自动化。原开发人员离职、配置无人维护的机器,最怕的就是工具要求你先改造环境。

DNS 验证的凭据要按最小权限给

走 DNS API 验证时,工具需要持有域名解析服务商的 API 凭据。这里有个容易被忽略的点:不要用主账号的全局密钥。阿里云、腾讯云、Cloudflare 都支持子账号或受限 Token,只授予对应域名区域的 DNS 编辑权限即可。泛域名证书(*.example.com)的验证记录是 _acme-challenge.example.com,凭据权限过宽意味着一旦泄露,攻击者可以改任意解析记录。

另外,DNS 验证依赖解析生效时间。TTL 设得很长的域名,验证可能反复失败,先把 _acme-challenge 相关记录的 TTL 调低再跑。

续期成功不等于线上生效

这是最值得单独拎出来的一环。证书文件更新了,Nginx 没 reload,或者 reload 失败,浏览器拿到的仍然是旧证书。判断方法很直接:

不动Nginx配置完成SSL证书自动续期的落地实践

openssl s_client -connect example.com:443 -servername example.com 2>/dev/null | openssl x509 -noout -dates

输出的 notAfter 就是线上实际生效的到期时间。如果它和你刚部署的新证书日期对不上,问题在加载环节,不在签发环节。

reload 失败的常见根因有三个:配置语法错误(用 nginx -t 先验)、reload 命令在非交互环境下找不到 nginx 二进制(写绝对路径)、以及 master 进程 PID 文件路径与脚本假设不一致。排查时先看 nginx -t 的返回码,再看 error.log 里 reload 前后的记录,基本能定位。

哪些环境适合,哪些要谨慎

适合的场景很明确:配置多年没人敢动的遗留系统;单实例托管几十上百个域名、证书路径各不相同的;中小企业没有专职运维、续期靠某个人记日历的;部署架构不允许改动的服务器。

需要谨慎的情况也得说清楚。如果 Nginx 配置里证书路径是动态拼接的,或者用了非标准模块加载证书,自动识别可能定位不到,这时仍要人工确认一次映射关系。另外,工具自动写回证书文件意味着它对该路径有写权限,生产机上要确认文件属主和权限不会被改乱,避免 Nginx worker 读不到证书。

自动化的边界

生产环境的目标不是把所有东西改成自己顺眼的样子,而是在业务稳定的前提下,把重复且高风险的动作交出去。证书续期恰好符合这个特征:频率固定、步骤明确、人工操作反而容易出错。

不动配置,把续期做掉,这件事本身不复杂。复杂的是承认老系统有它继续运行的理由,然后围绕这个前提设计工具。

ID:7641

Feng
这位作者很神秘,还没有填写简介。