续期与自动化
目标:让证书在 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 --apache4. 实战:完整可维护配置
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-rundeploy-hook 只在"证书确实更新"时执行,不会每次都无谓重启服务。
5. 手动强制续期(排查用)
bash
sudo certbot renew --force-renewal # 无视到期时间强制续
sudo certbot renew --cert-name example.com # 只续某张证书
sudo certbot renew --force-renewal --cert-name example.com6. 验证续期是否健康
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.log7. 常见坑
- 改过配置要重新验证:如果站点结构变了(如换了 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"的用途。
