一、概述

NTP服务器的阶层概念

网络时间按照NTP服务器的等级进行传播,根据离基准时间的远近将不同服务器归纳到不同的层中(Stratum),单个Stratum层的总数限制在15

0层(Stratum 0):表示高精度设备,例如原子钟、GPS时钟等,0层也称为参考时钟

1层(Stratum 1):这些设备和0层的设备相连,误差仅为微秒

2层(Stratum 2):这些设备和1层的设备通过网络相连

依次类推...,时间是按NTP的层级进行传播的(Peer之间是同层级传播)

NTP服务为C/S架构,NTP客户端请求NTP服务端,通过交互往返的数据包,客户端能够根据这个结果计算出准确的时间,客户端为了保证计算结果的精确度、可靠度,一般建议NTP服务客户端配置最少3个NTP服务器地址

列举部分NTP协议的软件实现

  • ntpdate:运行一次ntpdate命令,进行一次时间同步(该命令不是守护进程设计)
  • ntp:NTP协议的实现,可充当NTP Client、NTP Server(守护进程设计)
  • chrony:一个较新的NTP协议的实现,可充当NTP Client、NTP Server,Chrony相比ntp来说同步时间速度更快,精度更准,也是目前推荐的实现(守护进程设计)

二、ntpdate命令

ntpdate命令是一个客户端NTP程序,该程序并不是守护进程设计,ntpdate软件的绝大部分功能都已在ntpd中有包含,且ntpdate会逐渐进行退役

ntpdate设计用来通过指定的ntp服务器获取时间,并设置本地的时间,ntpdate的准确性、可靠性取决于服务器的数量,轮询查询的次数、间隔(该命令需要root权限执行)

#安装ntpdate
CentOS中执行 yum install ntpdate
Ubuntu中执行 apt install ntpdate

#ntpdate语法如下
ntpdate [ -46bBdqsuv ] [ -a key ] [ -e authdelay] [ -k keyfile ] [ -o version ] [ -p samples ] [ -t timeout ] [ -U user_name] server [ ... ]

#ntpdate命令选项解释如下:(可通过man ntpdate查看)
-4	仅使用IPv4
-6	仅使用IPv6
-a key		启用认证,并指定认证需要的密钥(默认禁用该功能)
-B		强制每次都使用adjtime()系统调用调整时间,即使偏移量+-500ms,默认情况下+-500ms使用settimeofday(),该情况下同步时间可能会超过1-2小时
-b		强制使用settimeofday()系统调用调整时间,而不是使用adjtime()调用来设置时间,在启动脚本中调用可以使用此选项

-d		启用调试模式,ntpdate将会完成所有动作,但是不修改本地时间,打印的输出信息可能会对调试很有帮助

-e authdelay		指定身份验证功能的处理延迟为authdelay,以秒和分为单位,给数字通常足够小,对于大多数用途来说可以忽略不记
-k keyfile		指定身份验证的密钥路径,默认为/etc/ntp/keys,该文件应该采用ntpd中所描述的格式

-o version		指定传出数据包的ntpd整数形式的版本号,可以为1、2,默认为4,该选项允许与较旧的NTP版本一起使用
-p samples		指定从每个服务器获取的样本数,可以是1-8,默认为4

-q		仅查询,不设置clock
-s		从标准输出转义日志输出到syslog,这主要是为了方便cron脚本而设计

-t timeout		指定从服务器收到响应的超时时间,可以是秒,分,该值四舍五入为0.2秒的倍数,默认值为1s
-u		ntpdate为传出数据包使用非特权端口,当处于防火墙背后且知名端口被防火墙阻断时很有用,-d选项始终使用非特权端口
-v		显示更多详细信息

-U user_name		ntpdate不使用root权限,并将用户ID更改为user_name,并将GroupID更改为server_user的主要组

ntpdate可以根据需要来手动设置时间,或者设置开机脚本达到每次启动时运行一次,也可以使用cron脚本来周期性运行ntpdate命令(带cron脚本的ntpdate不能替代ntpd,ntpd使用了很多复杂的算法来最大限度提高时间的准确性、可靠性,ntpdate不会约束本地主机的时钟频率,ntpdate的准确性是有限的)

使用ntpdate和NTP服务器同步一次时间
[root@ ~]# ntpdate 172.16.32.254
 6 May 10:54:35 ntpdate[2614]: adjust time server 172.16.32.254 offset 0.031896 sec


将同步好的Linux Kernel时间写入BIOS硬件时钟,以便重启后保持时间准确
hwclock -w


(可选)可以在cron中设置每2个小时运行一次
0 */2 * * * root /usr/sbin/ntpdate 172.16.32.254 > /dev/null 2>&1

若本机上运行了ntpd服务的话,无法再通过ntpdate命令来设置日期

三、ntpd守护进程、服务

使用ntpd守护能够自动调整时间

#安装ntpd守护进程
CentOS系统中执行    yum install ntp
Ubuntu系统中执行    apt install ntp

安装完成之后,该服务可用systemd进行管理

#在CentOS中ntp服务的服务名和Ubuntu中有点不一样
#CentOS中该service文件为
/usr/lib/systemd/system/ntpd.service

#Ubuntu中该service文件为
/lib/systemd/system/ntp.service

#当使用systemd进行管理的时候,注意名称区别(CentOS中服务名带d,Ubuntu中不带)
systemctl enable ntpd.service
systemctl enable ntp.service

systemctl start ntpd.service
systemctl start ntp.service

3.1 ntpd配置文件

ntpd的服务配置文件路径为/etc/ntp.conf,该文件的默认配置如下:

#为了方便查看,这里把配置文件中一些注释行删除

driftfile /var/lib/ntp/drift
restrict default nomodify notrap nopeer noquery

restrict 127.0.0.1 
restrict ::1

# Hosts on local network are less restricted.
#restrict 192.168.1.0 mask 255.255.255.0 nomodify notrap

#默认配置中配置了4个server字段,已指定了4台NTP服务器的地址
server 0.centos.pool.ntp.org iburst
server 1.centos.pool.ntp.org iburst
server 2.centos.pool.ntp.org iburst
server 3.centos.pool.ntp.org iburst

includefile /etc/ntp/crypto/pw
keys /etc/ntp/keys
disable monitor

该默认配置已经将ntp设置为客户端模式,自动向server字段中配置的服务器进行时间同步

配置文件中的restrict字段的解释:指定可以和本机NTP服务通信的IP地址或网段,如果没有指定任何选项,那么表示客户端在访问本机提供的NTP服务器没有任何限制

restrict <ipaddr> <netmask> [ignore | nomodiy | noquery | notrap | notrust | nokod ]

  • ignore:关闭所有的NTP服务
  • nomodiy:表示客户端不能更改NTP服务器的时间参数,但可以通过NTP服务器校对时间
  • noquery:不提供NTP服务,
  • notrap:不提供trap远程事件登陆(Remote Event Logging)的功能,拒绝任何被发送的控制包
  • notrust:拒绝没有通过认证的客户端
  • kod:kod技术可以阻止kiss of death包(一种DOS攻击)对服务器的破坏,kod用来发送特定的回应包,以减慢那些超过规定速度界限的客户机
  • nopeer:不和其他同一层的NTP服务器进行时间同步

server字段中的iburst表示发送到服务器的前4个请求之间的间隔将为2s或者更短,表示在初次同步时能进行快速同步时间

3.2 ntpd作为客户端运行,自定义ntpd上层NTP服务器

假设需要自定义本机的上层NTP server,直接修改默认的服务器即可,例如这里配置阿里云公共NTP服务器阿里云NTP服务器 (aliyun.com)

#为了方便查看,这里把配置文件中一些注释行删除

driftfile /var/lib/ntp/drift
restrict default nomodify notrap nopeer noquery

restrict 127.0.0.1 
restrict ::1

# Hosts on local network are less restricted.
#restrict 192.168.1.0 mask 255.255.255.0 nomodify notrap

#指定server为阿里云公开NTP服务器(这里的server可以是ip地址、域名)
server ntp.aliyun.com iburst
server ntp1.aliyun.com iburst
server ntp2.aliyun.com iburst
server ntp3.aliyun.com iburst

includefile /etc/ntp/crypto/pw
keys /etc/ntp/keys
disable monitor

修改配置文件后,执行service ntpd restart重启ntp服务即可(注意在Ubuntu中服务名称不带d,ntp)

可以通过ntpstat命令查看本机上一次和NTP服务器时间同步的情况

[root@localhost ~]# ntpstat 
synchronised to NTP server (120.25.115.20) at stratum 3	//进行校对的NTPserver
   time correct to within 956 ms		//本地主机和上层NTP时间差
   polling server every 64 s		//下次同步时间

也可以使用ntpd -p命令查看本机和上层NTP服务器通信的情况

[root@localhost ~]# ntpq -p
     remote           refid      st t when poll reach   delay   offset  jitter
======================================================================
*120.25.115.20   10.137.53.7      2 u   29   64    3   23.546    6.034   1.098
+203.107.6.88    10.137.38.86     2 u   30   64    3   29.517    6.789   0.334


#一些字段解释
remote:本地主机所连接的上层服务器
refid:上层NTP服务器的NTP服务器
st:上层NTP服务器层级
when:上一次与上层NTP服务器进行时间校对的时间

3.3 ntpd运行为客户端,向上层NTP服务同步时间;且同时ntpd运行为服务端,为本地子网中的客户端提供NTP时间同步服务

配置本机NTP服务向本地子网提供NTP授时服务,取消注释配置文件中的restrict字段,并修改该子网,可以配置多个,配置完成后,重启ntpd服务service ntpd restart,该配置实现了本机从指定的上层NTP服务器(例如这里本机上层NTP服务器配置的是阿里云公共NTP服务器)获取时间,并向本地子网提供时间同步服务

#为了方便查看,这里把配置文件中一些注释行删除

driftfile /var/lib/ntp/drift
restrict default nomodify notrap nopeer noquery

restrict 127.0.0.1 
restrict ::1

#允许向特定的本地子网提供NTP服务
restrict 192.168.0.0 mask 255.255.0.0 nomodify notrap
restrict 172.16.0.0 mask 255.240.0.0 nomodify notrap
restrict 10.0.0.0 mask 255.0.0.0 nomodify notrap

#指定server为阿里云公开NTP服务器(这里的server可以是ip地址、域名)
server ntp.aliyun.com iburst
server ntp1.aliyun.com iburst
server ntp2.aliyun.com iburst
server ntp3.aliyun.com iburst

includefile /etc/ntp/crypto/pw
keys /etc/ntp/keys
disable monitor

整体来说,一般情况下,配置文件的修改较为简洁,大体分为2个部分:上层NTP服务器配置,本地子网授权配置

四、Chronyd守护进程、服务

Chrony是NTP比较新的实现,chrony相比ntp有着较高的时间同步效率、准确度,推荐使用chrony

#安装chrony
CentOS中执行    yum install chrony
Ubuntu中执行    apt-get install chrony

#安装完成后可以用systemd管理,但是他们之间的服务名称有差别
#在CentOS中service文件为
/usr/lib/systemd/system/chronyd.service

#在Ubuntu中service文件为
/lib/systemd/system/chrony.service


#管理chrony服务(以CentOS为例)
systemctl enable chronyd.service
systemctl start chronyd

4.1 chronyd配置文件

chronyd的配置文件路径为/etc/chrony.conf,该文件的默认配置如下:

#为了方便查看,这里删除一些注释行

#默认配置中pool指令已指定了一台上层NTP服务器
pool 2.centos.pool.ntp.org iburst

driftfile /var/lib/chrony/drift
makestep 1.0 3
rtcsync

# Allow NTP client access from local network.
#allow 192.168.0.0/16

# Serve time even if not synchronized to a time source.
#local stratum 10

keyfile /etc/chrony.keys
leapsectz right/UTC
logdir /var/log/chrony

该默认配置文件中的pool指令已经指定了一个上层NTP服务器,不做任何修改的话,chrony服务能够作为NTP客户端向上层NTP服务器进行时间同步

4.2 Chronyd作为NTP客户端,并指定上层NTP服务器

这里我们指定阿里云NTP服务器 (aliyun.com)作为我们服务器的上层NTP服务器,注释掉默认配置文件中的pool指令部分,使用server指令指定上层阿里云NTP服务器,配置如下:(这里的server指令后面可以跟上域名、IP地址)

#为了方便查看,这里删除一些注释行

#默认配置中pool指令已指定了一台上层NTP服务器
#pool 2.centos.pool.ntp.org iburst

#指定上层NTP服务器为阿里云NTP服务器
server ntp.aliyun.com iburst
server ntp1.aliyun.com iburst
server ntp2.aliyun.com iburst

#(可选配置)本机向上层NTP服务器请求数据时,可进行限制的一些配置
#acquisitionport 1123     固定本机请求的源端口(对于穿越防火墙时,有利于防火墙统一配置策略)
#bindacqaddress 192.168.1.1    固定本机请求数据包使用的源IP地址
#bindacqdevice eth0       固定本机请求数据包的源网络接口

driftfile /var/lib/chrony/drift
makestep 1.0 3
rtcsync

# Allow NTP client access from local network.
#allow 192.168.0.0/16

# Serve time even if not synchronized to a time source.
#local stratum 10

keyfile /etc/chrony.keys
leapsectz right/UTC
logdir /var/log/chrony

4.3 Chronyd作为客户端运行,和上层NTP同步时间;且Chronyd作为服务端运行,向本地子网提供NTP服务

Chronyd在和上层NTP进行同步时间同时,Chronyd作为服务端向本地子网提供NTP时间同步服务,需要在配置文件中配置allow指令,通过allow指令可以允许特定的本地子网向本机进行NTP时间同步,在allow范围之外的主机、子网将无法和本机进行NTP时间同步

#为了方便查看,这里删除一些注释行

#默认配置中pool指令已指定了一台上层NTP服务器
#pool 2.centos.pool.ntp.org iburst

#指定上层NTP服务器为阿里云NTP服务器
server ntp.aliyun.com iburst
server ntp1.aliyun.com iburst
server ntp2.aliyun.com iburst

#(可选配置)本机向上层NTP服务器请求数据时,可进行限制的一些配置
#acquisitionport 1123     固定本机请求的源端口(对于穿越防火墙时,有利于防火墙统一配置策略)
#bindacqaddress 192.168.1.1    固定本机请求数据包使用的源IP地址
#bindacqdevice eth0       固定本机请求数据包的源网络接口

driftfile /var/lib/chrony/drift
makestep 1.0 3
rtcsync

#允许特定的本地子网向本机进行NTP时间同步
allow 192.168.0.0/16
allow 172.16.0.0/12
allow 10.0.0.0/8
allow all        //允许所有
allow 0/0        //允许所有IPv4

#(可选配置)定义本机chronyd服务监听的IP、端口、网卡
#bindaddress 192.168.1.1
#binddevice eth0
#port 123


# Serve time even if not synchronized to a time source.
#local stratum 10

keyfile /etc/chrony.keys
leapsectz right/UTC
logdir /var/log/chrony

特定时候,为了安全等因素考虑,可以通过port命令修改chronyd提供的NTP服务监听的端口,通过binddevice命令限制chronyd监听的网卡,若本机上有多个IP地址,可以通过bindaddress命令绑定本机监听的IP地址

4.4 在隔离的网络中,使用chronyd作为NTP服务端,为本地子网同步时间

某些时刻,在一个隔离的网络中(无互联网连接),需要本地子网中的所有主机时间一致(准不准不重要),这里通过local命令,配置即使本机上的chronyd上层NTP服务器不可达的情况下,仍然将本机的时间同步给本地子网中的客户端,配置如下:

#为了方便查看,这里删除一些注释行

#默认配置中pool指令已指定了一台上层NTP服务器
#pool 2.centos.pool.ntp.org iburst

#指定上层NTP服务器为阿里云NTP服务器
server ntp.aliyun.com iburst
server ntp1.aliyun.com iburst
server ntp2.aliyun.com iburst

#(可选配置)本机向上层NTP服务器请求数据时,可进行限制的一些配置
#acquisitionport 1123     固定本机请求的源端口(对于穿越防火墙时,有利于防火墙统一配置策略)
#bindacqaddress 192.168.1.1    固定本机请求数据包使用的源IP地址
#bindacqdevice eth0       固定本机请求数据包的源网络接口

driftfile /var/lib/chrony/drift
makestep 1.0 3
rtcsync

#允许特定的本地子网向本机进行NTP时间同步
allow 192.168.0.0/16
allow 172.16.0.0/12
allow 10.0.0.0/8
allow all        //允许所有
allow 0/0        //允许所有IPv4

#(可选配置)定义本机chronyd服务监听的IP、端口、网卡
#bindaddress 192.168.1.1
#binddevice eth0
#port 123


#无论自己时间对不对都将自己的时间同步给本地子网中的客户端(可用于隔离的网络中)
local
#指定本地的NTP层级,用于报给给客户端
local stratum 8

keyfile /etc/chrony.keys
leapsectz right/UTC
logdir /var/log/chrony

上面配置中通过local、local stratum 8指令指定了隔离网络中依然向本地子网提供NTP服务,并把本机的时间同步给客户端,并向客户端报告本机的NTP层级为8(该层级你可以手动进行指定,这里我配置为8)

修改配置后,记得重启chronyd服务

上面配置文件中存在2种情况:

  • 同时存在local字段配置和server字段配置:这种情况下,当本机的上层NTP服务器可达时,本机通过chrony运行为客户端模式上上层NTP服务器同步时间,且同时运行为服务端模式,向本地子网提供NTP服务;该情况下,配置中的local指令会被忽略,本地子网中的客户端查看到的本地服务器的NTP层级为该服务器上层级别+1,例如本地服务器中配置的上层NTP服务器为2层,那么本地子网中的客户端查询到的本地服务器的层级则为2+1=3层,配置中的local stratum 8不生效
  • 仅存在local字段配置:该chronyd仅作为服务端,无论本机的时间对不对,都将本机的时间同步给本地子网中的主机,这时,本地子网中的主机查询到的本地NTP服务器层级则为local startum 8中配置的层级

上面这2种情况下,allow字段都需要存在

4.5 chronyc命令解释

该命令是chronyd守护进程的命令行控制界面,chronyc有2个有用的选项如下:

chronyc 命令
-h host		指定联系到运行chronyd的主机上
-p port		指定chronyd用于监控连接的端口号,默认为udp323

连接到指定机器上的chronyd服务端
chronyc -h 192.168.1.1 -p 1123

不加这2个参数默认表示连接到本机的chronyd上

该命令有一些有用的选项来监控chronyd服务端的状态信息,这里选取了几个,下面进行简单的介绍

source指令:该命令用于显示chronyd中的服务器状态,语法为sources [-a][-v],加上[-a]选项的话,表示所有源都会显示(all),包括未知的源,示例如下:

[root@us2 ~]# chronyc -a sources
210 Number of sources = 2
MS Name/IP address         Stratum Poll Reach LastRx Last sample               
==========================================================================
^* 120.25.115.20                 2   6    17     6  +1317us[+7993us] +/-   16ms
^- 203.107.6.88                  2   6    17     5  -6810us[-6810us] +/-   43ms


相关字段解释:
M列:表示源的模式,^表示server,=表示peer,#表示本地连接的参考时钟
S列:表示源的选择状态
    *表示当前用于同步时间的最佳源
    +表示用于同步的其他源,这些源和最佳源相结合
    -表示被认为可以选择用于同步但是当前未选择的源
    x表示认为是虚假信息的来源(即他的时间和大多数其他来源、或使用trust选项指定的来源不一致)
    ~表示其时间有太多可变性
    ?表示由于其他原因不能选择用于同步的源(例如无法访问,未同步,没有足够的测量值等)

Stratum列:该服务器的NTP层级(这里显示阿里云的NTP服务器层级为2)
Poll列:源的轮询速率,表示2的几次方,这里6表示2的6次方,为64,表示每64秒进行一次NTP测量

sourcestats指令:用来查看有关chronyd当前正在检查的每个源的时间偏移量,等估计过程等信息,语法格式为sourcestats [-a][-v],使用[-a]选项的话,会显示所有源

[root@us2 ~]# chronyc -a sourcestats 
210 Number of sources = 2
Name/IP Address            NP  NR  Span  Frequency  Freq Skew  Offset  Std Dev
==========================================================================
120.25.115.20              23  13   28m     +0.003      1.263   +345ns   693us
203.107.6.88                8   7   583     -1.166      5.425  -9714us   512us


相关字段的解释:
NP:当前为服务器保留的样本数,通过对这些点执行线性回归来估计漂移率、电流漂移
NR:最后一次回归后具有相同符号的残差的运行次数,如果这个数字相对于样本数开始变得太小,如果运行次数太少,chronyd丢弃样本并重新运行回归,直到运行次数变得可以接受

Span列:旧样本和最新样本之间的间隔时间,如果未显示单位表示默认单位为s
Frequency列:服务器的估计剩余频率
Freq Skew列:Freq估计误差范围
Offset列:源的估计偏移量
Std Dev列:估计的样本标准差

clients命令:该命令用于列出通过NTP、NTS-KE端口访问本机NTP服务的客户端列表(不包括UNIX套接字的访问),仅记录通过访问检查指令的主机(使用allow、deny、cmdallow、cmddeny命令或配置文件指令设置的主机)

[root@us2 ~]# chronyc -n clients
Hostname                      NTP   Drop Int IntL Last     Cmd   Drop Int  Last
=========================================================================
192.168.111.23                  5      0   4   -    61       0      0   -     -


相关列的解释:
NTP列:从客户端收到的NTP数据包数量
Drop列:为了限制响应速率而丢弃的NTP数据包数量
Int列:NTP数据包之间的平均间隔
IntL列:限制响应速率后NTP包之间的平均间隔
Last列:自收最后一个NTP数据包以来的时间
Cmd列:从客户端接收到的命令包或NTS-KE连接数
Drop列:为限制响应速率而丢弃的命令包或NTS-KE连接数
Int列:命令包或NTS-KE连接之间的平均间隔
Last列:自收到最后一个命令包或NTS-KE连接以来的时间

4.6 chronyd命令解释

该命令为chrony的守护进程,该程序在启动的时候,如果没有在命令行指定配置文件,那么程序会从默认位置/etc/chrony.conf读取配置文件,输出的信息、告警记录到syslog中

chronyd命令解释:

-4		主机名将仅解析为IPv4地址,并且仅创建IPv4套接字
-6		主机名将仅解析为IPv6地址,并且仅创建IPv6套接字
-f file		指定配置文件的位置(/etc/chrony.conf)
-n		在此模式下运行时,程序将不会与终端分离
-d		在这种模式下运行时,程序不会将自身与终端分离,并且所有消息都将被写入终端,而不是syslog,当chronyd使用调试支持进行编译时,此选项可以使用两次来打印调试消息,该模式主要用于调试

-l file		此选项指定应用于记录日志的文件,而不是syslog或terminal
-q		在此模式下运行时,chronyd将设置系统时钟一次并退出。它不会从终端分离
-Q		该选项与-q选项相似,不同之处在于它仅打印偏移量而不对时钟进行任何更正,并且允许chronyd在没有root特权的情况下启动
-p		chronyd会输出配置并退出,该选项常常用于验证配置文件语法
-r		删除之前保存的每个NTP源的历史测量文件,这些文件是由dumpdir指令配置的
-s		将系统时钟设置为计算机的RTC或由driftfile指令指定的文件的最后的修改时间,RTC仅在Linux上受支持
-U		禁用对root权限的检查,并以非root用户下启动chronyd

五、总结

可以看出,chronyd和ntpd在配置文件中,很多配置部分都很类似,但有一定的差别

当下更加推荐chronyd服务

本文简要概述了几个NTP协议的软件实现,关于这几个NTP实现的详细信息请参考其官方网站

ntpd官方网站:​​​​​​http://www.ntp.org

chronyd官方网站: chrony – Introduction

Logo

为开发者提供学习成长、分享交流、生态实践、资源工具等服务,帮助开发者快速成长。

更多推荐