上周四早上九点四十,开发在群里喊:登录接口大面积报错,全是证书校验失败。我第一反应是证书过期了,登服务器 curl 了一下 https 自己,好的,证书还有 287 天才到期。那就不是证书的事。

再细看报错,客户端那边抛的是 x509: certificate has expired or is not yet valid。not yet valid?这就怪了,证书明明是好的。我脑子转了半天,突然想起半年前另一台机器出过一模一样的问题——当时排查了两个小时,最后发现是那台机器时间慢了四分钟,客户端拿"过去的时间"去校验服务端证书,证书在本地时间轴上还没生效,直接 not yet valid。

赶紧 timedatectl 一看:

# timedatectl
      Local time: Thu 2026-08-20 09:37:14 CST
  Universal time: Thu 2026-08-20 01:37:14 UTC
        RTC time: Thu 2026-08-20 01:40:41 CST
       Time zone: Asia/Shanghai (CST, +0800)
     NTP enabled: yes
NTP synchronized: no

NTP synchronized: no。再对一下真实时间,这台机器慢了 3 分 47 秒。当时我就来气了——NTP enabled 明明开着,为什么没同步?

查 chrony 状态:

# chronyc tracking
Reference ID    : 127.127.1.1 (127.127.1.1)
Stratum         : 10
Last offset     : +227.6 seconds

Reference ID 是 127.127.1.1,这是本地时钟源。也就是说 chrony 根本连不上任何上游 NTP 服务器,一直在拿本地时钟当参考,自然越走越偏。查 /etc/chrony.conf,server 配的是内网一台 NTP 服务器 10.0.0.8,但 chronyc sources 一看全是 unreachable。ping 10.0.0.8 通,UDP 123 端口却是不通的——后来查防火墙,这台新上架的机器出站规则里漏了 UDP 123,NTP 包全被丢了。

修起来倒简单,三条命令:

# chronyc makestep
200 OK
# chronyc sources
210 Number of sources = 1
MS Name/IP address         Stratum Poll Reach LastRx Last sample
^* 10.0.0.8                       2   6   377    25  -8us[ -5us] +/- 301us

makestep 直接跳变,时间拉回来,再验证同步正常。然后去防火墙把 UDP 123 出站加上,省得下台机器再踩。

修完群里的报错自己就消了,开发都没再说话。我倒是记了一笔:这已经是第二次栽在"时间不对"上了,上次是四分钟,这次三分四十七秒。事后我在监控里加了个时间偏差告警,偏差超过 10 秒就报。当时觉得挺完善,结果下个月巡检一看,告警一直没触发过——因为监控探针自己也跑在同一批机器上,大家一起慢,谁都发现不了。后来把 NTP 监控独立到另一台机器上才算完。

写出来就是提醒一句:证书校验失败不一定查证书,先看一眼服务器时间。还有,NTP 出站端口这种基础规则,新机器上架清单里最好有,不然哪天就在这上面耗一上午。