Network Time Protocol daemon (简体中文)

From ArchWiki
The printable version is no longer supported and may have rendering errors. Please update your browser bookmarks and please use the default browser print function instead.
翻译状态:本文是 Network_Time_Protocol_daemon翻译。上次翻译日期:2017-04-22。如果英文版本有所更改,则您可以帮助同步翻译。

Network Time Protocol (网络时间协议)是 GNU/Linux 系统通过互联网时间服务器同步系统软件时钟的最常见方法。设计时考虑到了各种网络延迟,通过公共网络同步时,误差可以降低到10毫秒以内;通过本地网络同步时,误差可以降低到 1 毫秒。

NTP 项目提供了一个名为简单 NTP 的参考实现。本文介绍如何设置和运行服务器和客户端 NTP 进程。

安装

安装 ntp 软件包。如果不做任何配置, ntpd 默认工作于客户端模式。如果使用 Arch Linux 默认的配置,请跳转到 #使用。作为服务器的配置,请参阅 #NTP 服务器模式

配置

主要的后台进程是 ntpd, 可以通过 /etc/ntp.conf 配置。详细信息可以参考手册 ntp.conf(5) 和相关的 man {ntpd|ntp_auth|ntp_mon|ntp_acc|ntp_clock|ntp_misc}.

连接到 NTP 服务器

NTP 服务器通过一个层级系统进行分类,不同的层级称为 strata;独立的时间源为stratum 0;直接连接到 stratum 0 的设备为 stratum 1;直接连接到 stratum 1 的源为 stratum 2,以此类推。

服务器的 stratum 并不能完全等同于它的精度和可靠度。通常的时间同步都使用 stratum 2 服务器。通过pool.ntp.org 服务器或这个链接 可以选择比较近的服务器池。

下面几行仅仅是例子:

/etc/ntp.conf
server 0.fr.pool.ntp.org iburst
server 1.fr.pool.ntp.org iburst
server 2.fr.pool.ntp.org iburst
server 3.fr.pool.ntp.org iburst

推荐使用iburst选项,如果第一次尝试无法建立连接,程序会发送一系列的包。burst 选项则总是发送一系列的包,即使第一次也是这样。如果没有明确的允许的话不要使用 burst 选项,有可能被封禁。

NTP 服务器模式

如果建立一个 NTP 服务器,你需要添加 local clock 作为一个服务器,这样,即便它失去网络连接,它也可以继续为网络提供服务;添加 local clock 作为一个 stratum 10 服务器 (使用 fudge 命令)这样它就只会在失去连接时使用本地时钟:

server 127.127.1.0
fudge  127.127.1.0 stratum 10

下一步,定义规则允许客户端连接你的服务(localhost 也被认为是一个客户端)。使用 restrict 命令;你应该在文件中已经有一行:

restrict default nomodify nopeer noquery

这限制了每个人做任何修改并阻止每个人请求你的时间服务器状态:nomodify 防止重新配置你的ntpd(使用ntpqntpdc ),noquery 防止从你的nptd(或是ntpqntpdc)获取状态数据。

你也能添加其它选项:

restrict default kod nomodify notrap nopeer noquery
注意: 这会允许其他人查询你的时间服务器。你需要添加 noserve 来停止提供时间。

"restrict"选项的完整文档可以从 ntp.conf(5) 中查找到。详见 https://support.ntp.org/bin/view/Support/AccessRestrictions

你需要在这一行之后告诉 ntpd 什么可以访问你的服务器;如果你不是在配置一台 NTP 服务器的话,下面一行就足够了。

restrict 127.0.0.1

如果你想要强制DNS解析到IPv6域名,在IP地址或域名前写上 -6-4 则强制使用IPv4域名),例如:

restrict -6 default kod nomodify notrap nopeer noquery
restrict -6 ::1    # ::1 is the IPv6 equivalent for 127.0.0.1

最后,指定drift文件(它能时刻监控你的时钟的时间漂移)和log文件的位置:

driftfile /var/lib/ntp/ntp.drift
logfile /var/log/ntp.log

一份基础的配置文件是这样的:

/etc/ntp.conf
server 0.pool.ntp.org iburst
server 1.pool.ntp.org iburst
server 2.pool.ntp.org iburst
server 3.pool.ntp.org iburst

restrict default kod nomodify notrap nopeer noquery
restrict -6 default kod nomodify notrap nopeer noquery

restrict 127.0.0.1
restrict -6 ::1  

driftfile /var/lib/ntp/ntp.drift
logfile /var/log/ntp.log
注意: 定义日志文件不是必须的,但是它对于反馈 ntpd 操作是有好处的。

使用

软件包默认包含客户端模式的配置,并且使用单独的用户和群组,启动时就会移除 root 权限。如果在终端中启动,请使用 -u 选项:

# ntpd -u ntp:ntp

systemd 服务默认使用 -u 选项和 -g 选项禁用一个阈值(panic-gate). 这样即使 ntp-server 的时间和系统时间的差异超过阈值,依然会同步时间。

警告: 使用 panic-gate 的原因是某些后台任务或服务会引起时间跳跃. 如果系统的时间从来没有同步过,请考虑先禁用其他服务再进行同步。

两个服务都依赖系统网络状况,会在检测到网络连接时开始同步。

启动时启用 ntpd

启用 ntpd.service 服务.

注意: systemd 命令 timedatectl 仅可以控制 systemd-timesyncd, 用 root 执行 timedatectl set-ntp 1 会停止运行中的 ntpd.service.[1]

ntpq 可以查看同步的状态:

$ ntpq -p

delay, offset 和 jitter 不应该为零,ntpd 同步的服务器前有星号,ntpd 可能等待很多分钟后才会进行同步,请等 17 分钟 (1024 秒).

每次启动同步一次

另一种方式是 启用 ntpdate.service 服务,每次启动都同步一次(-q) 并且是 non-forking (-n), 进程不会在后台运行。如果是服务器或者很多天才会重启一次,不建议使用此方式。

如果需要把同步到的时间写入硬件时钟,请按照 这里 的说明修改服务并启动:

/etc/systemd/system/ntpdate.service.d/hwclock.conf
[Service]
ExecStart=/usr/bin/hwclock -w

技巧

有网络连接的时候启动ntpd

ntpd 可以由你的网络管理器启动, 所以ntp这个守护进程只有在计算机有网络连接的时候才会启动.

Netctl

Tango-preferences-desktop-locale.png本文或本节需要翻译。要贡献翻译,请访问简体中文翻译团队Tango-preferences-desktop-locale.png

附注: 英文页面风格不好。添加 -u 参数以及“使用”中提及的可选参数,或尽可能使用 systemctl 。(在 Talk:Network Time Protocol daemon (简体中文)# 中讨论)

给你的 netctl 配置文件添加如下这几行:

ExecUpPost='/usr/bin/ntpd || true'
ExecDownPre='killall ntpd || true'
NetworkManager

通过网络管理器的 dispatcher 脚本,可以同网络连接一起启动/终止ntpd 守护进程。 安装networkmanager-dispatcher-ntpdAUR 预配置包 #启动时启用 ntpd 来让网络连接同步ntp启动/终止.

Wicd

Wicd 来说, 要在 postconnect 目录创建一个启动脚本,在 predisconnect 目录创建一个终止脚本。 记住要把他们设为可执行的哦:

/etc/wicd/scripts/postconnect/ntpd
#!/bin/bash
systemctl start ntpd &
/etc/wicd/scripts/predisconnect/ntpd
#!/bin/bash
systemctl stop ntpd &
注意: 根据 #使用ntpd 这个命令的说明,你可以自由设置自己的配置选项。

参照 Wicd#Scripts.

KDE

在KDE中,通过右击时间图标选择 Adjust date/time,可以使用 NTP (别忘了安装NTP)。 注意, 在配置KDE中配置NTP之前,先要把 ntp 守护进程设置为  disabled 状态. [2]

在GPS中使用NTP

大多数联网的交通工具要通过(共享内存) 方式让 ntpd 从GPS中接收时间。 但是, 从 ntpd 4.2.8版本开始,一个 更好 的办法出现了----直接与 gpsd守护进程交互。这个要先安装 gpsd .

/etc/ntp.conf 配置文件中添加下面这几行:

/etc/ntp.conf
#=========================================================
#  GPSD native ntpd driver
#=========================================================
# This driver exists from at least ntp version 4.2.8
# Details at
#   https://www.eecis.udel.edu/~mills/ntp/html/drivers/driver46.html
server 127.127.46.0 
fudge 127.127.46.0 time1 0.0 time2 0.0 refid GPS

只要 gpsd 一直起着,ntp就会一直正常运行。 ntp会通过一个本地套接字同 gpsd 连接, 搜索 gpsd 返回的 "gpsd_json" 对象.

要检验安装的话, 首先要检查 gpsd 是不是正常运行:

 $ cgps -s 

然后等个几分钟运行 ntpq -p. 这个会显示 ntpd 是否已经跟 gpsd 建立连接了:

$ ntpq -p
remote           refid            st t when poll reach   delay   offset  jitter
 ==================================================================================
*GPSD_JSON(0)    .GPS.            0 l   55   64  377    0.000    2.556  14.109
提示: 如果 reach 这列是0的话, 这就说明 ntpd 还没有同 gpsd 建立连接。 等几分钟再试一次。 有时 ntpd 要花点时间来跟gpsd 建立连接。

在 chroot 底下运行

注意: 在试图把 ntpd 放到chroot目录下面之前,ntpd 应该在正常路径下启动 (默认在 Arch Linux 安装路径下)。 因为在相对以root身份运行的进程,chroots的用户相对没有啥权限的。

创建一个新目录(如果还没创建的话) /etc/systemd/system/ntpd.service.d/,并添加在里面添加文件 customexec.conf ,内容如下:

[Service]
ExecStart=
ExecStart=/usr/bin/ntpd -g -i /var/lib/ntp -u ntp:ntp -p /run/ntpd.pid

然后, 编辑 /etc/ntp.conf 来改变 driftfile 路径来让跟它跟 chroot 路径保持一致, 而不是还用原先的普通路径。修改

driftfile       /var/lib/ntp/ntp.drift

driftfile       /ntp.drift

通过root创建永久目录和文件,作为一个合适的 chroot 环境来支持 getaddrinfo() :

# mkdir /var/lib/ntp/etc /var/lib/ntp/lib /var/lib/ntp/proc
# touch /var/lib/ntp/etc/resolv.conf /var/lib/ntp/etc/services

然后通过修改 fstab 绑定前面提到的文件:

/etc/fstab
...
#ntpd chroot mounts
/etc/resolv.conf  /var/lib/ntp/etc/resolv.conf none bind 0 0
/etc/services	  /var/lib/ntp/etc/services none bind 0 0
/lib		  /var/lib/ntp/lib none bind 0 0
/proc		  /var/lib/ntp/proc none bind 0 0
# mount -a

最后, 再一次重启 ntpd 监控进程。 一旦重启完成你就可以通过检查 /proc/{PID}/root 的软连接来判断监控进程是不是在 chrooted 下面工作:

# ps -C ntpd | awk '{print $1}' | sed 1d | while read -r PID; do ls -l /proc/$PID/root; done

正常应该链接到 /var/lib/ntp 而不是 /.

不用等一段时间就要确定 driftfile 配置是否工作正常是比较困难的, 因为 ntpd 不会经常读写。 如果配置错误的话,log里面会打印一个error; 如果配置正确的话, 时间戳会更新的。 可以通过等一天来判断,如果没有log中没有错误打印,并且log的时间戳还更新了,那么说明配置成功了。

排错

无法分配请求地址

Tango-preferences-desktop-locale.png本文或本节需要翻译。要贡献翻译,请访问简体中文翻译团队Tango-preferences-desktop-locale.png

附注: 英文章不正。对需要或必须使用 IPv6 的用户而言,此方案不可行。(在 Talk:Network Time Protocol daemon (简体中文)# 中讨论)

如果收到下列无法分配请求地址的报错信息:

$ journalctl -u ntpd
ntpd[2130]: bind(21) AF_INET6 fe80::6ef0:49ff:fe51:4946%2#123 flags 0x11 failed: Cannot assign requested address
ntpd[2130]: unable to create socket on eth0 (5) for fe80::6ef0:49ff:fe51:4946%2#123
ntpd[2130]: failed to init interface for address fe80::6ef0:49ff:fe51:4946%2

可以禁用 IPv6 解决。做法是:编辑 ntpd.service 添加 -4 参数:

[Service]
ExecStart=
ExecStart=/usr/bin/ntpd -g -u ntp:ntp -4

参见