测试环境炸出一个 502,根因是隔壁把我的证书续期接管了
下午一点十五分,同事丢来一张截图:某个测试环境 502 Bad Gateway。我回了句「我看看」,十八分钟后说了句「好了」。
从报障到恢复一共二十一分钟,听着挺平淡。有意思的是根因,说出来有点离谱:隔壁团队把同一主域的证书自动续期接管到他们那边去了,我们这边的证书就断了供。谁也没通知谁,两边的自动化各干各的,最后由一个 502 来传话。
一张很会甩锅的报错页
先看症状。截图里的报错页写的是:
ERROR: The request could not be satisfied.
We can't connect to the server for this app or website at this time.
There might be too much traffic or a configuration error.
翻译过来就是「我连不上服务器,可能是流量太大,也可能是配置错了」。这页面特别贴心,连理由都替你想好了,还挑了个最唬人的放前面:流量太大。
差一点我就去查带宽和限流了。
502 的字面意思很朴素,网关从上游拿不到有效响应。可这页面是边缘节点吐的,它只知道回源失败了,回源为什么失败一个字没说。看到它,第一反该问的不是「流量是不是扛不住」,而是「边缘到源站这一段,哪一环断了」。
根因三句话就讲完了
事后看,根因就是聊天记录里那三句:
「后端证书本来都是自动续期的。」
「他们那边也有个域名挂在同一个主域下。」
「然后他们把这张证书的自动续期搞到他们那边去了。」
两边共用一个主域的证书,本来续期挂在我们这边跑得好好的。隔壁要接自己的服务过去,顺手把续期也接走了。接走之后,我们这台机器上的证书就再也没人喂,等它出问题的那一刻,报障的人还以为是流量。
修复也快:把续期的归属改回来,证书重新下发,握手恢复。真正的功夫全花在「怎么会变成这样」上。
「接管」为什么能把另一个环境搞挂
这是我最想记下来的部分。同一张证书被两套自动化接管,常见三种死法:
第一种,老任务被停了,证书到期没人知道。 续期是个安静的活,成功了不吭声,失败了往往也只是写进日志。原负责的那套一旦被下掉或者验证权限被迁走,续期就悄悄停了,等到证书过期那天才炸,而那天可能离接管已经过去两个月。
第二种,新任务签的证书根本没装到你这台上。 一台机器签发、安装、reload 是一整套动作,隔壁只做了他们那半套。运气再差一点,共享的证书文件被覆盖成只带他们域名的,你这台握手时主机名对不上,或者私钥跟证书配不上对,一样完蛋。
第三种,回源走 https,握手一失败,反代直接吐 502。 这种在源站日志里其实很好认,经典长相是 SSL_do_handshake() failed,社区里一搜一大堆。麻烦的是这次边缘层抢先把花哨的报错页顶在了前面,源站日志反而没机会露脸,排查方向就这么被带偏了。
三种死法指向同一件事:证书这东西的续期,只能有一个主人。
怎么让这种坑再也炸不出来
一个主域一张证书一个 owner,接管之前必须通知旧 owner。 这条最便宜也最容易被跳过。自动化尤其容易让人产生「反正它自己会跑」的错觉,可两套「自己会跑」撞在一起,就是谁都不跑。
把证书到期天数做成监控。 一条命令的事,谁都能挂到告警里:
echo | openssl s_client -connect example.com:443 -servername example.com 2>/dev/null \
| openssl x509 -noout -enddate
拿到 notAfter 后算个天数,剩三十天就喊人。有了这条,第一种死法根本活不到炸的那天。
502 永远分层定位。 边缘报错、网关报错、回源报错是三件不同的事,先确认故障发生在哪一层,再去那一层的日志里找答案。边缘吐什么都别当结论,它只是个传话的。
节前一天
这事发生在国庆假期的前一天。证书类的事故有个坏毛病,特别爱挑放假前现身,修好了是二十一分钟,修不好就是带着一个 502 走人。
好在这次修好了。我把这几条记下来,下次再有谁说「我把续期接过去了」,我至少知道该先问一句:那旧的那份,你通知了吗喵。