跳转至内容

网络时间协议守护进程

来自 ArchWiki

网络时间协议 (NTP) 是最常用的方法,用于将 GNU/Linux 系统的 软件时钟 与互联网时间服务器同步。它旨在减轻网络延迟变化的影响,通常可以在公共互联网上将时间精度保持在几十毫秒以内。在局域网上的精度甚至更高,可达一毫秒。

NTP 项目 提供了一个名为 NTP 的协议的参考实现。本文将进一步介绍如何设置和运行 NTP 守护程序,作为客户端和服务器。

有关其他 NTP 实现,请参阅 System time#Time synchronization

安装

安装 ntp 软件包。默认情况下,ntpd 在没有进一步配置的情况下以客户端模式运行。如果您想使用 Arch Linux 的默认配置文件,可以直接跳到 #Usage。有关服务器配置,请参阅 #NTP server mode

配置

主守护程序是 ntpd,它在 /etc/ntp.conf 中进行配置。有关详细信息,请参阅 ntp.conf(5)

连接到 NTP 服务器

NTP 服务器被分为一个包含许多级别的分层系统,称为 strata(层级):被视为独立时间源的设备被归类为 stratum 0 源;直接连接到 stratum 0 设备的服务器被归类为 stratum 1 源;连接到 stratum 1 源的服务器然后被归类为 stratum 2 源,依此类推。

需要理解的是,服务器的层级不能作为其精度或可靠性的指标。通常,stratum 2 服务器用于一般的同步目的:如果您不知道将要连接的服务器,应该从 pool.ntp.org 服务器池中选择一个离您位置较近的服务器(备用链接)。

ntp 版本 4.2.7.p465-2 以来,Arch Linux 使用由 NTP Pool 项目提供的自有默认 NTP 服务器池(请参阅 FS#41700)。根据您的需求修改它们,例如,如果您想使用您所在国家/地区的服务器,可以添加一个选项

/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 选项无论如何都会这样做,即使在第一次尝试时,并且在未获得明确许可的情况下不应使用,否则可能导致被列入黑名单。

闰秒文件

为了使系统能够向请求它的应用程序提供 国际原子时间,必须加载闰秒列表。该列表是 tzdata 软件包的一部分,可以通过将以下行添加到 NTP 配置文件来加载

leapfile /usr/share/zoneinfo/leap-seconds.list

NTP 服务器模式

如果您正在设置 NTP 服务器,请检查是否已启用 孤儿模式 (orphan mode),这样即使它失去互联网连接,它也能继续为网络提供时间;通过 tos 配置参数启用孤儿模式(您可以设置高达 stratum 15),这样除非互联网连接丢失,否则它永远不会被使用。

tos orphan 15

接下来,使用 restrict 命令定义允许客户端连接到您的服务的规则(localhost 也被视为客户端);您的文件中应该已经有一行像这样

restrict default nomodify nopeer noquery

这会阻止所有人修改任何内容,并阻止所有人查询您的时间服务器的状态:nomodify 可阻止重配置 ntpd(使用 ntpqntpdc),而 noquery 对于 防止ntpd(同样使用 ntpqntpdc)转储状态数据非常重要。

您还可以添加其他选项

restrict default kod limited nomodify notrap nopeer noquery
注意 这仍然允许其他人查询您的时间服务器。您需要添加 noserve 来停止提供时间。它还会阻止时间同步,因为它会阻止除 ntpqntpdc 查询之外的所有数据包。

如果您想更改其中任何一个,请参阅 ntp.conf(5) 中关于 "restrict" 选项的完整文档,以及详细的 NTP 说明#Usage

在此行之后,您需要告诉 ntpd 允许哪些流量进入您的服务器;如果您不配置 NTP 服务器,以下行就足够了

restrict 127.0.0.1

如果您想强制 DNS 解析到 IPv6 命名空间,请在 IP 地址或主机名之前写上 -6-4 则强制 IPv4),例如

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

最后,指定漂移文件(drift file,用于跟踪您的时钟时间偏差)以及可选的日志文件位置

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

一个非常基础的配置文件将如下所示

/etc/ntp.conf
server 0.arch.pool.ntp.org iburst
server 1.arch.pool.ntp.org iburst
server 2.arch.pool.ntp.org iburst
server 3.arch.pool.ntp.org iburst
tos orphan 15

restrict default kod limited nomodify notrap nopeer noquery
restrict -6 default kod limited 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

-u 选项被包含的两个 systemd 服务使用。这些服务还使用 -g 选项,该选项禁用了一个阈值(所谓的 panic-gate)。因此,即使 ntp-server 的时间超过了系统时钟的阈值偏差,它们也会同步时间。

警告 引入 panic-gate 的一个原因是因为后台作业/服务可能容易受到时间跳转的影响。如果系统的时钟从未同步过,请在首次运行 ntpd 之前考虑停止它们。

这两个服务都与系统的解析器绑定,并在检测到活动网络连接时开始同步。

启动 ntpd 守护进程

启用 ntpd.service 守护程序。另请参阅 #Running in a chroot

注意 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)并且不fork(选项 -n),而不是在后台运行守护程序。此方法不推荐用于服务器,以及在不重启的情况下运行超过几天的机器。

如果同步的时间也应该写入硬件时钟,请在启动之前,按照 systemd#Editing provided units 中的描述配置提供的单元。

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

技巧与提示

网络连接时启动 ntpd

ntpd 可以由您的网络管理器启动,这样守护程序只在计算机在线时运行。

Netctl

将以下行追加到您的 netctl 配置文件中

ExecUpPost="systemctl start ntpd.service"
ExecDownPre="systemctl stop ntpd.service"

NetworkManager

可以通过 NetworkManager 的 调度器 脚本,将 ntpd 守护程序随网络连接一起启动/停止。AUR 软件包 networkmanager-dispatcher-ntpd 安装了一个预先配置好的脚本,用于在连接时启动和停止 ntpd 服务

KDE

KDE 可以使用 NTP(必须安装 ntp),方法是右键单击时钟并选择 调整日期/时间。但是,这要求在配置 KDE 使用 NTP 之前 禁用 ntp 守护程序。[2]

使用 ntpd 和 GPS

网上关于配置 ntpd 从 GPS 接收时间的文章大部分建议使用 SHM(共享内存)方法。然而,至少自 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 正常工作,这就会奏效。它通过本地套接字连接到 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 需要一些时间。
  • GPS 设备必须具备 PPS 功能。您可以通过运行 ppscheck /dev/gps0 来测试您的设备是否具备此能力。
注意 ntpd 期望您的 GPS 设备名称为 /dev/gps0。如果您的 GPS 设备通过 USB 连接,它可能显示为 /dev/ttyUSB0,您可能需要创建一个符号链接 ln -s /dev/ttyUSB0 /dev/gps0,并在该链接的 /dev/gps0 上运行 gpsd,以便 GPSD_JSON 行按预期出现。gpsd 应该在 /etc/default/gpsd 配置文件中的 GPSD_OPTIONS 行上使用 -n 标志运行,并在 DEVICES 行上使用 /dev/gps0

在 chroot 中运行

注意 在尝试将 ntpd 放入 chroot 之前,应以非 root 用户身份启动它(Arch Linux 软件包中的默认设置),因为 chroot 在保护以 root 身份运行的进程方面作用相对有限。

如果 /etc/systemd/system/ntpd.service.d/ 目录不存在,则创建它,并在其中创建一个名为 customexec.conf 的文件,内容如下

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

然后,编辑 /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
# mkdir /var/lib/ntp/usr /var/lib/ntp/usr/lib
# touch /var/lib/ntp/etc/resolv.conf /var/lib/ntp/etc/services

并通过绑定挂载上述文件

/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
/usr/lib	  /var/lib/ntp/usr/lib none bind 0 0
/proc		  /var/lib/ntp/proc none bind 0 0
# mount -a

最后,重新启动 ntpd 守护程序。重新启动后,您可以检查守护进程是否被 chroot,方法是查看 /proc/{PID}/root 符号链接指向哪里

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

现在应该指向 /var/lib/ntp 而不是 /

在等待一段时间之前,相对难以确定您的 driftfile 配置是否真正有效,因为 ntpd 不会非常频繁地读取或写入它。如果配置错误,它会记录一个错误;如果配置正确,它会更新时间戳。如果在运行一整天后没有看到任何关于它的错误,并且时间戳已更新,您应该确信已成功。

限制监听套接字

您可以使用 interface 选项来限制 ntpd 正在监听的套接字

interface [listen | ignore | drop] [all | ipv4 | ipv6 | wildcard | name | address[/prefixlen]]

例如

/etc/ntp.conf
interface listen lo
interface listen enp3s0
interface ignore enp5s0

参见

© . This site is unofficial and not affiliated with Arch Linux.

Content is available under GNU Free Documentation License 1.3 or later unless otherwise noted.