Ccyriak.xyz
首页/笔记/systemd

systemd-timesyncd:时间不准会让证书提前失效

目录

浏览器给出的错误是「你的连接不是私密连接」,证书详情里写着有效期正常、签发者正常。这种情况下大部分人会去查证书链、查中间证书、查 SNI——而真正的原因可能只是这台机器的时钟慢了七分钟。

先怀疑时间,再怀疑证书

证书校验有两端:服务端提供证书,客户端用自己的时钟判断它「现在是否有效」。如果服务端的时钟偏了,会带来两个连锁问题:

  • 签发的证书 notBefore 落在「未来」,客户端立刻判定为尚未生效
  • 自动续期任务的判断依据也是本机时间,可能提前续、也可能永远不续
bash
date -u
timedatectl
# 关键看这三行
#   System clock synchronized: no
#   NTP service: inactive
#   RTC in local TZ: no

synchronized: no 就是结论。机器从开机起就没有和任何时间源对过,它的时间是「上次关机时存进 RTC 的那个值」加上运行时长,误差会一直累积。

为什么小机器上经常没开

Debian 的最小化安装不一定会带上 systemd-timesyncd。它是个独立软件包,不是 systemd 本体的一部分。剪裁过的镜像、容器模板、以及一些 VPS 提供的系统镜像里,它常常是缺失的——于是「装了系统」但「没有时间同步」。

bash
# 看有没有
systemctl list-unit-files | grep -E 'timesyncd|chrony|ntp'

# 装并启用(Debian / Ubuntu)
apt-get install -y systemd-timesyncd
systemctl enable --now systemd-timesyncd

# 等几秒再看
sleep 5
timedatectl show -p NTPSynchronized --value

输出 yes 就成了。如果还是 no,问题在别的地方。

三个时间服务只能开一个

systemd-timesyncd、chrony、ntp 都是 NTP 客户端,同时跑会互相打架——它们会各自把时钟往不同方向拨。检查一下:

bash
systemctl status chrony 2>/dev/null | head -3
systemctl status ntp    2>/dev/null | head -3

如果已经在用 chrony,就别装 timesyncd,直接 chronyc tracking 看偏移量。chrony 更适合网络不稳的环境,timesyncd 胜在「装上就有、不用配」。

UDP 123 被拦掉的情况

NTP 走 UDP 123。有些云厂商的默认安全组、或者偏执的防火墙规则会把它挡在外面,表现就是 systemctl status systemd-timesyncd 一直显示 Connecting。

bash
# 直接测一下能不能出去
timedatectl timesync-status
# 或换一个可达的源
sed -i 's/^#\?NTP=.*/NTP=ntp.aliyun.com time.cloudflare.com/' /etc/systemd/timesyncd.conf
systemctl restart systemd-timesyncd

国内机器上用 ntp.aliyun.com 或 ntp.tencent.com 比默认的 *.debian.pool.ntp.org 稳,后者经常解析到很远的节点甚至直接超时。

容器里的特例

如果是容器,容器通常共享宿主机内核时钟,自己启动 NTP 客户端没有意义,还可能因为没有 CAP_SYS_TIME 直接失败。这种情况该去修宿主机,容器里只需要确认 date 读到的值是对的。

把它写进部署检查清单

这件事的教训不是「要开时间同步」,而是它该被检查,而不是被假设。我现在的做法是:任何新机器上完系统,先跑三行——

bash
timedatectl show -p NTPSynchronized --value   # 期望 yes
df -h / | tail -1                              # 磁盘还有多少
free -m | awk '/^Mem:/{print $3"/"$2" MB"}'    # 内存基线

三十秒的事,能省掉后面几个小时的排查。证书类问题最麻烦的地方就在于:它的症状和原因之间离得很远,而时间是那个最容易被跳过的怀疑对象。