返回博客
Let's Encrypt自动续期证书部署

Let's Encrypt 证书自动续期和部署怎么做

Let's Encrypt 证书有效期正在从 90 天逐步缩短到 45 天。真正要自动化的不只是 certbot renew,而是验证、续期、部署、重载和线上检查这一整条链路。

2026-04-258 分钟
Let's Encrypt 证书自动续期和多目标部署流程插画

Let's Encrypt 证书不能靠人记

以前 Let's Encrypt SSL/TLS 证书 90 天续一次,很多团队还能靠日历提醒、表格、运维群消息勉强撑着。以后不行了。Let's Encrypt 已经公布计划:2027 年 2 月 10 日开始变成 64 天,2028 年 2 月 16 日开始变成 45 天。官方也明确提醒,短有效期下手工续期不再推荐。

有效期短本身不是坏事——证书或私钥出问题时,风险窗口更小。但它逼着每个团队把证书管理彻底自动化。如果脚本还写死“每 60 天续一次”,到 45 天证书就已经来不及了。Let's Encrypt 在缩短有效期的公告里也提到,不支持 ARI 的客户端要重新确认续期调度,不能再用固定 60 天这种老逻辑。

有效期会分阶段缩短

截至 2026 年 4 月,Let's Encrypt 默认证书仍是 90 天。变化会分阶段推进:2027 年进入 64 天,2028 年进入 45 天。现在检查自动化链路,还来得及。

更难的是签出之后那一段:

  • 证书续了,但 Nginx 没有 reload。
  • 新证书在一台服务器上,另一台服务器还在用旧证书。
  • CDN 边缘证书正常,源站证书已经快过期。
  • 泛域名证书要走 DNS-01,DNS Token 权限、传播等待、TXT 记录清理都有可能出问题。
  • 证书文件更新了,但线上入口实际返回的还是旧证书。

certbot renew 只能覆盖续期这一步。真正上线时,还要确认验证可重复执行、证书能分发到正确位置、相关服务已经重载,并且用户入口实际返回的是新证书。

只跑 certbot renew 还不够

很多团队一开始是这样处理的:

bash
certbot renew --dry-run
certbot renew
systemctl reload nginx

如果一台机器上只跑一个 Nginx,这套足够用——certbot 自带 systemd timer 或 cron,定期跑 renew,hook 里再 reload 一下就完事。

问题在于多数生产环境的证书不是只服务于本机。一张 example.com 证书可能同时放在多台 Nginx、负载均衡监听器、CDN、Kubernetes Ingress、内网 API 网关上。这时候 certbot renew 只更新了本机文件,分发、导入、绑定、reload 全要你自己接。

更容易翻车的是半自动流程。证书自动续好了,却还等着人复制到另一台机器;部署脚本返回成功了,但线上入口实际返回的还是旧证书。这种状态比纯手工更难发现,因为团队会误以为续期链路已经闭环。

续期、部署、检查要串成一条链路

可以把 Let's Encrypt 自动续期拆成 6 个动作。

动作要回答的问题
检查哪些证书快到期了?线上入口实际返回的是哪张证书?
验证HTTP-01 或 DNS-01 还能不能跑通?
续期ACME 客户端能不能按正确时间续证书?
部署新证书要放到哪些服务器、云产品、CDN 或网关?
生效Nginx reload 了吗?云资源绑定换新了吗?
告警哪一步失败了?谁需要处理?

这 6 个动作少一个,都可能导致线上过期。最隐蔽的是“生效”那一步:磁盘上的证书已经是新的,进程内存里加载的还是旧的,用 ls 看文件没问题,用户访问时拿到的还是旧证书。

单机 Nginx:Certbot 自己就能跑

只有一台服务器、一个 Nginx 时,Certbot 自带的自动续期加一个 reload hook 通常就解决问题。没必要一上来引入平台,多一层系统也意味着多一层维护成本。

需要做的就是把下面三件事检查到位。

定时任务真的存在

在 systemd 系统上看 timer:

bash
systemctl list-timers | grep certbot

如果是 cron,就检查系统 crontab 或当前用户的 crontab。不要只记得“我当时好像装过 Certbot”,要看到明确的定时任务。

dry-run 能跑通

改完证书配置、DNS 配置或 Web 入口规则后,跑一次测试续期:

bash
certbot renew --dry-run

它能提前暴露 HTTP-01 路径被拦、DNS-01 Token 没权限、插件参数失效这类问题。

续期后会 reload 服务

Certbot 支持 hook。续期成功后 reload Nginx:

bash
certbot renew --deploy-hook "systemctl reload nginx"

不想每次在命令里写也可以把脚本放到 Certbot 的 renewal hooks 目录里。关键不是写在哪,而是证书真的更新后服务会重新加载。

reload 也要测试

certbot renew --dry-run 默认不会直接替换正式证书。新版 Certbot 有 --run-deploy-hooks 参数,可以在 dry-run 成功后执行 deploy hook,但它用的是当前正式证书,不是测试证书。测试 reload 时要看清楚这一点。

泛域名:DNS-01 的问题通常出在细节

如果你要申请 *.example.com,就不能用 HTTP-01,必须用 DNS-01。用 Certbot 的话,通常需要配一个DNS 插件,让它自动创建和清理 _acme-challenge 的 TXT 记录。

DNS-01 的原理很简单:ACME 客户端在 _acme-challenge.example.com 写一条 TXT 记录,Let's Encrypt 查到了正确值,就认为你控制这个域名。

麻烦在工程细节:

  • DNS 服务商必须支持 API。
  • API Token 权限要收小,不能直接用全局密钥。
  • DNS 记录有传播时间,不是控制台显示创建成功就马上能被 CA 查到。
  • 同一个 _acme-challenge 可能需要多个 TXT 值,脚本不能简单覆盖。
  • Token 过期、权限被改、zone 迁移,都会导致续期失败。

周期越短,这些边角条件被触发得越频繁。只要其中一步依赖人工记忆,续期失败就只是时间问题。

多入口部署:签发成功只是第一步

一张 *.example.com 证书可能同时用于:

  • api.example.com 的 Nginx。
  • admin.example.com 的负载均衡。
  • docs.example.com 的 CDN。
  • internal.example.com 的内网网关。

续期后要把同一张证书部署到这些地方,方式还不一样:

  • SSH 主机要复制文件并 reload 服务。
  • 云负载均衡要上传证书并切换监听器绑定。
  • CDN 要调用平台 API 或进控制台替换证书。
  • Kubernetes 要更新 Secret,再等 Ingress 控制器加载。

到这一步,你维护的已经不是一条续期命令,而是一套分发和生效确认流程。部署完成后还要反查线上结果——不能只相信“API 返回成功”,要检查用户访问到的证书是不是新证书。否则就会出现证书平台显示已更新,某个边缘节点或某个旧入口还在返回旧证书的情况。

什么时候该用 CertFlow

CertFlow 不是替代所有 ACME 客户端。单机单站点,用 Certbot 很合适。

它更适合这种场景:

  • 你有多个域名或多张证书。
  • 你在用泛域名证书,需要 DNS-01。
  • 同一张证书要部署到多台服务器或多个云产品。
  • 你不想靠表格记录“这张证书现在放在哪里”。
  • 你希望失败时能知道失败在哪一步,而不是等用户报错。

证书已经分散在多台主机、云产品和 CDN 上时,CertFlow 的价值不在“再签一张证书”,而在续期之后的动作能被串起来:

  1. 证书快到期时自动触发续期。
  2. 通过 DNS-01 完成域名验证。
  3. 续期成功后部署到指定目标。
  4. 跟踪部署目标状态,并配合证书监控发现线上入口是否还在使用旧证书。
  5. 失败时给出明确状态,方便处理。

这样能把问题定位到具体环节:DNS 验证失败、证书续期失败、部署目标失败,还是线上入口仍在返回旧证书。

证书过期是最不复杂的故障

证书有效期从 90 天走向 64 天、45 天以后,原来那些“偶尔手工处理一下”的地方,会越来越容易出事。

证书过期不是复杂故障,它很简单也很刺眼。页面打不开,浏览器直接报错,用户不会关心你是 DNS Token 失效还是某台机器没 reload。

用 CertFlow 管好 Let's Encrypt 续期和部署
CertFlow 可以把 DNS-01 验证、证书续期、多目标部署和线上到期检查放到同一条链路里,适合多域名、泛域名和多入口部署场景。
查看 CertFlow