云服务器时间不同步导致证书与签到失败:chrony 对时排查
前段时间遇到一件看起来很玄学的事:一台跑了大半年的云服务器,突然开始报证书错误,curl 访问自己的接口提示 certificate has expired;与此同时,每天定时跑的签到脚本也开始失败,服务端返回签名过期。重启服务、重新申请证书、手动重跑脚本,全都没用。最后发现,问题根本不在证书和脚本上——服务器的系统时间比标准时间慢了 7 分钟。
一、时间一偏,处处报错
服务器时间参与两件关键事。
第一是 TLS 证书校验。证书有生效时间(Not Before)和过期时间(Not After),客户端用本地时间判断证书是否在有效期内。本地时间慢了几天,合法证书也会被判过期;本地时间快了几天,还没生效的证书会被提前信任,出问题时很难第一时间联想到时间。
第二是签名和令牌。很多接口签名、JWT、一次性口令都带时间戳和有效期窗口,通常只有几分钟容差。时间偏了几分钟,请求还没发出去,在服务端看来就已经过期了。
所以当证书和签到同时出问题,别急着换证书,先看一眼时间。
二、快速定位:先看时间,再看同步
三条命令,先后顺序别乱:
date
timedatectl
chronyc tracking
date 只告诉你现在几点;timedatectl 告诉你系统时间是否已同步(System clock synchronized)和用的是哪个时区;chronyc tracking 告诉你同步得好不好:System time 一行就是本地时间与 NTP 服务器的偏差,单位是秒,正常应该在毫秒级。
我那台机器查下来:date 显示的时间确实慢了 7 分钟,timedatectl 显示 System clock synchronized: no,chronyc 直接报错找不到服务——chrony 根本没装也没跑,时间是几个月前装机时定下来的,之后一直在慢慢漂。
三、修一次,更要修住
只改时间不修同步,等于没修。正确的做法是装 chrony、设好源、启动并设为开机自启:
dnf install -y chrony
systemctl enable --now chronyd
chronyc tracking
chronyc sources -v
云上的机器一般不用自己搭 NTP 源,用系统默认源或内网源就可以。改完先看 chronyc tracking 的 System time 是否在几十毫秒以内,再看 chronyc sources -v 确认源是可达的(带 ^* 的就是当前在用的源)。如果源全部显示 unreachable,先别怀疑 chrony,往下看第四节。
另外注意时区:
timedatectl set-timezone Asia/Shanghai
很多新手把时间调对了,却忘了时区还是 UTC,业务日志的时间戳全差 8 小时,排查时又是一笔糊涂账。
四、两个容易踩的坑
第一个坑:对时流量被安全组拦了。NTP 走 UDP 123 端口。不少机器的出方向规则只放行了 80/443,chrony 永远连不上源,tracking 里的偏差只会越漂越大。放行 UDP 123 出方向,或者直接用云厂商提供的内网 NTP,往往更稳。
第二个坑:沙箱、容器里没有 systemd。有些沙箱和容器环境 PID 1 不是 systemd,timedatectl 会报无法连接系统总线,chronyd 也起不来。这种环境里别硬装 chrony,退而求其次:用 date 和 date -u 对照本地与 UTC 时间,确认时区和偏差在可接受范围,再把对时交给宿主机或编排层去做。
五、排查清单
以后再遇到证书过期、签名过期、定时任务准点却失败,先按这个顺序查,十分钟就能定性:
- date 看时间对不对,timedatectl 看时区和同步状态;
- chronyc tracking 看偏差,偏差超过 1 秒就值得处理;
- chronyc sources -v 看源通不通,不通先查 UDP 123;
- systemctl status chronyd 看服务在不在、开没开机自启;
- 修好后等一两分钟再复测,别刚启动就下结论。
时间同步是个平时没人惦记、一出问题牵连一大片的基础项。把它当成机器的健康检查项之一,比出了问题再到处换证书、改脚本要省心得多。
- 点赞
- 收藏
- 关注作者
评论(0)