续期任务日志里写着 Certificate renewed,到期日已经往后推了三个月,浏览器打开还是提示证书已过期,用户截图来问是不是没生效。日志里能对上时间点,这种反而好排。

certbot 把新文件写进 archive 目录也把软链换掉了,nginx 的 worker 进程手里还攥着旧的 inode,不做一次 reload 就一直拿老证书对外握手,磁盘和线上完全是两回事。这一点先确认清楚,后面就不用反复试。

L=/etc/letsencrypt/live/example.com
openssl s_client -connect example.com:443 </dev/null \
 | openssl x509 -noout -enddate
openssl x509 -enddate -noout -in $L/fullchain.pem
nginx -t && nginx -s reload

这次卡住的地方就在「证书续期未重载」这一环,单独把它拎出来验证,别和其他改动混在同一次发布里。线上出问题先对时间点,跟发布、备份、任务执行的时刻排一排,能省掉一半功夫。

处理上按这个顺序:先对比磁盘证书和线上握手拿到的到期日,确认是不是没生效;确认不一致后在低峰期 reload 一次 nginx,避开正在发布的窗口;把 reload 写进续期脚本的钩子里,以后不再靠人记这一步。

结果对不对很好判断,s_client 输出的 notAfter 跟磁盘上的文件一致,浏览器刷新后也不再提示证书过期。

作者 9823189