Ubuntu / Debian 设置北京时间与修复 NTP 同步

记录把 Ubuntu / Debian 服务器时区改为 Asia/Shanghai,并在 DNS 分流、FakeIP 或透明代理环境下修复 systemd-timesyncd NTP 同步失败的方法。

这篇记录一次内网 sing-box 旁路网关上的时间修复过程。表面问题是系统显示 UTC,实际继续检查后发现 systemd-timesyncd 虽然在运行,但一直没有同步成功;NTP 域名被 DNS 分流解析成 FakeIP,UDP/123 请求没有拿到回复。

目标有两个:

  1. 系统本地时间显示为北京时间。
  2. NTP 服务真正同步成功,而不是只把时区改成 Asia/Shanghai

检查当前时间状态

先看系统时区、UTC 时间、RTC 时间和 NTP 同步状态:

timedatectl
date

如果看到类似下面的状态,说明时区还是 UTC,而且 NTP 没有同步成功:

Local time: Tue 2026-06-02 14:16:50 UTC
Universal time: Tue 2026-06-02 14:16:50 UTC
Time zone: Etc/UTC (UTC, +0000)
System clock synchronized: no
NTP service: active

这里容易误判:NTP service: active 只表示服务开着,不代表已经校时成功。真正要看的是:

System clock synchronized: yes

设置北京时间时区

设置为中国大陆常用的 Asia/Shanghai

timedatectl set-timezone Asia/Shanghai
timedatectl set-ntp true
timedatectl
date

设置完成后应看到:

Time zone: Asia/Shanghai (CST, +0800)

如果只是时区问题,到这里就够了。但如果 System clock synchronized 仍然是 no,需要继续排查 NTP。

排查 NTP 同步失败

查看 systemd-timesyncd 日志:

systemctl status systemd-timesyncd --no-pager -l
timedatectl timesync-status --no-pager

在 DNS 分流或 FakeIP 环境中,可能会看到类似日志:

Timed out waiting for reply from 28.0.0.60:123 (ntp.ubuntu.com).

这里的 28.0.0.60 是 sing-box FakeIP 地址,不是真实 NTP 服务器地址。对浏览器、GitHub、AI 服务这类流量,FakeIP 很有用;但对系统本机的 NTP 服务,尤其是 UDP/123,可能导致 timesyncd 长期收不到响应。

再看本机 DNS:

resolvectl status

如果服务器自己的 DNS 指向旁路网关或本机 sing-box,例如:

DNS Servers: 10.20.20.12

而 NTP 域名又被解析到 FakeIP,就可以考虑给 timesyncd 单独指定更适合直连的国内 NTP 源。

配置国内 NTP 源

创建一个独立 drop-in 配置,不直接改主配置文件:

mkdir -p /etc/systemd/timesyncd.conf.d
nvim /etc/systemd/timesyncd.conf.d/local-cn.conf

写入:

[Time]
NTP=ntp.aliyun.com ntp.tencent.com cn.pool.ntp.org
FallbackNTP=ntp.ubuntu.com time.cloudflare.com

重启 timesyncd:

systemctl restart systemd-timesyncd

等待几秒后检查:

timedatectl
timedatectl timesync-status --no-pager
systemctl status systemd-timesyncd --no-pager -l

正常结果类似:

System clock synchronized: yes
NTP service: active
Server: 203.107.6.88 (ntp.aliyun.com)

systemd-timesyncd 日志里也会出现:

Contacted time server 203.107.6.88:123 (ntp.aliyun.com).

最终确认

最终确认命令:

timedatectl
date
cat /etc/systemd/timesyncd.conf.d/local-cn.conf

期望看到:

Local time: Tue 2026-06-02 14:17:29 CST
Universal time: Tue 2026-06-02 06:17:29 UTC
Time zone: Asia/Shanghai (CST, +0800)
System clock synchronized: yes
NTP service: active

关于 RTC

Linux 服务器通常建议 RTC 保持 UTC:

RTC in local TZ: no

不要为了显示北京时间而把硬件时钟改成本地时区。服务器、容器、日志和跨时区同步都更适合 RTC 使用 UTC,本地显示交给 Time zone 处理。

小结

这次修复不是简单地执行 timedatectl set-timezone Asia/Shanghai。真正的问题链路是:

系统时区是 UTC
NTP 服务 active 但未同步
ntp.ubuntu.com 被解析到 FakeIP
UDP/123 没有收到 NTP 响应
改用国内 NTP 源后同步成功

在透明代理、FakeIP、旁路网关环境中,时间同步最好单独验证一次。NTP service: active 不是终点,System clock synchronized: yes 才是。