Network Time Protocol daemon
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(使用ntpq 或 ntpdc ),noquery
防止從你的nptd(或是ntpq 和 ntpdc)獲取狀態數據。
你也能添加其它選項:
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
使用[編輯 | 編輯原始碼]
軟件包默認包含客戶端模式的配置,並且使用單獨的用戶和群組,啟動時就會移除 root 權限。如果在終端中啟動,請使用 -u
選項:
# ntpd -u ntp:ntp
systemd 服務默認使用 -u
選項和 -g
選項禁用一個閾值(panic-gate). 這樣即使 ntp-server 的時間和系統時間的差異超過閾值,依然會同步時間。
兩個服務都依賴系統網絡狀況,會在檢測到網絡連接時開始同步。
啟動時啟用 ntpd[編輯 | 編輯原始碼]
啟用 ntpd.service
服務.
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
給你的 netctl 配置文件添加如下這幾行:
ExecUpPost='/usr/bin/ntpd || true' ExecDownPre='killall ntpd || true'
- NetworkManager
通過網絡管理器的 dispatcher 腳本,可以同網絡連接一起啟動/終止ntpd 守護進程。 安裝networkmanager-dispatcher-ntpdAUR 預配置包 #啟動時啟用 ntpd 來讓網絡連接同步ntp啟動/終止.
- 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
在 chroot 底下運行[編輯 | 編輯原始碼]
創建一個新目錄(如果還沒創建的話) /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的時間戳還更新了,那麼說明配置成功了。
排錯[編輯 | 編輯原始碼]
無法分配請求地址[編輯 | 編輯原始碼]
如果收到下列無法分配請求地址的報錯信息:
$ 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