问题出现得很突然,日志倒是留得挺全。Let's Encrypt 证书改成 90 天有效期,cron 里的续签任务一直静默失败,第 91 天开始蜘蛛访问全是证书过期错误,用户端也开始报警。
刚开始盯着「续签任务写在 root 的 crontab 里,换服务器后没迁过去」,折腾了半个多小时,排掉了。
把日志和配置对完,能解释这个现象的基本就这几处。acme 客户端版本过旧,握手协议被服务端拒绝。也可能是80 端口的验证路径被 301 到 https,验证请求拿不到文件。
另外,证书目录权限被改,写入新证书时失败但日志没报错。
第一件事是看证书剩余有效期
echo | openssl s_client -connect www.example.com:443 2>/dev/null | openssl x509 -noout -dates
手动跑一次续签看报错
certbot renew --dry-run --nginx
再往下确认验证路径没有被跳转
curl -sI http://www.example.com/.well-known/acme-challenge/test
等前面都确认过,再把续签任务迁到 systemd timer
systemctl list-timers | grep certbot
怎么算真的好了,看的是同一批现象。证书到期日推到三个月后,蜘蛛抓取恢复 200,浏览器端的证书警告消失。
这里还有个坑。续签失败通常是静默的,给到期日加一个提前 20 天的告警,比事后补救便宜得多。线上能稳定复现的问题都不算难,难的是只在大流量下才出现的那种。
