在Ubuntu服务器上配置chrony时间同步并启用NTS(Network Time Security)加密,核心操作就是安装chrony包、配置NTS密钥、指向支持NTS的时间服务器,然后重启服务验证。具体来说,你需要在/etc/chrony/chrony.conf中添加nts指令,生成或获取NTS密钥文件,将服务器指向类似time.cloudflare.com这类支持NTS的上游源,最后用chronyc sources -v确认NTS握手成功。整个过程不复杂,但细节决定安全性和同步精度,下面我一步步拆开讲。
为什么要用chrony而不是ntpd
Ubuntu 18.04之后默认用的就是chrony,它比传统ntpd更轻量、收敛更快、对间歇性网络连接适应性更好。chrony支持NTS协议,这是目前时间同步领域最前沿的安全机制。NTS通过TLS 1.3加密通道交换密钥,再用AEAD加密实际的时间同步数据包,彻底解决了传统NTP容易被中间人攻击、时间篡改的问题。对于生产环境服务器、数据库集群、金融系统来说,这不是可选项,是必选项。
Ubuntu上安装chrony的基础步骤
先确认系统是否已经安装chrony,Ubuntu 20.04及以上版本通常预装了。如果没有,直接执行:
sudo apt update sudo apt install chrony -y
安装完成后启动并设置开机自启:
sudo systemctl enable chrony sudo systemctl start chrony
用下面的命令快速检查当前同步状态:
chronyc tracking chronyc sources -v
如果看到带有"^*"标记的源,说明已经在正常同步。但这还只是基础配置,没有NTS加密,数据仍然是明文传输的。
NTS加密的核心原理
NTS的工作流程分两个阶段。第一阶段叫NTS-KE(Key Exchange),客户端和服务器通过TLS 1.3建立加密通道,交换临时密钥。第二阶段是实际的NTP数据传输,使用第一阶段协商出来的密钥进行AEAD加密。这样即使网络被监听,攻击者也无法伪造时间包或者篡改时间戳。chrony从3.5版本开始原生支持NTS,Ubuntu 22.04自带的chrony版本已经满足要求。
配置NTS密钥文件
chrony的NTS密钥存储在/etc/chrony/nts.keys文件中。你可以手动生成,也可以从支持NTS的服务器获取。手动生成的方法:
sudo chronyd -Q 'ntskey /etc/chrony/nts.keys'
或者更简单的方式,直接创建一个包含密钥的文件。密钥格式是:
NTS-KEY-1 AQAAAAAAAAD...(很长的base64字符串)
实际生产环境中,推荐使用支持NTS的公共时间服务器提供的密钥。比如Cloudflare的time.cloudflare.com就提供NTS服务,你可以通过以下方式获取其NTS密钥:
curl -s https://time.cloudflare.com/cdn-cgi/trace | grep nts
获取到的密钥对需要放到/etc/chrony/nts.keys中。文件权限要设为600,属主为chrony用户:
sudo chmod 600 /etc/chrony/nts.keys sudo chown chrony:chrony /etc/chrony/nts.keys
修改chrony.conf启用NTS
打开配置文件:
sudo nano /etc/chrony/chrony.conf
在文件中添加或修改以下内容。首先指定NTS密钥文件位置:
ntskeyfile /etc/chrony/nts.keys
然后配置上游服务器,使用nts指令启用加密同步。以Cloudflare为例:
server time.cloudflare.com iburst nts server time1.cloudflare.com iburst nts server time2.cloudflare.com iburst nts server time3.cloudflare.com iburst nts
如果你有自己的NTS服务器,把地址换成自己的就行。iburst参数让chrony启动时快速发起多次请求以加速初始同步。同时建议保留本地时钟作为fallback:
server 127.127.1.0 local stratum 10
完整的配置文件关键部分应该长这样:
# /etc/chrony/chrony.conf 关键片段 ntskeyfile /etc/chrony/nts.keys pool time.cloudflare.com iburst nts driftfile /var/lib/chrony/chrony.drift logdir /var/log/chrony makestep 1.0 3 rtcsync
重启服务并验证NTS是否生效
配置改完后重启chrony:
sudo systemctl restart chrony
然后用chronyc sources -v查看详细信息。如果NTS握手成功,你会看到类似这样的输出:
210 Number of sources = 4 MS Name/IP address Stratum Poll Reach LastRx Last sample =============================================================================== ^* time.cloudflare.com 1 6 377 12 -452us[ -893us] +/- 15ms
注意看,如果NTS生效,chrony的日志里会有明确的NTS握手记录。查看日志:
sudo journalctl -u chrony | grep -i nts
你应该看到类似"NTS key exchange with ... completed"的信息。如果没有看到,检查密钥文件是否正确、服务器是否真的支持NTS、防火墙是否放行了UDP 123端口。
防火墙和网络注意事项
NTS使用UDP 123端口,和普通NTP一样。但NTS-KE阶段需要TCP 4460端口(部分服务器用这个端口做密钥交换)。如果你的服务器在防火墙后面,确保UDP 123出站放行,同时确认TCP 4460是否需要开放。用ufw的话:
sudo ufw allow out 123/udp sudo ufw allow out 4460/tcp
如果是iptables,规则类似。另外注意,NTS不需要额外的端口转发或复杂的网络配置,它就是在标准NTP端口上跑加密,对现有网络架构几乎零侵入。
chrony的其他安全加固建议
光开NTS还不够,生产环境建议做以下加固。第一,限制哪些客户端可以查询你的时间服务器,在chrony.conf中加:
allow 192.168.1.0/24 deny all
第二,启用chrony的速率限制防止被当作DDoS反射源:
clientloglimit 1000
第三,定期检查时间偏移,设置告警。可以写一个简单的cron脚本:
#!/bin/bash
OFFSET=$(chronyc sources | awk '/\*/ {print $5}')
if (( $(echo "$OFFSET > 0.1" | bc -l) )); then
echo "Time offset too large: $OFFSET" | mail -s "NTP Alert" admin@example.com
fi第四,如果服务器长期离线后重启,chrony的makestep指令会在偏移超过1秒时直接跳变修正,避免长时间慢慢漂移。这个在配置里已经有了,确认一下就行。
常见问题排查
如果配置后NTS不生效,按以下顺序排查。第一,确认chrony版本支持NTS:
chronyd -v
需要3.5以上版本。第二,确认nts.keys文件格式正确,没有多余空格或换行。第三,确认上游服务器确实支持NTS,不是所有NTP服务器都开了NTS,目前Cloudflare、Netnod、Google的部分节点支持。第四,查看chrony的详细日志:
sudo chronyd -d -d
用前台调试模式运行,能看到完整的NTS握手过程和错误信息。第五,如果系统时间偏差太大(超过1000秒),chrony可能拒绝同步,先用ntpdate手动校一次:
sudo ntpdate -b time.cloudflare.com
然后再启动chrony。
多服务器集群的时间同步架构
如果你管理多台Ubuntu服务器,建议搭建一个内部NTS时间源。选一台机器作为主时间服务器,配置好chrony + NTS,然后其他机器都指向这台内网服务器。这样既减少外网依赖,又统一管理。内网NTS服务器的chrony.conf配置和上面一样,只是server指向自己或者外部源,其他机器的server指向内网IP即可。注意内网机器之间也要放行UDP 123。
总结
Ubuntu上配置chrony NTS时间同步,本质就是三件事:装好chrony、配好NTS密钥和上游源、验证握手成功。操作门槛不高,但安全收益巨大。在当前网络攻击日益复杂的环境下,明文NTP同步已经是一个不可忽视的风险点。花十分钟配置NTS,换来的是整个基础设施时间层的可信保障,这笔账怎么算都划算。建议所有Ubuntu服务器管理员尽快检查现有配置,没有NTS的赶紧加上。
