HTTPS 证书自动续期,差点因为一行配置失效
我给自己这个小站上 HTTPS,是照着教程一步一步弄下来的。证书用的是 Let's Encrypt,免费,一张 90 天有效期,到期前靠定时任务自动续。当时看完那段说明,我心里的想法特别简单:这事配一次就不用管了。然后就把注意力挪到别的地方去了。
直到前阵子做例行检查,看到证书剩余天数那一栏,我才有点后背发凉。不是已经出事,而是差一点就出事——而且问题不在证书身上,在我自己手上。
一开始,我把它当成"配完就不用管"的事
上 HTTPS 这件事,真正的难点其实不在装证书,而在别让它过期。手动续期那种做法我不是没想过:三个月提醒一次,全靠人记得。可人一忙就会忘,忘了就是站点直接报错。所以我很自然地走了自动那条路——签一次,然后交给定时任务,它每天自己去看一眼要不要续,快到期就悄悄续上。
配好之后,浏览器地址栏里那个小锁头亮着,看着确实安心。我默认这件事已经"解决"了,后面好几个月都没再碰过它。
它的"自动",其实是每个月来敲一次门
后来我才认真去看它到底是怎么续的。免费证书不是发给你就永久归你,签发机构要定期确认"这个域名现在还是不是你在管"。这个确认不是发邮件问你,而是——它在你的网站上临时放一个验证文件,然后从外网去访问它,能读到约定的内容,就算通过,接着给你发一张新的。
所以续期成功不成功,取决于一件特别具体的事:那条验证路径,从外网是不是能直接访问到,能不能老老实实把文件内容吐出来。
这里有个容易被忽略的点:验证程序不会"理解"你的配置。它只管发一个请求,然后看返回什么。返回了正确内容,通过;返回一个跳转、一个错误页、或者干脆 404,就是不通过。它不关心你那个跳转跳到哪儿去了,也不关心页面打开得多好看。
我干的那件蠢事
前段时间我在整理站点配置,翻到那条验证路径的规则时犯了个嘀咕:这个目录平时是空的,看着好像没什么用,还占一段配置,是不是有点多余?
于是我顺手把它改了——让它跳到首页去,或者干脆并进别的规则里一起处理。改完我刷新了站点,一切正常:页面打得开,速度也挺快,控制台干干净净,什么异常都看不出来。我甚至还有点小得意,觉得配置总算清爽了一些。
现在回头看,这就是整件事最要命的地方。我删掉的不是什么冗余配置,而是两个多月以后那次续期的唯一入口。
你以为你在清理一段没用的空目录规则,其实你在拆掉一个定时任务的前提。区别在于,前者你当场就能看到结果,后者要等两个多月才发作。
给验证路径留的位置,大概是长这样的,注释那两行是我后来才补上的:
# ⚠️ 这段不能删,也不能改成跳转
# 自动续期会从这里读验证文件,改掉=到期后站点直接报证书错误
server {
server_name example.com;
location ^~ /.well-known/acme-challenge/ {
root /var/www/example;
default_type "text/plain";
}
}
这类故障最坑人的地方,是它有很长的沉默期
改完配置的那一天,站点正常。那一周,正常。甚至接下来一整个月,都正常得让你根本想不起来自己动过什么。因为证书还没到期,续期任务压根没走到需要验证的那一步。
等到它真的开始验证、真的验证失败,事情也不会立刻爆出来。任务只是在后台记一行失败,那张旧证书还在硬撑着继续用。而定时任务的日志,说实话,没人会天天去翻。
最后的结果就是:某天你或者别人打开站点,浏览器直接甩一个证书错误页面,红通通一片。这时候你去查日志、查配置,唯一的线索是"两个多月前有人动过一次配置"——而那个人就是你,可你早就不记得当时改了什么、为什么改。
更别扭的是排查方向。看到证书报错,人的第一反应都是去看证书、看续期任务、看网络,很少有人会立刻想到"是不是有人把某个看着没用的路径给清理了"。故障现场和真正的原因,中间隔着两个多月,这就是它最难受的地方。
后来我给自己定了这么几条规矩
- 配置里给这条验证路径写上醒目注释,把话说明白:不能删、不能改成跳转、不能并进别的规则。别指望几个月后的自己还记得这件事,注释是写给未来的自己看的。
- 定期做一次"演练续期"。让续期程序假装续一次,但不去真的签发证书。它走的是同一套验证流程,几分钟就能跑完。能通就说明路是活的,不通会当场报错——这个问题本来要等两个多月才暴露,现在提前到了几分钟。
- 续期任务跑完要留记录。成功也好失败也好,都留个痕迹,别无声无息。最好是失败的时候能主动吵醒你,而不是安静地写进一个永远不会被打开的文件里。
- 把证书到期日记下来,留足提前量。别等到只剩三天才去看,那时候万一出问题,你想改都没时间试。
- 改配置之前先问自己一句:这一段,会不会有别的流程正在依赖它?看不懂、拿不准的,就先别动,或者先备份再动。
这几条我全写进了自己的检查清单里。尤其是"演练续期"这一条,性价比最高——它几乎是唯一能在事前把问题揪出来的办法,其余的都得等出事。
说到底,"自动"从来都不等于"不用管"
这件事给我的教训,其实比证书本身大得多。我们平时挂上去的那些自动任务——自动备份、自动同步、自动续期、自动清理——看上去都是"配好就完事",但每一个"自动"背后,都站着一串它默认成立的前提:某个路径还在、某个权限没变、某个服务还开着、某段配置没被顺手改掉。
而这些前提,恰恰都是你在做别的事情时,最容易顺手清理掉的东西。因为清理的那一刻,它们看起来都像没用的垃圾。
凡是靠定时任务自动完成的事,都值得多问一句:它依赖哪些前提?这些前提会不会被我哪天顺手改掉?如果答案是"会",那就得给它留一道能提前报警的关卡。
现在每条自动任务我都尽量做到三件事:前提写在注释里、定期手动演练一遍、跑完留下记录。听起来有点啰嗦,但比起三个月后打开网站看到一片红色警告,这点啰嗦实在不算什么。
本文写于 2026-09-12,记录的是当时的情况与做法,未必适用于所有环境,仅供参考。