如何用 cron 自动续期 Let's Encrypt 证书?
Let's Encrypt 证书自动续期:certbot renew 原理、官方推荐的每日两次 cron 写法、--deploy-hook 重载 Nginx、续期失败监控与 FAQ。
定期运行 certbot renew,由 Certbot 根据版本、证书有效期、配置及可用的 ACME Renewal Information(ARI)判断续期窗口,不能把所有证书都固定理解为 90 天有效、剩 30 天才续。常用方案是每天检查两次,不到窗口的证书会跳过。 多数发行版装 certbot 时已自带 systemd timer/cron 规则,先检查再决定要不要手写。
1. 安装 certbot
# Ubuntu/Debian
sudo apt install certbot python3-certbot-nginx
# RHEL/CentOS(EPEL)
sudo dnf install certbot python3-certbot-nginx
2. 先检查:可能已经有自动续期了
systemctl list-timers | grep certbot # systemd timer(现代发行版默认)
ls /etc/cron.d/ | grep certbot # 或者 cron 规则
sudo certbot renew --dry-run # 演练一次,验证续期流程可用
有 timer 就不要再加 cron,两套并行徒增混乱。
演练后检查 certbot 日志中的失败原因。通过观测云 DataKit采集实际日志文件时,保留域名和执行时间;续期成功后再从客户端检查服务实际返回的证书,避免把文件已更新误认为服务已加载。
3. 手写 cron 规则(没有自带时)
# /etc/cron.d/certbot:每天 03:17 和 15:17 各检查一次
17 3,15 * * * root certbot renew --quiet --deploy-hook "systemctl reload nginx"
要点:
- 官方推荐每天两次:提供重复检查与重试机会,仍需按实际证书有效期和告警窗口监控。
--quiet:无动作时不输出,避免 cron 邮件轰炸。--deploy-hook:仅在真正续期成功后执行——重载 Web 服务器加载新证书。别把 reload 写在外面,否则每天白重载两次。- 时间错开整点(03:17 而非 03:00),减轻 LE 服务器压力,也避免和其他整点任务挤在一起。
4. webroot / standalone 的特殊情况
- nginx/apache 插件模式:按保存的 authenticator/installer 配置验证与安装,是否需要额外 reload hook 须核对插件与实际服务配置。
- webroot 模式:
certbot renew复用申请时的 webroot 路径,无需停站。 - standalone 模式:续期瞬间要独占 80 端口,如 Nginx 占用该端口,可用
--pre-hook "systemctl stop nginx" --post-hook "systemctl start nginx"配合;这会中断服务,且不要与停止期间执行的 reload deploy-hook 盲目叠加。
常见问题(FAQ)
Q:证书还有 60 天,手动 renew 会怎样?
A:certbot 通常会提示"未到续期窗口"并跳过,但配置或 CA 提供的 ARI 窗口可能要求提前续期。旧版本采用 30 天阈值;Certbot 4.0+ 的回退规则按有效期比例判断,短期证书另有规则,并可优先采用 CA 提供的 ARI 窗口。--force-renewal 可强制(注意 LE 有速率限制,别玩过头)。
Q:续期后浏览器还是旧证书?
A:可能是 Web 服务器没 reload,也可能是访问了代理/负载均衡器或其他证书路径。确认 --deploy-hook 配置,或检查 Nginx 是否以 daemon 方式正常收到了 HUP。
Q:多域名证书会分别续期吗?
A:同一张多域名证书的域名一起续期,不是每个域名单独续;certbot renew 会遍历 /etc/letsencrypt/renewal/ 下所有证书配置,该续的都续,一次命令全覆盖。