【轉】Linux NTP配置詳解 (Network Time Protocol)

spectre2發表於2011-12-15

Network Time Protocol (NTP) 也是RHCE新增的考試要求. 學習的時候也順便複習了一下如何設定Linux的時間,現在拿出來和大家分享

設定NTP伺服器不難但是NTP本身是一個很複雜的協議. 這裡只是簡要地介紹一下實踐方法
和上次一樣,下面的實驗都在RHEL5上執行

 

1. 時間和時區

如果有人問你說現在幾點? 你看了看錶回答他說晚上8點了. 這樣回答看上去沒有什麼問題,但是如果問你的這個人在歐洲的話那麼你的回答就會讓他很疑惑,因為他那裡還太陽當空呢.

這裡就有產生了一個如何定義時間的問題. 因為在地球環繞太陽旋轉的24個小時中,世界各地日出日落的時間是不一樣的.所以我們才有劃分時區(timezone) 的必要,也就是把全球劃分成24個不同的時區. 所以我們可以把時間的定義理解為一個時間的值加上所在地的時區(注意這個所在地可以精確到城市)

地理課上我們都學過格林威治時間(GMT), 它也就是0時區時間. 但是我們在計算機中經常看到的是UTC. 它是Coordinated Universal Time的簡寫. 雖然可以認為UTC和GMT的值相等(誤差相當之小),但是UTC已經被認定為是國際標準,所以我們都應該遵守標準只使用UTC

那麼假如現在中國當地的時間是晚上8點的話,我們可以有下面兩種表示方式
20:00 CST
12:00 UTC

這裡的CST是Chinese Standard Time,也就是我們通常所說的北京時間了. 因為中國處在UTC+8時區,依次類推那麼也就是12:00 UTC了.

為什麼要說這些呢(呵呵這裡不是地理論壇吧...)

第一,不管通過任何渠道我們想要同步系統的時間,通常提供方只會給出UTC+0的時間值而不會提供時區(因為它不知道你在哪裡).所以當我們設定系統時間的時候,設定好時區是首先要做的工作
第二,很多國家都有夏令時(我記得小時候中國也實行過一次),那就是在一年當中的某一天時鐘撥快一小時(比如從UTC+8一下變成UTC+9了),那麼同理到時候還要再撥慢回來.如果我們設定了正確的時區,當需要改變時間的時候系統就會自動替我們調整

現在我們就來看一下如何在Linux下設定時區,也就是time zone

 

2. 如何設定Linux Time Zone

在Linux下glibc提供了我們事先編譯好的許多timezone檔案, 他們就放在/usr/share/zoneinfo這個目錄下,這裡基本涵蓋了大部分的國家和城市
程式碼:
# ls -F /usr/share/zoneinfo/
Africa/      Chile/   Factory    Iceland      Mexico/   posix/      Universal
America/     CST6CDT  GB         Indian/      Mideast/  posixrules  US/
Antarctica/  Cuba     GB-Eire    Iran         MST       PRC         UTC
Arctic/      EET      GMT        iso3166.tab  MST7MDT   PST8PDT     WET
Asia/        Egypt    GMT0       Israel       Navajo    right/      W-SU
Atlantic/    Eire     GMT-0      Jamaica      NZ        ROC         zone.tab
Australia/   EST      GMT+0      Japan        NZ-CHAT   ROK         Zulu
Brazil/      EST5EDT  Greenwich  Kwajalein    Pacific/  Singapore
Canada/      Etc/     Hongkong   Libya        Poland    Turkey
CET          Europe/  HST        MET          Portugal  UCT在這裡面我們就可以找到自己所在城市的time zone檔案. 那麼如果我們想檢視對於每個time zone當前的時間我們可以用zdump命令
程式碼:
# zdump Hongkong
Hongkong  Fri Jul  6 06:13:57 2007 HKT那麼我們又怎麼來告訴系統我們所在time zone是哪個呢? 方法有很多,這裡舉出兩種

第一個就是修改/etc/localtime這個檔案,這個檔案定義了我麼所在的local time zone.
我們可以在/usr/share/zoneinfo下找到我們的time zone檔案然後拷貝去到/etc/localtimezone(或者做個symbolic link)

假設我們現在的time zone是BST(也就是英國的夏令時間,UTC+1)
程式碼:
# date
Thu Jul  5 23:33:40 BST 2007我們想把time zone換成上海所在的時區就可以這麼做
程式碼:
# ln -sf /usr/share/zoneinfo/posix/Asia/Shanghai /etc/localtime
# date
Fri Jul  6 06:35:52 CST 2007
這樣時區就改過來了(注意時間也做了相應的調整)

第二種方法也就設定TZ環境變數的值. 許多程式和命令都會用到這個變數的值. TZ的值可以有多種格式,最簡單的設定方法就是使用tzselect命令
程式碼:
# tzselect
...
TZ='America/Los_Angeles';export TZtzselect
會讓你選擇所在的國家和城市(我省略了這些步驟),最後輸出相應的TZ變數的值.那麼如果你設定了TZ的值之後時區就又會發生變化

程式碼:
# date
Thu Jul  5 15:48:11 PDT 2007
通過這兩個例子我們也可以發現TZ變數的值會override /etc/localtime. 也就是說當TZ變數沒有定義的時候系統才使用/etc/localtime來確定time zone. 所以你想永久修改time zone的話那麼可以把TZ變數的設定寫入/etc/profile裡

好了現在我們知道怎麼設定時區了,下面我們就來看看如何設定Linux的時間吧

 

3. Real Time Clock(RTC) and System Clock

說道設定時間這裡還要明確另外一個概念就是在一臺計算機上我們有兩個時鐘:一個稱之為硬體時間時鐘(RTC),還有一個稱之為系統時鐘(System Clock)

硬體時鐘是指嵌在主機板上的特殊的電路, 它的存在就是平時我們關機之後還可以計算時間的原因
系統時鐘就是作業系統的kernel所用來計算時間的時鐘. 它從1970年1月1日00:00:00 UTC時間到目前為止秒數總和的值 在Linux下系統時間在開機的時候會和硬體時間同步(synchronization),之後也就各自獨立執行了

那麼既然兩個時鐘獨自執行,那麼時間久了必然就會產生誤差了,下面我們來看一個例子
程式碼:
# date
Fri Jul  6 00:27:13 BST 2007
# hwclock --show
Fri 06 Jul 2007 12:27:17 AM BST  -0.968931 seconds
通過hwclock --show 命令我們可以檢視機器上的硬體時間(always in local time zone), 我們可以看到它和系統時間還是有一定的誤差的, 那麼我們就需要把他們同步

如果我們想要把硬體時間設定成系統時間我們可以執行以下命令
程式碼:
# hwclock --hctosys  反之,我們也可以把系統時間設定成硬體時間
程式碼:
# hwclock --systohc  那麼如果想設定硬體時間我們可以開機的時候在BIOS裡設定.也可以用hwclock命令
程式碼:
# hwclock --set --date="mm/dd/yy hh:mm:ss"  如果想要修改系統時間那麼用date命令就最簡單了
程式碼:
# date -s "dd/mm/yyyy hh:mm:ss"  現在我們知道了如何設定系統和硬體的時間. 但問題是如果這兩個時間都不準確了怎麼辦? 那麼我們就需要在網際網路上找到一個可以提供我們準確時間的伺服器然後通過一種協議來同步我們的系統時間,那麼這個協議就是NTP了. 注意接下去我們所要說的同步就都是指系統時間和網路伺服器之間的同步了


4. 設定NTP Server前的準備

其實這個標題應該改為設定"NTP Relay Server"前的準備更加合適. 因為不論我們的計算機配置多好執行時間久了都會產生誤差,所以不足以給網際網路上的其他伺服器做NTP Server. 真正能夠精確地測算時間的還是原子鐘. 但由於原子鐘十分的昂貴,只有少部分組織擁有, 他們連線到計算機之後就成了一臺真正的NTP Server. 而我們所要做的就是連線到這些伺服器上同步我們系統的時間,然後把我們自己的伺服器做成NTP Relay Server再給網際網路或者是區域網內的使用者提供同步服務

好了,前面講了一大堆理論,現在我們來動手實踐一下吧. 架設一個NTP Relay Server其實非常簡單,我們先把需要的RPM包裝上
是否已經安裝了NTP包可以用這條命令來確定:

[root@NTPser ~]# rpm -qa | grep ntp
ntp-4.2.2p1-9.el5_4.1
chkfontpath-1.10.1-1.1
出現以上程式碼則表示已安裝NTP包,否則用下面方法安裝:
程式碼:

# rpm -ivh ntp-4.2.2p1-5.el5.rpm

那麼第一步我們就要找到在網際網路上給我們提供同步服務的NTP Server

http://www.pool.ntp.org是NTP的官方網站,在這上面我們可以找到離我們城市最近的NTP Server. NTP建議我們為了保障時間的準確性,最少找兩個個NTP Server
那麼比如在英國的話就可以選擇下面兩個伺服器
0.uk.pool.ntp.org
1.uk.pool.ntp.org

它的一般格式都是number.country.pool.ntp.org

第二步要做的就是在開啟NTP伺服器之前先和這些伺服器做一個同步,使得我們機器的時間儘量接近標準時間.
這裡我們可以用ntpdate命令手動更新時間
程式碼:
# ntpdate 0.uk.pool.ntp.org
 6 Jul 01:21:49 ntpdate[4528]: step time server 213.222.193.35 offset -38908.575181 sec
# ntpdate 0.pool.ntp.org
 6 Jul 01:21:56 ntpdate[4530]: adjust time server 213.222.193.35 offset -0.000065 sec
假如你的時間差的很離譜的話第一次會看到調整的幅度比較大,所以保險起見可以執行兩次. 那麼為什麼在開啟NTP服務之前先要手動執行同步呢?
1. 因為根據NTP的設定,如果你的系統時間比正確時間要快的話那麼NTP是不會幫你調整的,所以要麼你把時間設定回去,要麼先做一個手動同步
2. 當你的時間設定和NTP伺服器的時間相差很大的時候,NTP會花上較長一段時間進行調整.所以手動同步可以減少這段時間

5. 配置和執行NTP Server

現在我們就來建立NTP的配置檔案了, 它就是/etc/ntp.conf. 我們只需要加入上面的NTP Server和一個driftfile就可以了
程式碼:
# vi /etc/ntp.conf

server 210.72.145.44     #這是中國國家授時中心的IP
server 0.uk.pool.ntp.org
server 1.uk.pool.ntp.org
                                     
fudge 127.127.1.0 stratum 0  stratum
 
這行是時間伺服器的層次。設為0則為頂級,如果要向別的NTP伺服器更新時間,請不要把它設為0

driftfile /var/lib/ntp/ntp.drift  非常的簡單. 接下來我們就啟動NTP Server,並且設定其在開機後自動執行
程式碼:
# /etc/init.d/ntpd start
# chkconfig --level 35 ntpd on

 

6. 檢視NTP服務的執行狀況

現在我們已經啟動了NTP的服務,但是我們的系統時間到底和伺服器同步了沒有呢? 為此NTP提供了一個很好的檢視工具: ntpq (NTP query)

我建議大家在開啟NTP伺服器後就可以執行ntpq命令來監測伺服器的執行.這裡我們可以使用watch命令來檢視一段時間內伺服器各項數值的變化
程式碼:
# watch ntpq -p
Every 2.0s: ntpq -p                                  Sat Jul  7 00:41:45 2007

     remote           refid      st t when poll reach   delay   offset  jitter
===========================================================
+193.60.199.75   193.62.22.98     2 u   52   64  377    8.578   10.203 289.032
*mozart.musicbox 192.5.41.41      2 u   54   64  377   19.301  -60.218 292.411

 

現在我就來解釋一下其中的含義

  remote: 它指的就是本地機器所連線的遠端NTP伺服器
      refid: 它指的是給遠端伺服器(e.g. 193.60.199.75)提供時間同步的伺服器
          st: 遠端伺服器的層級別(stratum). 由於NTP是層型結構,有頂端的伺服器,多層的Relay Server再到客戶端. 所以伺服器從高到低階別可以設定為1-16. 為了減緩負荷和網路堵塞,原則上應該避免直接連線到級別為1的伺服器的.
            t: 這個.....我也不知道啥意思^_^
    when: 我個人把它理解為一個計時器用來告訴我們還有多久本地機器就需要和遠端伺服器進行一次時間同步
       poll: 本地機和遠端伺服器多少時間進行一次同步(單位為秒). 在一開始執行NTP的時候這個poll值會比較小,那樣和伺服器同步的頻率也就增加了,可以儘快調整到正確的時間範圍.之後poll值會逐漸增大,同步的頻率也就會相應減小
    reach: 這是一個八進位制值,用來測試能否和伺服器連線.每成功連線一次它的值就會增加
    delay: 從本地機傳送同步要求到伺服器的round trip time
    offset: 這是個最關鍵的值, 它告訴了我們本地機和伺服器之間的時間差別. offset越接近於0,我們就和伺服器的時間越接近
     jitter: 這是一個用來做統計的值. 它統計了在特定個連續的連線數裡offset的分佈情況. 簡單地說這個數值的絕對值越小我們和伺服器的時間就越精確

那麼大家細心的話就會發現兩個問題: 第一我們連線的是0.uk.pool.ntp.org為什麼和remote server不一樣? 第二那個最前面的+和*都是什麼意思呢?

第一個問題不難理解,因為NTP提供給我們的是一個cluster server所以每次連線的得到的伺服器都有可能是不一樣.同樣這也告訴我們了在指定NTP Server的時候應該使用hostname而不是IP

第二個問題和第一個相關,既然有這麼多的伺服器就是為了在發生問題的時候其他的伺服器還可以正常地給我們提供服務.那麼如何知道這些伺服器的狀態呢? 這就是第一個記號會告訴我們的資訊

* 它告訴我們遠端的伺服器已經被確認為我們的主NTP Server,我們系統的時間將由這臺機器所提供
+ 它將作為輔助的NTP Server和帶有*號的伺服器一起為我們提供同步服務. 當*號伺服器不可用時它就可以接管
- 遠端伺服器被clustering algorithm認為是不合格的NTP Server
x 遠端伺服器不可用

 

瞭解這些之後我們就可以實時監測我們系統的時間同步狀況了

 

7. NTP安全設定

執行一個NTP Server不需要佔用很多的系統資源,所以也不用專門配置獨立的伺服器,就可以給許多client提供時間同步服務, 但是一些基本的安全設定還是很有必要的
那麼這裡一個很簡單的思路就是第一我們只允許區域網內一部分的使用者連線到我們的伺服器. 第二個就是這些client不能修改我們伺服器上的時間

關於許可權設定部分
許可權的設定主要以 restrict 這個引數來設定,主要的語法為:
restrict IP地址 mask 子網掩碼 引數
其中 IP 可以是IP地址,也可以是 default ,default 就是指所有的IP
引數有以下幾個:
ignore :關閉所有的 NTP 聯機服務
nomodify:客戶端不能更改服務端的時間引數,但是客戶端可以通過服務端進行網路校時。
notrust :客戶端除非通過認證,否則該客戶端來源將被視為不信任子網
noquery :不提供客戶端的時間查詢
注意:如果引數沒有設定,那就表示該 IP (或子網)沒有任何限制!

在/etc/ntp.conf檔案中我們可以用restrict關鍵字來配置上面的要求

首先我們對於預設的client拒絕所有的操作
程式碼:
restrict default kod nomodify notrap nopeer noquery

然後允許本機地址一切的操作
程式碼:
restrict 127.0.0.1

最後我們允許區域網內所有client連線到這臺伺服器同步時間.但是拒絕讓他們修改伺服器上的時間
程式碼:
restrict 192.168.1.0 mask 255.255.255.0 nomodify

把這三條加入到/etc/ntp.conf中就完成了我們的簡單配置. NTP還可以用key來做authentication,這裡就不詳細介紹了

 

8. NTP client的設定

做到這裡我們已經有了一臺自己的Relay Server.如果我們想讓區域網內的其他client都進行時間同步的話那麼我們就都應該照樣再搭建一臺Relay Server,然後把所有的client都指向這兩臺伺服器(注意不要把所有的client都指向Internet上的伺服器). 只要在client的/etc/ntp.conf加上這你自己的伺服器就可以了
程式碼:
server ntp1.leonard.com
server ntp2.leonard.com

 

LINUX客戶端使用
ntpdate 172.30.218.114
來向NTP伺服器同步自己的時間
其它LINUX如果僅作為只客戶端的話,則不能啟動ntpd服務!否則無法執行ntpdata 伺服器地址 來同步時間
之後可以使用cron或修改crontab檔案定期向NTP伺服器更新時間,並用
# hwclock --systohc  
將系統時間設定為硬體時間

9. 一些補充和拾遺(挺重要)

1. 配置檔案中的driftfile是什麼?
我們每一個system clock的頻率都有小小的誤差,這個就是為什麼機器執行一段時間後會不精確. NTP會自動來監測我們時鐘的誤差值並予以調整.但問題是這是一個冗長的過程,所以它會把記錄下來的誤差先寫入driftfile.這樣即使你重新開機以後之前的計算結果也就不會丟失了

2. 如何同步硬體時鐘?
NTP一般只會同步system clock. 但是如果我們也要同步RTC(hwclock)的話那麼只需要把下面的選項開啟就可以了
程式碼:
# vi /etc/sysconfig/ntpd
SYNC_HWCLOCK=yes

 

3、利用crontab讓LINUX NTP定時更新時間
注:讓linux執行ntpdate更新時間時,linux不能開啟NTP服務,否則會提示埠被佔用:如下
[root@ESXI ~]# ntpdate 1.rhel.pool.ntp.org                                 
20 May 09:34:14 ntpdate[6747]: the NTP socket is in use, exiting

crontab檔案配置簡要說明
命令格式的前一部分是對時間的設定,後面一部分是要執行的命令。時間的設定我們有一定的約定,前面五個*號代表五個數字,數字的取值範圍和含義如下:
分鐘 (0-59)
小時 (0-23)
日期 (1-31)
月份 (1-12)
星期 (0-6)//0代表星期天
除了數字還有幾個個特殊的符號就是“*”、“/”和“-”、“,”,“*”代表所有的取值範圍內的數字,“/”代表每的意思,“*/5”表示每5個單位,“-”代表從某個數字到某個數字,“,”分開幾個離散的數字。以下舉幾個例子說明問題:
每天早上6點:
0 6 * * *  command
每兩個小時:
0 */2 * * *  command
晚上11點到早上8點之間每兩個小時,早上八點:
0 23-7/2,8 * * * command
每個月的4號和每個禮拜的禮拜一到禮拜三的早上11點:
0 11 4 * 1-3 command
1月1日早上4點:
0 4 1 1 * command

3.3、設定開機自動啟動服務
執行setup或其它服務設定工具,將crond服務勾選上
chkconfig --level 2345 crond on  定義在這幾個系統執行級別上啟用crond (系統安裝完預設就是這個設定)
__________________________________________

 

10.NTP客戶端的設定

一、LINUX做為客戶端自動同步時間
如果想定時進行時間校準,可以使用crond服務來定時執行。
編輯 /etc/crontab 檔案
加入下面一行:

30 8 * * * root /usr/sbin/ntpdate 192.168.0.1; /sbin/hwclock -w  #192.168.0.1是NTP伺服器的IP地址
然後重啟crond服務
service crond restart
這樣,每天 8:30 Linux 系統就會自動的進行網路時間校準。

 

二、WINDOWS 需要開啟windows time服務和RPC的二個服務
如果在開啟windows time 服務,時報 錯誤1058,進行下面操作
1.執行 cmd 進入命令列,然後鍵入
w32tm /register  進行註冊
正確的響應為:W32Time 成功註冊。

2.如果上一步正確,用 net start "windows time" 或 net start w32time 啟動服務。

 

11.其它造成無法成功更新的原因:
1、客戶端的日期必須要設定正確,不能超出正常時間24小時,不然會因為安全原因被拒絕更新。其次客戶端的時區必須要設定好,以確保不會更新成其它時區的時間。
2、fudge 127.127.1.0 stratum 10 如果是LINUX做為NTP伺服器,stratum(層級)的值不能太大,如果要向上級NTP更新可以設成2
3、LINUX的NTP伺服器必須記得將從上級NTP更新的時間從系統時間寫到硬體裡去 hwclock --systohc
     NTP一般只會同步system clock. 但是如果我們也要同步RTC(hwclock)的話那麼只需要把下面的選項開啟就可以了
      程式碼:
      # vi /etc/sysconfig/ntpd
      SYNC_HWCLOCK=yes
4、Linux如果開啟了NTP服務,則不能手動執行ntpdate更新時間(會報埠被佔用),它只能根據/etc/ntp.conf 裡server 欄位後的伺服器地址按一定時間間隔自動向上級NTP伺服器更新時間。可以執行命令 ntpstat 檢視每次更新間隔如:
[root@ESXI ~]# ntpstat
synchronised to NTP server (210.72.145.44) at stratum 2    #本NTP伺服器層次為2,已向210.72.145.44 NTP同步過
   time correct to within 93 ms                                               #時間校正到相差93ms之內
   polling server every 1024 s                                                 #每1024秒會向上級NTP輪詢更新一次時間

轉自:http://blog.csdn.net/iloli/article/details/6431757 

來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/14184018/viewspace-713353/,如需轉載,請註明出處,否則將追究法律責任。

相關文章