「监控页面白了,你们看下。」
早上 9 点 12,客户运维老周在群里发的,后面跟了张截图。整个浏览器窗口一片白,连浏览器的报错页都没有,就是白。
我第一反应是 grafana 挂了。这套是上个月新上的,grafana 9.5.2,跑在 10.30.7.22,systemd 拉起来的。
ssh 上去,systemctl status grafana-server,active (running),uptime 17 天。curl -s -o /dev/null -w '%{http_code}' http://127.0.0.1:3000/login,200。服务是活的。
那就是 nginx。
这台机器上的 nginx 1.20.1 做反代,配置文件 /etc/nginx/conf.d/grafana.conf。nginx -t 通过,我顺手 reload 了一遍,没报错。翻 access.log,最近一小时全是 200,夹着几个 499。error.log 干干净净。
我给老周说,你 ping 一下 grafana.xxx.com。他说通。telnet 443 也通。
到这儿就卡住了。服务活着,端口通着,日志没东西,白屏是哪来的。
我说你按 F12,看 Console。
两三分钟后截图过来,一整屏红的。
GET https://grafana.xxx.com/api/dashboards/home net::ERR_CERT_DATE_INVALID
后面几十条全是这个。
我心里大概有数了,但还是确认一遍:
openssl s_client -connect grafana.xxx.com:443 -servername grafana.xxx.com </dev/null 2>/dev/null | openssl x509 -noout -dates
notBefore=Apr 9 02:41:33 2024 GMT
notAfter=Jul 8 02:41:33 2024 GMT
今天 7 月 22 号。过期 14 天了。
顺带说一句为什么是白屏不是证书警告页。客户那边自己做了个监控大屏,grafana 是用 iframe 嵌进去的。主页面没问题,iframe 里的证书错误浏览器不弹框,直接静默拦掉,所以整块就是空的。这个坑我两三年前踩过一次,现在看到白屏第一反应就是让人开控制台。
接下来要回答的是,为什么没续上。
证书是 Let's Encrypt 的,certbot 1.21.0 装的,续期靠 systemd timer,一天跑两次。
ls -l /etc/letsencrypt/live/grafana.xxx.com/
fullchain.pem 的时间戳停在 2024-04-09 10:41。三个多月没动过。
timer 是 active 的,在跑。那跑出什么了。
翻 /var/log/letsencrypt/letsencrypt.log。最近一次:
Certbot failed to authenticate some domains (authenticator: nginx). The Certificate Authority reported these problems:
Domain: grafana.xxx.com
Type: connection
Detail: 116.xx.xx.xxx: Fetching http://grafana.xxx.com/.well-known/acme-challenge/8Yt3k...: Timeout during connect (likely firewall problem)
Hint: The Certificate Authority failed to download the temporary challenge files created by Certbot.
这条从 5 月 23 号开始,一天两遍,一天没落。
往前翻到 5 月 22 号还是好的。
5 月 22 号晚上干了什么。翻变更单。安全那边做了一次入站策略收敛,80 端口从全放改成白名单,只留了几个办公段的 IP。443 没动。
Let's Encrypt 的 HTTP-01 校验是从它自己的验证节点发起的,源 IP 不固定,进不了白名单。所以从那以后每一次续期都卡在验证这一步。
certbot 也不降级,也不换别的验证方式,就每天老老实实失败一次,写一行日志,退出。
三个月的日志里,几百条一模一样的报错。
再补一个为什么拖了 14 天。其实 5 月底就续不上了,但证书 7 月 8 号才到期,中间六周是能用的,没人注意。7 月 8 号之后到今天,14 天,为啥没人报?因为看这个页面的就两个人,另一个 6 月底休假到 7 月中,老周那阵子在跟一个机柜搬迁的活,一直拿手机看告警推送,没开过网页。
处理很简单。我临时把 80 端口的白名单放开十分钟,certbot renew --force-renewal,四十多秒签下来,nginx -s reload。老周说好了。
但不能每次都手动开防火墙。去找安全的老郑,问能不能把 Let's Encrypt 的验证段加白名单。他说他们源 IP 是动态的,加不了,让我想别的办法。
行吧。换成 DNS-01。域名托管在阿里云,装 python3-certbot-dns-aliyun,配好 AK,续期走 TXT 记录验证,跟 80 端口一点关系都没有。手动跑了一次,成功。
然后加监控。一个每天早上 8 点跑的小脚本,openssl s_client 拿 notAfter,剩不到 15 天直接告警到值班群。certbot 的日志里出现 fail 两个字也告警。之前那套监控只看了 systemd timer 的状态,timer 一直在正常触发,unit 状态也是绿的——这个是我事后才想明白的,timer 触发成功,跟里面那条命令成没成功,是两码事。我们盯着一个一直绿的东西看了三个月。
上周把这套 DNS-01 推到了另外六台机器上,都是走 HTTP-01 的,怕再踩一次。
顺带一提:我们自研了一款免费的七亿批量远程管理工具,Windows 端,支持 RDP 九宫格、SSH 终端、SFTP/FTP,一台电脑批量管多台服务器。
评论