为什么要自动:90 天有效期是设计上逼你把流程跑熟
Let's Encrypt 把证书有效期压到 90 天,不是要折腾你,而是要你杜绝"长有效期证书忘了换"这种事故。90 天意味着一年要续四次,手动记住几乎必然失败,续期必须自动化才能守住站点不断线。
续期机制的原理是重签:certbot renew 会读到期日前 30 天内的证书,重新走一遍签发流程换新证。它只重签快到期或已过期的,其余在"还有效"区间的会跳过,所以每周跑一次 renew 很安全。
certbot --version
sudo certbot certificates
# 干跑一遍,看会不会重签
sudo certbot renew --dry-run
# 看每张证的到期时间
sudo certbot certificates | grep -E "Expiry Date|Certificate Name"签发方式选择:webroot 优于 standalone 的两个理由
standalone 模式要临时占用 80 端口,y 是证书上的挑战仅由 certbot 自己应答,如果你的 80 端口让 nginx 占着、或者前面还有负载均衡,standalone 就撞车或得不到准确校验。webroot 是验证服务器往你指定目录写一个 token 文件,让正在跑的 Web 服务代为响应,改到最小。
对大多数有 nginx 的部署,webroot 是稳健默认;只有反向代理把 / 和 acme 目录逻辑绕走时才要考虑 DNS-01。webroot 前提是 nginx 愿意把 /.well-known/acme-challenge/ 这个路径直接指到我们的目录,这一步作为下面第一步做掉。
# nginx: 让 ACME 校验流量落在 webroot
location /.well-known/acme-challenge/ {
root /var/www/certbot;
default_type text/plain;
}
# 目录与权限
sudo mkdir -p /var/www/certbot/.well-known
sudo chown www-data:www-data /var/www/certbot -R
sudo nginx -t && sudo systemctl reload nginx首次签发:指定 webroot 与域名组合
签发命令的关键是 -w(webroot 路径)和 -d(域名)成组出现;一张证对应多个域名时,每加一个域名都要带上各自的根路径,否则 certbot 会警告 "The requested /path was not a ..." 之类。
还要说清 chain:签发成功后会得到 fullchain.pem 与 privkey.pem 两个关键产物,nginx 的 ssl_certificate 与 ssl_certificate_key 分别指向它们。证书生成后立刻做一次 https 冒烟,确认可用而不是等到配置完才发现链断了。
sudo certbot certonly --webroot -w /var/www/certbot \
-d example.com -d www.example.com \
-m admin@example.com --agree-tos --no-eff-email
# 校验产物存在
sudo ls -l /etc/letsencrypt/live/example.com/
# 立即冒烟
curl -sI https://example.com -o /dev/null -w "%{http_code}\n"auto 续期接入:certbot.timer 与 cron 两份保险
certbot 安装包自带 systemd 的 renew.timer,每天会触发两次检查,多数发行版装好即开。验证它是开着的即可;若你的发行版没带 timer 或者你希望月底固定跑并附带重启 Nginx,就用 cron 补一道。
续期后 Deploy 钩子是个隐藏杀招:在续期成功后自动 reload Nginx,避免"证换好了但 Server 不知道自己持有的已不是旧证"这种经典续期失效。下面给出 timer 状态核对 + cron + deploy 钩子三段。
# 系统自带 timer 是否启用
sudo systemctl status certbot.timer
# 兜底 cron:每周一凌晨 2:30 续期并 reload
30 2 * * 1 certbot renew --quiet --deploy-hook "systemctl reload nginx"
# deploy 钩子示例(放到同目录):
# /etc/letsencrypt/renewal-hooks/deploy/reload-nginx
systemctl reload nginx
# 验证续期链路
sudo certbot renew --dry-run常见误区与修复:renewal 配置指错了 webroot
相当常见的坑是:首次签发用 -w 指定了正确 webroot,而后为了验证或别的原因改了目录,renewal 配置里的 old webroot 却没有跟随,续期时 ACME 校验变 404,证书悄悄盯在过期路上。
修复时不要改 /etc/letsencrypt 下的 renewal 配置文件手抄心记的路径,直接看证书目录里的 renewal conf 并校正 installer 与 webroot 字段,或者干脆重新 certonly 让 certbot 重写它。改完跑 --dry-run 验证路径正确。
# 错误示范:改了目录没同步 renewal 配置
# apt move /var/www/certbot /srv/acme # 然后忘了改 webroot
# 修复对照:查看并校正 renewal 配置
sudo cat /etc/letsencrypt/renewal/example.com.conf | grep -i webroot
# 重新签发以重写配置
sudo certbot certonly --webroot -w /srv/acme -d example.com --force-renewal
sudo certbot renew --dry-run