NTP 实战与排错 — chrony/ntpd/timedatectl 与时间不同步定位

Wireshark 抓 NTP、chronyc/ntpq/timedatectl/w32tm 命令、配置与时间漂移排错 / 应用层 / UDP 123

这篇你能学到

  • 如何用 Wireshark / tcpdump / tshark 抓并读懂 NTP 报文(Mode、Stratum、refid、四时间戳、KoD),以及怎么确认 monlist 已关闭。
  • chronyc / ntpq / timedatectl / w32tm 全套命令怎么用、输出符号怎么读、chrony.conf / ntp.conf 怎么配。
  • “时间不同步 / offset 抖动 / falseticker / 时间跳变 / Kerberos 偏斜 / 全是 ? / 被当反射源"的排错思路,以及 NTP vs chrony vs PTP 的选型。

1. 抓包观察

1.1 Wireshark 显示过滤式

这组过滤式能干什么:从海量 UDP 里只挑 NTP 流量,按模式(客户端/服务端/危险的 mode 7)、层级、闰秒、参考源、根延迟过滤,快速定位问题包。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
ntp # NTP 解析器
udp.port == 123 # 标准端口
ntp.flags.mode == 3 # 客户端请求
ntp.flags.mode == 4 # 服务端响应
ntp.flags.mode == 7 # 私有模式(monlist!应当为 0 条)
ntp.stratum # 层级
ntp.stratum == 0 # Kiss-o-Death 报文
ntp.stratum == 16 # 对端未同步
ntp.flags.li == 3 # 时钟未同步告警
ntp.flags.li == 1 || ntp.flags.li == 2 # 闰秒预告
ntp.refid # 参考源:GPS/PPS/上游IP
ntp.rootdelay > 0.1 # 根延迟过大(可信度低)
ntp.precision
udp.port == 123 && ip.src == 203.107.6.88 # 指定服务器

命令行:

1
2
3
4
5
6
sudo tcpdump -i any -nn 'udp port 123' -w ntp.pcap -c 20
tshark -r ntp.pcap -Y ntp -T fields \
  -e frame.time_relative -e ip.src -e ntp.flags.mode -e ntp.stratum \
  -e ntp.refid -e ntp.rootdelay -e ntp.rootdispersion
# 实时观察
sudo tshark -i any -f 'udp port 123' -Y ntp -V | grep -E 'Stratum|Reference|Root|Timestamp'

1.2 典型字段说明(怎么读一个 NTP 响应)

字段正常值异常判读
Flags.Leap Indicator0(no warning)3 = 对端自己都没同步,别用它
Flags.Version43 为老版本,兼容但建议升级
Flags.Mode请求 3 / 响应 4出现 7(private)= monlist 探测,安全告警
Peer Clock Stratum1~416 = 未同步;0 = Kiss-o-Death(看 refid)
Peer Polling Interval6~10(64~1024 s)过小可能触发服务端限速(KoD RATE)
Root DelayLAN < 1 ms,公网 < 100 ms过大说明上游链路差,精度受限
Root Dispersion< 100 ms越大越不可信;chrony 用它算 root distance
Reference IDGPS/PPS/.GPS. 或上游 IPv4RATE/DENY/RSTR = 被限速或拒绝
Origin Timestamp等于客户端发出的 t1不匹配 → 伪造包或串包,客户端应丢弃
Receive/Transmit Timestamp单调递增t3 < t2 异常;两者差过大说明服务端处理慢

快速心算校验delay = (t4-t1) - (t3-t2)。若 Wireshark 中相邻请求/响应帧的时间差远大于该 delay,说明本地处理或抓包点引入了额外延迟。

1.3 安全检查:确认 monlist 已关闭

这组命令能干什么:验证你的 NTP 服务端有没有暴露 monlist 这个 556 倍反射放大入口,有响应就是风险。

1
2
3
4
# 应无响应或返回错误(有响应 = 存在反射放大风险)
ntpdc -n -c monlist <目标IP>
nmap -sU -p 123 --script ntp-monlist <目标IP>
# chrony 不实现 mode 7,天然免疫

2. 常用命令 / 配置

2.1 通用:查看系统时间状态(systemd)

这组命令能干什么:总览系统时间/时区/NTP 开关,设时区、开关网络同步、读写硬件时钟——排错第一步先看这里。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
timedatectl # 总览:本地时间/UTC/时区/NTP 是否启用/是否已同步
timedatectl status
timedatectl set-timezone Asia/Shanghai # 设置时区
timedatectl set-ntp true # 启用网络时间同步
timedatectl set-ntp false # 关闭(改用 chrony/ntpd 前需先关 systemd-timesyncd)
timedatectl list-timezones | grep Shanghai
timedatectl set-time "2026-08-03 10:00:00" # 手工设时(需先关 NTP)
timedatectl show-timesync --all # systemd-timesyncd 的详细同步状态

hwclock --show # 读硬件时钟(RTC)
sudo hwclock --systohc # 系统时间写入 RTC
sudo hwclock --hctosys # RTC 写入系统时间
date -u; date +%s # UTC 时间 / Unix 时间戳

2.2 chrony(现代 Linux 默认,推荐

这组命令能干什么:启停服务、看时间源列表(最常用 chronyc sources)、看详细同步状态(chronyc tracking)、紧急校时。chronyc sources 输出符号是判断"谁被选中/谁在说谎/谁不可达"的关键。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
sudo systemctl status chronyd
sudo systemctl enable --now chronyd

chronyc sources -v # 时间源列表(最常用)
chronyc sourcestats -v # 各源的频率/偏移统计
chronyc tracking # 当前同步状态汇总(最重要)
chronyc ntpdata # 每个源的详细 NTP 报文字段
chronyc activity # 在线/离线源计数
chronyc makestep # 立即步进校时(应急)
chronyc burst 4/4 # 立即连发 4 个请求加速收敛
chronyc -a 'burst 4/4' && sleep 10 && chronyc -a makestep
chronyc serverstats # 作为服务端时的统计
chronyc clients # 谁在向我同步
chronyc -n sources # 不做 DNS 反解(更快)

读懂 chronyc sources 输出:

1
2
3
4
5
6
MS Name/IP address Stratum Poll Reach LastRx Last sample
===============================================================================
^* 203.107.6.88 2 6 377 23 -1234us[-1189us] +/- 12ms
^- 120.25.115.20 2 6 377 21 +5678us[+5678us] +/- 28ms
^+ ntp.tuna.tsinghua.edu.cn 2 6 377 19 -892us[ -892us] +/- 15ms
^? 10.0.0.99 0 10 0 - +0ns[ +0ns] +/- 0ns
符号含义
^服务器(= 为对等体,# 为本地参考时钟)
*当前选中的同步源
+可接受的备选源(参与合并)
-被聚类算法排除的源
xfalseticker(与多数源矛盾,被判为说谎)
?不可达(Reach=0)
~变化过大,时间不稳定
Reach8 位八进制可达寄存器。377 = 最近 8 次全部成功(理想值);0 不可达;177/376 表示有丢包
LastRx距上次收到响应的秒数
Last sample偏移[修正后偏移] +/- 误差范围

chronyc tracking 关键行:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
Reference ID : CB6B0658 (203.107.6.88)
Stratum : 3
System time : 0.000123456 seconds slow of NTP time ← 当前偏差
Last offset : -0.000012345 seconds
RMS offset : 0.000234567 seconds ← 长期均方根偏差
Frequency : 12.345 ppm fast ← 本机晶振偏差
Skew : 0.123 ppm ← 频率不确定度
Root delay : 0.012345 seconds
Root dispersion : 0.001234 seconds
Leap status : Normal ← 闰秒状态

/etc/chrony/chrony.conf(Debian)或 /etc/chrony.conf(RHEL):

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
# 时间源:iburst 加速首次收敛(连发 4 个包)
pool ntp.aliyun.com iburst maxsources 4
server ntp1.aliyun.com iburst
server ntp.ntsc.ac.cn iburst # 国家授时中心
server time.cloudflare.com iburst nts # 启用 NTS 加密(需 TCP 4460 放行)

driftfile /var/lib/chrony/drift # 频率补偿文件
makestep 1.0 3 # 前 3 次更新中偏差>1s 则 step,之后只 slew
rtcsync # 内核周期性同步 RTC
logdir /var/log/chrony

# 作为内网时间服务器对外提供服务
allow 10.0.0.0/8
allow 192.168.0.0/16
local stratum 10 # 上游全断时仍以 stratum 10 对内服务
# deny all # 纯客户端时明确拒绝

# 安全与限速
port 123
cmdport 0 # 关闭 chronyc 远程控制端口(323)
ratelimit interval 3 burst 8 # 服务端限速,防放大攻击

改完重启并验证:

1
2
sudo systemctl restart chronyd
chronyc sources -v && chronyc tracking

2.3 ntpd(传统 ntp.org 实现)

这组命令能干什么:启停 ntpd、看时间源(ntpq -p)、读系统变量、单次校时。注意 ntpd 需手工 disable monitor 才安全。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
sudo systemctl status ntpd # 或 ntp
ntpq -p # 时间源列表(经典命令)
ntpq -pn # 不反解 DNS
ntpq -c rv # 读系统变量(含 offset/jitter/leap)
ntpq -c "rv 0 offset,frequency,sys_jitter"
ntpq -c peers -c associations
ntpstat # 简明状态:synchronised/unsynchronised
ntpdate -q pool.ntp.org # 只查询不设置(安全)
sudo ntpdate -u pool.ntp.org # 强制设置(需先停 ntpd,端口冲突)
sudo ntpd -gq # 单次校时后退出(-g 允许大偏差)

ntpq -p 输出符号(与 chrony 类似):

1
2
3
4
5
6
     remote refid st t when poll reach delay offset jitter
==============================================================================
*203.107.6.88 10.137.38.86 2 u 45 64 377 8.123 -0.456 0.234
+120.25.115.20 10.137.53.7 2 u 38 64 377 12.456 1.234 0.567
-time.windows.com 13.86.101.172 3 u 51 64 377 45.678 -5.678 2.345
 10.0.0.99 .INIT. 16 u - 64 0 0.000 0.000 0.000
首列符号含义
*system peer,当前同步源
+候选源(通过选择算法)
-被聚类剔除
xfalseticker
#良好但因源过多未被选中
oPPS 同步的 peer
(空格)被丢弃(不可达、stratum 过高、环路)

/etc/ntp.conf 安全基线:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
driftfile /var/lib/ntp/ntp.drift

server ntp.aliyun.com iburst
server ntp.ntsc.ac.cn iburst

# 默认全禁,逐项放开(关键的反放大配置)
restrict default kod nomodify notrap nopeer noquery limited
restrict -6 default kod nomodify notrap nopeer noquery
restrict 127.0.0.1
restrict ::1
restrict 10.0.0.0 mask 255.0.0.0 nomodify notrap nopeer # 允许内网同步

disable monitor # 关闭 monlist,消除 556 倍反射放大风险

2.4 Windows 时间服务(w32time)

这组命令能干什么:查看/配置 Windows 的 w32time 同步状态与源,强制重同步,查域控 PDC(域内权威时间源),设时区。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
w32tm /query /status # 当前同步状态(Stratum/上次同步/源)
w32tm /query /source # 当前时间源
w32tm /query /peers # 所有配置的对等体
w32tm /query /configuration # 完整配置
w32tm /stripchart /computer:ntp.aliyun.com /samples:5 /dataonly # 逐次显示偏移(好用)
w32tm /monitor # 域环境:监控各 DC 时间

# 配置外部 NTP 源
w32tm /config /manualpeerlist:"ntp.aliyun.com,0x8 ntp.ntsc.ac.cn,0x8" /syncfromflags:manual /reliable:yes /update
net stop w32time && net start w32time
w32tm /resync /force # 立即强制同步

# 域环境查看 PDC 模拟器(域内权威时间源)
netdom query fsmo
w32tm /query /status /verbose

# 时区
tzutil /g # 查看当前时区
tzutil /s "China Standard Time" # 设置
Get-Date; Get-TimeZone

Hyper-V/VMware 虚拟机注意:来宾集成服务的"时间同步"会与 NTP 抢控制权,域控/时间服务器上应关闭虚拟化时间同步

2.5 快速手工校时(应急,不推荐长期使用)

这组命令能干什么:在没配常驻服务时,做一次性的临时对时(会跳变,仅应急)。

1
2
3
4
sudo chronyd -q 'server ntp.aliyun.com iburst' # chrony 单次校时后退出
sudo ntpdate -u ntp.aliyun.com # 传统方式(会跳变)
sudo sntp -sS ntp.aliyun.com # macOS / 部分 Linux
sudo date -s "$(curl -sI https://www.baidu.com | grep -i '^date:' | cut -d' ' -f2-)" # 无 NTP 时的兜底

3. 常见故障与排错

3.1 时间不同步(timedatectl 显示 System clock synchronized: no

先记住结论:九成落在这三处——多个时间服务互相打架、UDP 123 出不去/回不来被防火墙挡了、或 NTP 域名解析不了。按"服务冲突 → 端口 → 防火墙 → 源可达 → DNS"顺序查最快。

排查顺序:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
# ① 有没有同步服务在跑?多个服务冲突是最常见原因
systemctl status chronyd systemd-timesyncd ntpd 2>/dev/null | grep -E 'Active|●'
# 只能留一个!例如用 chrony 就要关掉另两个
sudo systemctl disable --now systemd-timesyncd ntp ntpd

# ② UDP 123 通不通
sudo ss -ulnp | grep :123
nc -zvu ntp.aliyun.com 123
sudo tcpdump -i any -nn 'udp port 123' -c 10 # 看有无请求发出、有无响应回来

# ③ 防火墙
sudo iptables -L -n | grep 123
sudo firewall-cmd --add-service=ntp --permanent && sudo firewall-cmd --reload
sudo ufw allow 123/udp

# ④ 源是否可达
chronyc sources -v # Reach 应为 377
chronyc -n sources # 排除 DNS 问题

# ⑤ DNS 能否解析 NTP 域名
dig +short ntp.aliyun.com
现象原因解决
Reach = 0,所有源 ?UDP 123 被防火墙/云安全组阻断放行出方向 UDP 123(很多云默认放行,但等保加固后常被关掉)
Cannot talk to daemonchronyd 未运行systemctl start chronyd
端口被占用ntpd 与 chronyd 同时启动只保留一个
容器内不同步容器共享宿主内核时钟,容器内不应跑 NTP宿主机上同步;容器只挂载 /etc/localtime 校正时区
云主机时间跳变云厂商 hypervisor 时间同步 + NTP 冲突用云内网 NTP(如阿里云 ntp.cloud.aliyuncs.com169.254.169.123

3.2 offset 抖动大 / jitter 高

先记住结论:offset 忽大忽小,根因多半是网络抖、路径不对称、源太少或抹平/非抹平源混用——不是 NTP 算错了,而是"输入的样本本身就脏”。

原因判断处理
网络拥塞或链路抖动chronyc sourcestats 中 Std Dev 大;ping RTT 波动大换就近服务器;用内网时间服务器分发
路径不对称offset 存在稳定的固定偏差换对称路径;或本地部署 GPS 时钟源
服务器负载高服务端 t3-t2换服务器
虚拟机 CPU stealvmstatst减少超卖;启用 kvm-clock / hyperv-tsc
源太少只配 1~2 个源配 4 个以上不同机构的源
混用抹平与非抹平源一部分源被标记 x(falseticker)抹平源(Google/AWS)与标准源不可混用

3.3 出现 falseticker(x 标记)

先记住结论x 标记=该源被算法判定"和大多数源矛盾、在说谎"。先确认它是不是 leap smear 源混用、或路径严重不对称,再决定移除。

1
2
chronyc sources -v | grep '^\^x'
chronyc ntpdata <该源IP> # 看其 stratum / root dispersion / refid

原因:该源确实时间不对;或它是 leap smear 源而其他不是;或路径严重不对称。处理:移除该源,或统一全部源的抹平策略。

3.4 时间跳变导致应用异常

先记住结论:数据库报"时间倒退"、定时任务重复/漏跑、Java currentTimeMillis() 回退——这些几乎都是一次性大幅 step 跳变惹的祸;治本是"运行时只 slew,启动才允许一次 step",应用侧改用单调时钟。

症状:数据库报"时间倒退"、定时任务重复或漏跑、日志时间乱序、Java 应用 System.currentTimeMillis() 回退。

根因:一次性大幅 step 调整。

处理

1
2
3
# chrony:仅允许启动阶段 step,运行中只 slew
makestep 1.0 3
maxslewrate 1000 # 提高 slew 速率,加快追赶(默认 83333 ppm 上限受内核限制)
1
2
3
4
# 应用侧:使用单调时钟而非墙上时钟
# C: clock_gettime(CLOCK_MONOTONIC, &ts)
# Java: System.nanoTime()(而非 currentTimeMillis)
# Go: time.Since(start) 内部用单调时钟

3.5 Kerberos / AD 认证失败(KRB_AP_ERR_SKEW

先记住结论:域登录、RDP、kinit 报"clock skew",根因就是客户端与 KDC 时间偏差 > 5 分钟——先 chronyc tracking 看 System time 偏多少,再对齐到 DC/PDC 的时间。

症状:域账号登录失败、RDP 报认证错误、kinit 提示 “Clock skew too great”。

原因:客户端与 KDC 时间偏差 > 5 分钟(默认 clockskew)。

1
2
3
4
5
# Linux 侧检查
chronyc tracking | grep 'System time'
kinit alice@EXAMPLE.COM # 观察是否报 skew
# 与 KDC 直接比时间
ntpdate -q <kdc-ip>
1
2
3
# Windows 侧
w32tm /monitor # 域内各 DC 时间差
w32tm /stripchart /computer:dc01 /samples:5 /dataonly

正确的 AD 时间架构PDC 模拟器 → 外部 Stratum 1/2 → 其他 DC 同步 PDC → 成员服务器与客户端同步各自 DC。虚拟化的 DC 必须关闭 hypervisor 时间同步。

3.6 chronyc sources 全是 ? 但 tcpdump 有响应包

先记住结论:能抓到包却显示 ?,说明响应包"内容不合格"——服务端自己没同步(stratum 16 / LI=3)、被限速(KoD)、或 Origin 不匹配被当成伪造包丢弃。

  • 检查响应包的 Stratum:若为 16 或 LI=3,说明服务端自己没同步,chrony 会拒绝使用。
  • 检查是否为 KoD:ntp.stratum == 0 且 refid 为 RATE/DENY → 被限速或拒绝,换服务器或调大 poll。
  • 检查 Origin Timestamp 是否匹配:不匹配说明响应被 NAT/中间设备改写或是伪造包。

3.7 服务器被当作 NTP 反射放大源

先记住结论:出方向 UDP 123 突然暴涨打向陌生 IP,基本就是你的 ntpd 暴露了 monlist 被当成放大跳板——立刻 disable monitor + restrict ... noquery,或换 chrony。

发现:出方向 UDP 123 流量暴涨,目标为陌生 IP。

1
2
sudo tcpdump -i any -nn 'udp port 123 and greater 200' -c 50 # 大响应包
ntpq -c "rv 0 stratum" ; ntpdc -c monlist localhost # 有输出即危险

修复

1
2
3
# ntpd
disable monitor
restrict default kod nomodify notrap nopeer noquery limited
1
2
3
4
5
# chrony(更安全,天然无 mode 7)
deny all
allow 10.0.0.0/8
ratelimit interval 3 burst 8
cmdport 0

云安全组:仅放行必要来源的 UDP 123 入方向。

3.8 排错思路总览

先记住结论:时间不对的排查是一条"由粗到细"的链——先看服务在不在、是不是多个服务打架,再看源是否可达(Reach 377),最后看偏差/抖动/时区。时刻记住"时区错 ≠ 时间错"。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
时间不对?
├─ timedatectl → NTP service 是否 active、synchronized 是否 yes
├─ 是否多个时间服务并存(chronyd / timesyncd / ntpd)→ 只留一个
├─ chronyc sources → Reach 是否 377
│ ├─ Reach=0 → UDP123 不通(防火墙/安全组/DNS)
│ ├─ 全是 ? → 源 stratum=16 或 KoD 限速
│ └─ 出现 x → falseticker,检查抹平混用/路径不对称
├─ chronyc tracking → System time 偏差、Frequency ppm 是否异常
├─ 偏差大但不收敛 → makestep / chronyc makestep
├─ 时区显示错但 UTC 对 → timedatectl set-timezone(不是 NTP 问题)
└─ 容器/虚机 → 到宿主机层面解决

重要区分时区错(显示差 8 小时)与时间错(UTC 本身不准)是两个完全不同的问题。前者用 timedatectl set-timezone,与 NTP 无关。

4. 与其他协议对比

维度NTPSNTPchronyPTP (IEEE 1588)systemd-timesyncd
性质协议 + 参考实现 ntpdNTP 的简化子集NTP 的另一实现独立协议SNTP 客户端实现
规范RFC 5905RFC 4330(已归并)实现 RFC 5905IEEE 1588-2019实现 SNTP
端口UDP 123UDP 123UDP 123UDP 319(事件)/ 320(通用)UDP 123
精度LAN 0.11 ms,WAN 150 ms较低(无滤波)同 NTP,收敛更快亚微秒~纳秒毫秒级
时间戳位置软件(用户态/内核)软件软件(支持硬件时戳)硬件(网卡 PHY)软件
多源统计有(选择/聚类/合并)有,算法更优有(BMCA 最佳主时钟算法)(单源)
网络要求普通 IP 网普通 IP 网普通 IP 网需支持边界/透明时钟的交换机普通 IP 网
断网/间歇连接一般优秀(专为笔记本/虚机设计)一般一般
可作服务端是(Master)
资源占用极低极低
典型场景传统服务器、大规模授时嵌入式、IoT现代 Linux 默认金融交易、5G、工业控制、电力桌面/轻量容器宿主

选型建议

  • 普通服务器 / 云主机 → chrony(RHEL 8+、Ubuntu 20.04+ 默认,收敛快、断网友好、无 mode 7 风险)。
  • 需要作为大规模内网授时服务器且已有成熟 ntpd 运维体系 → ntpd(注意 disable monitor)。
  • 桌面/极简容器宿主 → systemd-timesyncd 足够。
  • 微秒级以下需求(高频交易、5G 前传、变电站) → PTPlinuxptpptp4l + phc2sys),并配 GPS/北斗 grandmaster。
  • 混合方案:PTP 做机房内高精度分发,NTP 做跨机房/公网兜底。

5. 速查表 / 常见面试题

5.1 命令速查

目标chronyntpdsystemdWindows
查看源chronyc sources -vntpq -ptimedatectl show-timesyncw32tm /query /peers
同步状态chronyc trackingntpstat / ntpq -c rvtimedatectl statusw32tm /query /status
立即校时chronyc makestepntpd -gqsystemctl restart systemd-timesyncdw32tm /resync /force
只查询不改chronyd -Q 'server X'ntpdate -q Xw32tm /stripchart /computer:X
统计chronyc sourcestatsntpq -c rvw32tm /monitor
配置文件/etc/chrony.conf/etc/ntp.conf/etc/systemd/timesyncd.conf注册表 / w32tm /config
drift 文件/var/lib/chrony/drift/var/lib/ntp/ntp.drift

5.2 关键数值速查

项目
端口UDP 123(NTS-KE 为 TCP 4460
报文长度48 字节(不含扩展与 MAC)
时间戳纪元1900-01-01 00:00:00 UTC
Unix 换算Unix = NTP - 2208988800
时间戳分辨率2⁻³² s ≈ 233 皮秒
Era 溢出2036-02-07 06:28:16 UTC
Stratum 范围0(参考钟)~ 15,16 = 未同步
默认 poll64 ~ 1024 秒(log₂ 值 6~10)
ntpd step 阈值128 ms(超过则 step,>1000 s 触发 panic)
chrony makestepmakestep 1.0 3 = 前 3 次超 1 s 则 step
Kerberos 容忍偏差5 分钟
推荐源数量≥ 4 个(可靠剔除 1 个 falseticker)
monlist 放大倍数556 倍(CVE-2013-5211)
公网常用源ntp.aliyun.comntp.ntsc.ac.cn(国家授时中心)、cn.pool.ntp.orgtime.cloudflare.com(支持 NTS)

5.3 高频面试题

Q1:NTP 如何计算时钟偏移和往返时延?关键假设是什么? A:用四个时间戳 t1(客户端发送)、t2(服务端接收)、t3(服务端发送)、t4(客户端接收): offset = ((t2-t1) + (t3-t4)) / 2delay = (t4-t1) - (t3-t2)关键假设是网络往返路径对称(去程与回程延迟相等)。路径不对称会引入约为"不对称量一半"的系统性偏差,这是 NTP 精度的主要限制。

Q2:Stratum 是什么?Stratum 越小越准吗? A:Stratum 表示距离参考时钟的层级:0 是参考钟本体(GPS/原子钟),1 是直连它的主服务器,逐级递增,16 表示未同步。不是越小越准——一个 RTT 300 ms 的远程 Stratum 1 精度可能远不如同机房 RTT 0.2 ms 的 Stratum 3。选源需综合 stratum、delay、dispersion、jitter。

Q3:为什么建议至少配置 4 个 NTP 源? A:NTP 用交集算法剔除 falseticker。1 个源无法判断真伪;2 个源分歧时无法裁决;3 个源能识别 1 个错误源但幸存者仅剩 2 个;4 个及以上才能在剔除 1 个错误源后仍有 3 个源做可靠的聚类与合并。

Q4:slew 和 step 的区别?为什么默认优先 slew? A:slew 通过调整时钟频率(最大约 500 ppm)让时间缓慢逼近正确值,保证时间单调不倒退step 直接跳变系统时间,可能造成时间倒退。倒退会破坏数据库事务顺序、定时器、日志时序、分布式租约。因此默认只在启动时允许一次 step,运行中只 slew。

Q5:NTP 用 UDP 而不用 TCP,为什么? A:① 时间同步对延迟确定性要求高,TCP 的重传、拥塞控制、Nagle 算法会引入不可预测的排队延迟,破坏时间戳准确性;② 单次交换即可完成,无需连接状态;③ 开销小,服务端可支撑海量客户端;④ 丢包不影响正确性——下次 poll 重来即可,反而比重传的"过期数据"更好。

Q6:什么是 NTP 反射放大攻击?如何防护? A:攻击者伪造受害者源 IP,向开放的 ntpd 发送 mode 7 的 monlist 请求(234 字节),服务端返回最近 600 个客户端记录(约 48 KB),放大约 556 倍(CVE-2013-5211),洪水般打向受害者。防护:升级 ntpd ≥ 4.2.7p26;配置 disable monitorrestrict default ... noquery limited;改用 chrony(不实现 mode 7);边界做 UDP 123 出入向限速与源地址校验(BCP 38)。

Q7:chrony 相比 ntpd 的优势? A:① 收敛快(iburst + 更激进的算法,秒级完成初始同步,ntpd 需数分钟);② 断续网络友好(笔记本休眠、虚机迁移后能快速恢复,专门设计了频率补偿);③ 不实现 mode 7,天生免疫 monlist 放大;④ 能在没有网络时靠 RTC 与 drift 保持较好精度;⑤ 支持硬件时间戳与 NTS;⑥ 资源占用更低。现已是 RHEL 8+/Ubuntu 20.04+ 的默认实现。

Q8:闰秒是什么?现代如何处理? A:为对齐 UTC 与地球自转,在 6/30 或 12/31 末尾插入一秒(23:59:60)。NTP 用报文的 LI 字段提前预告。历史上曾引发大规模故障(2012 年 Linux hrtimer 死锁)。现代主流方案是 leap smear(闰秒抹平):把这 1 秒分散到前后 12~24 小时内逐步微调,客户端无感。抹平源与非抹平源不能混用,否则互判 falseticker。CGPM 已决议最晚 2035 年前取消闰秒。

Q9:NTP 的时间戳纪元是哪一年?如何转成 Unix 时间戳? A:1900-01-01 00:00:00 UTC(不是 Unix 的 1970)。64 位时间戳高 32 位为秒、低 32 位为小数(分辨率约 233 ps)。换算:Unix = NTP_seconds - 2208988800。32 位秒数将在 2036-02-07 溢出,NTPv4 用 Era 概念处理。

Q10:容器里的时间怎么同步? A:容器不应该自己跑 NTP。容器与宿主机共享内核时钟(除非用了特殊的 time namespace),容器内改时间要么无效要么会影响宿主。正确做法:在宿主机上运行 chrony 保证时间准确;容器内只需正确挂载时区(-v /etc/localtime:/etc/localtime:ro 或设 TZ 环境变量)。Kubernetes 场景同理,在 Node 层面统一同步。

Q11:NTP 和 PTP 怎么选? A:NTP 是软件时间戳、普通 IP 网即可、精度毫秒级、部署简单,适合绝大多数 IT 场景;PTP(IEEE 1588)用硬件时间戳并需要支持边界时钟/透明时钟的交换机,精度可达亚微秒甚至纳秒,适合高频交易、5G 前传、电力自动化、工业控制。成本与精度成正比,按需选择;常见做法是 PTP 做机房内高精度分发、NTP 做跨域兜底。

Q12:如何确认一台机器的时间是准的? A:chronyc trackingSystem time ... slow/fast of NTP time(应在毫秒级以内)、Leap status: Normalchronyc sources -v 确认有 * 标记的选中源且 Reach=377;timedatectl 显示 System clock synchronized: yes;再用 w32tm /stripchartntpdate -q 与独立第三方源交叉验证。