应先用 nmap -p 123,323 -sU 扫描存活且开放 NTP/Chrony 端口的主机,再用 timeout 包裹 ntpdate -q 或 chronyc tracking 并发检测偏移,最后按超时、拒绝连接、偏移超标三类分类统计。

用 nmap 快速发现存活主机再逐台测时间同步状态
直接对整个网段暴力跑 ntpdate -q 或 chronyc tracking 不现实——多数主机没开 NTP 服务,更可能根本没响应。得先筛出「活着且开放了时间相关端口」的机器。nmap -sn 只能 ping 扫活主机,但内网常禁 ICMP;更稳的是用 nmap -p 123,323 -sU 扫 UDP 的 NTP 端口(123)和 Chrony 端口(323),配合 -oG - 输出可解析格式。
- 实际命令示例:
nmap -p 123,323 -sU -T4 --min-parallelism 50 192.168.1.0/24 -oG - | awk '/open/ {print $2}' | sort -u -
-sU是关键:NTP/Chrony 默认走 UDP,TCP 扫不到 - 别漏
--min-parallelism,否则默认并发太低,/24 网段要扫十几分钟 - 输出里可能混入
host down行,awk '/open/'能过滤掉
用 ntpdate -q 测时钟偏移但必须加超时和错误捕获
ntpdate -q 是最轻量的检测方式,不改本地时间,只返回偏移值。但它在目标不可达、防火墙拦截、或 NTP 服务未运行时会卡住默认 30 秒——脚本会因此阻塞。必须用 timeout 包裹,并检查退出码和 stderr。
- 单机测试写法:
timeout 3 ntpdate -q 192.168.1.100 2>/dev/null | grep 'offset' | awk '{print $NF}' - 退出码为 124 表示超时,0 表示成功获取 offset,1/2 表示拒绝连接或协议错误
- 注意:
ntpdate在较新系统(如 Ubuntu 22.04+)默认被移除,需装ntp包;若用 Chrony,则换chronyc -h 192.168.1.100 tracking 2>/dev/null | grep 'System time' - 偏移单位是秒,输出类似
+0.002123,建议用bc或awk提取绝对值后判断是否 >1.0
Shell 脚本里避免 for 循环串行拖慢速度,改用 parallel
对上百台主机挨个 timeout + ntpdate 是最常见性能陷阱。纯 Bash 的 for 循环本质是串行,哪怕加 & 后台也难控并发数和错误回收。用 parallel 更可靠:
- 先生成主机列表文件
hosts.txt(每行一个 IP) - 执行:
cat hosts.txt | parallel -j 20 'echo {} $(timeout 3 ntpdate -q {} 2>/dev/null | grep offset | awk "{print \$NF}" || echo "timeout")' -
-j 20控制并发数,太高易触发防火墙限速,建议从 10 起调 -
parallel自动等所有任务结束,stdout 按输入顺序输出,方便后续awk统计 - 没装
parallel?用apt install parallel(Debian/Ubuntu)或yum install parallel(RHEL/CentOS)
结果里区分「无响应」「拒绝连接」「偏移超标」三类问题
单纯打印「offset: +0.002」没意义。自动化测试的价值在于分类告警。真实环境里,这三类返回需不同处理:
-
timeout:可能是主机关机、防火墙丢 UDP 包、或中间网络设备过滤 —— 需单独归为「不可达」组 -
no server suitable或Connection refused:说明主机在线,但 NTP 服务未启动或监听地址不对(比如只 bind 127.0.0.1) - 偏移值绝对值 >1.0 秒:时间已不同步,但服务本身正常 —— 这才是真正的「时钟偏差」问题
- 建议脚本末尾用
awk统计:awk '$2 ~ /timeout/ {t++} $2 ~ /refused|suitable/ {r++} $2+0 > 1.0 || $2+0 1s:",o}'
真正麻烦的是那些 UDP 包能通但 NTP 响应异常的边界情况——比如某些嵌入式设备只实现 SNTP 子集,ntpdate 会静默失败。这种得切到 ntpq -c rv 或抓包确认,脚本里很难全覆盖。


















