Skip to content

续期与自动化

目标:让证书在 90 天到期前自动滚动续期,并让新证书自动生效。这是上线后的头等大事。

1. 续期机制

  • 证书有效期 90 天。
  • certbot renew 会扫描 /etc/letsencrypt/renewal/ 下的所有配置,只续期距到期 ≤ 30 天的证书(阈值 renew_before_expiry 默认 30 天)。
  • 续期会复用首次签发时的插件与参数(存在 renewal/*.conf),所以首次签发时参数要正确
bash
sudo certbot renew            # 续期所有到期证书(无到期则什么都不做)
sudo certbot renew --dry-run  # 演练:走流程但不真正签发,验证配置没问题

2. 自动续期的两种方式

2.1 systemd timer(推荐,apt/snap 一般自带)

bash
# 查看定时器
systemctl list-timers --all | grep -i certbot
systemctl status certbot.timer          # apt 版
systemctl status snap.certbot.renew.timer   # snap 版
  • 默认每天两次尝试续期(实际只在到期前 30 天才真正续)。
  • 若未启用,可手动启用:
bash
sudo systemctl enable --now certbot.timer   # 名称以实际为准

2.2 cron(老式 / pip 安装)

bash
# 编辑 root 的 crontab
sudo crontab -e

# 每天两次尝试续期(随机分钟避免同时请求)
0 0,12 * * * certbot renew --quiet

新版 certbot 推荐用 systemctl 的 random delay;cron 里也建议加随机偏移避免全网整点扎堆。

3. 续期后让服务生效

续期只替换 live/ 下的文件,Web 服务器不会自动重新加载,需要 hook:

Hook触发时机
--pre-hook续期(如:停掉占用端口的服务)
--post-hook续期,无论成败(如:重启服务)
--deploy-hook续期成功且证书已更新后(推荐用这个重载服务)
--renew-hook每次续期尝试结束时(旧版语义,尽量用 deploy-hook)

3.1 命令行一次性使用

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

3.2 写入 renew 配置(持久化,推荐)

编辑 /etc/letsencrypt/renewal/example.com.conf,在 [renewalparams] 段加:

ini
[renewalparams]
deploy_hook = systemctl reload nginx

或首次签发时就带上 --deploy-hook,会被自动记录。

3.3 通用钩子(对所有证书生效)

/etc/letsencrypt/cli.ini 中配置全局 hook(见 配置与文件布局),或在 systemd service 里加。Nginx/Apache 插件的常见做法:

bash
sudo certbot renew --nginx    # nginx 插件会自动重载
sudo certbot renew --apache

4. 实战:完整可维护配置

bash
# 首次签发即带上部署钩子
sudo certbot certonly --webroot -w /var/www/html \
  -d example.com -d www.example.com \
  --deploy-hook "systemctl reload nginx" \
  --email ops@example.com --agree-tos --no-eff-email --non-interactive

# 立即演练一次续期(确认 hook 也能正常跑)
sudo certbot renew --dry-run

deploy-hook 只在"证书确实更新"时执行,不会每次都无谓重启服务。

5. 手动强制续期(排查用)

bash
sudo certbot renew --force-renewal           # 无视到期时间强制续
sudo certbot renew --cert-name example.com   # 只续某张证书
sudo certbot renew --force-renewal --cert-name example.com

6. 验证续期是否健康

bash
# 看证书到期时间
sudo certbot certificates
# 或直接读证书到期日期
echo | openssl s_client -servername example.com -connect example.com:443 2>/dev/null | openssl x509 -noout -dates

# 确认定时器在跑
systemctl list-timers | grep -i certbot

# 看日志(定位某次续期失败原因)
sudo tail -n 100 /var/log/letsencrypt/letsencrypt.log

7. 常见坑

  • 改过配置要重新验证:如果站点结构变了(如换了 webroot 目录),先 renew --dry-run 看是否还通。
  • manual 模式不能自动续期:手动 DNS 签发的证书,续期会卡在交互。改用 dns-* 插件或 hook 脚本(见 插件与验证方式)。
  • 续期失败告警:证书到期前 30 天若续期反复失败,你只有 30 天窗口处理。建议监控 certbot certificates 的到期时间,或用 --deploy-hook 里发通知。
  • 端口占用:standalone 方式续期时会临时占 80/443,若服务没停会失败——这正是 --pre-hook "systemctl stop nginx" + --post-hook "systemctl start nginx" 的用途。