伺服器架設篇 - CentOS 6.x

第十五章、時間伺服器: NTP 伺服器

Network Time Protocol 就是 NTP 的全名。NTP 主機主要在提供網路上可以進行網路校時的主機功能!

最近更新時間: 2011/07/29

電腦內部所記錄的時鐘是記載於 BIOS (CMOS) 內的,但如果你的電腦上面的電池沒電了,或者是某些特殊因素導致 BIOS 資料被清除, 此時電腦的時間就會不準。同時,某些作業系統程式的問題,也可能導致我們看到的時間與現實社會不相同的情況。 所以我們都會調整一下時間,好讓電腦系統的時間可以一直保持正確的狀態。 在實際生活中,我們可以透過電視台、廣播電台、電話等等來調整我們的手錶,那麼如果是在網路上呢? 該如何讓我們的主機隨時保持正確的時間資訊?這就需要 NTP 這個伺服器囉。

15.1 關於時區與網路校時的通訊協定

時間對於現代人來說是很重要的,因為『 Time is money 』。既然時間如此重要,對於網際網路來說應該也是很重要吧? 為什麼呢?還記得我們在基礎學習篇第三版第十九章、登錄檔分析吧? 如果你架設了一個登錄檔伺服器的話,那麼總得要分析每個主機所傳來的登錄檔資訊吧?如果每一部主機的時間都不相同, 那如何判斷問題發生的時間點?所以囉,『每一部主機的時間同步化』就很重要了。

每一部主機時間同步化的重要性當然不只如此,包括之前談到的 DHCP 用戶端/伺服器端所需要的租約時間限制、 網路偵測時所需要注意的時間點、剛剛談到的登錄檔分析功能、具有相關性的主機彼此之間的錯誤偵測、前一章談到的叢集電腦群等等, 都需要具有相同的時間才能夠捉出問題呢。好了,底下咱們就來聊一聊,如何利用網路來進行主機的時間同步化吧!

15.1.1 什麼是時區?全球有多少時區?GMT 在那個時區?

因為地球是圓的,所以同一個時刻,在地球的一邊是白天,一邊是黑夜。而因為人類使用一天 24 小時的制度,所以,在地球對角的兩邊就應該差了 12 個小時才對。由於同一個時間點上面, 整個地球表面的時間應該都不一樣,為了解決這個問題,所以可以想見的,地球就被分成 24 個時區了!

那麼這 24 個時區是依據什麼來劃分的呢?由於地球被人類以『經緯度』座標來進行定位, 而經度為零的地點在英國『格林威治』這個城市所在的縱剖面上, (註:所謂的縱剖面就是由南極切到北極的直線,而橫切面就是與赤道平行的切線),如下圖所示:

地球的子午線、經緯度與時區的分隔概念
圖 15.1-1、地球的子午線、經緯度與時區的分隔概念

因為繞地球一圈是 360 度角,這 360 度角共分為 24 個時區,當然一個時區就是 15 度角啦! 又由於是以格林威治時間為標準時間 (Greenwich Mean Time, GMT 時間),加上地球自轉的關係,因此,在格林威治以東的區域時間是比較快的(+小時),而以西的地方當然就是較慢囉!

以台灣為例,因為台灣所在地約為東經 120 度北緯 25 度左右,又因為台灣在格林威治的東方 (廢話!因為是東經嘛! ^_^),因此台灣本地時間 (local time) 會比 GMT 時間快 8 小時 (GMT + 8)。當格林威治時間為零點,台灣就已經是早上八點了!底下約略列出各個時區的名稱與所在經度,以及與 GMT 時間的時差:

標準時區 經度 時差
GMT , Greenwich Mean Time 0   W/E 標準時間
CET , Central European 15  E +1  東一區
EET , Eastern European 30  E +2  東二區
BT  , Baghdad 45  E +3  東三區
USSR, Zone 3  60  E +4  東四區
USSR, Zone 4 75  E +5  東五區
Indian, First 82.3E +5.5東五半區
USSR, Zone 5 90  E +6  東六區
SST , South Sumatra 105 E +7  東七區
JT  , Java 112 E +7.5東七半區
CCT , China Coast (台灣所在地) 120 E +8  東八區
JST , Japan 135 E +9  東九區
SAST, South Australia 142 E +9.5東九半區
GST , Guam 150 E +10 東十區
NZT , New Zealand 180 E +12 東十二區
Int'l Date Line 180 E/W 國際換日線
BST , Bering 165 W -11 西十一區
SHST, Alaska/Hawaiian 150 W -10 西十區
YST , Yukon 135 W -9  西九區
PST , Pacific 120 W -8  西八區
MST , Mountain 105 W -7  西七區
CST , Central 90  W -6  西六區
EST , Eastern 75  W -5  西五區
AST , Atlantic 60  W -4  西四區
Brazil, Zone 2 45  W -3  西三區
AT  , Azores 30  W -2  西二區
WAT , West Africa 15  W -1  西一區

所以囉,台灣時間是 GMT + 8 就很容易推算出來了吧!要特別留意的是,很多朋友在安裝 Linux 的時候, 總是會發現目前的時間慢或者快了 8 小時,不要懷疑,絕對與時區有關! 趕緊給他查一下如何調整時區吧! ^_^。

另外,在上表中有個比較有趣的時區,那就是在太平洋上面的國際換日線了!我們剛剛說,在格林威治的東邊時間會較快, 而在西邊時間會較慢,但是兩邊各走了 180 度之後就會碰頭啊!那不就剛好差了 24 小時嗎?沒錯啦! 所以才訂定為『國際換日線』啊!國際換日線剛好在太平洋上面,因此,如果你有坐飛機到美國的經驗應該會發現,咦! 怎麼出發的時間是星期六下午,坐了 13 個小時的飛機到了美國還是星期六!因為剛好通過了國際換日線, 日期減少了一天喔!如果反過來,由美國到台灣,日期就會多加一天喔! ^_^

15.1.2 什麼是夏季節約時間 (daylight savings)?

時區的概念先建立起來之後,現在再來談一談,那麼什麼是『夏季節約時間 (或稱日光節約時間)』?既然是『夏季節約時間』當然主要是與夏天有關啦! 因為地球在運行的時候是呈現一個傾斜角在繞太陽運轉的,所以才有春夏秋冬 (這個大家應該都知道啦),在夏天的時候,白天的時間會比較長,所以為了節約用電, 因此在夏天的時候某些地區會將他們的時間定早一小時,也就是說,原本時區是 8 點好了, 但是因為夏天太陽比較早出現,因此把時間向前挪,在原本 8 點的時候,訂定為該天的 9 點 (時間提早一小時)~如此一來, 我們就可以利用陽光照明,省去了花費電力的時間,因此才會稱之為夏季節約時間!

因為台灣實在是太小了,並沒有橫跨兩個時區,因此,夏季節約時間對我們來說,雖然還是有幫助啦! 不過,似乎沒有特別推行的樣子說~

15.1.3 Coordinated Universal Time (UTC)與系統時間的誤差

瞭解了一些時區的概念之後,這裡要談的是『什麼是正確的時間』。 在 1880 年代的時間標準是以 GMT 時間為主的,但是 GMT 時間是以太陽通過格林威治的那一刻來作為計時的標準。 然而我們都知道啊,地球自轉的軌道以及公轉的軌道並非正圓,加上地球的自轉速度好像有逐年遞減的問題, 所以這個 GMT 時間與我們目前計時的時間就有點不一樣了。(註1)

在計算時間的時候,最準確的計算應該是使用『原子震盪週期』所計算的物理時鐘了 (Atomic Clock, 也被稱為原子鐘),這也被定義為標準時間 (International Atomic Time)。而我們常常看見的 UTC 也就是 Coordinated Universal Time (協和標準時間)就是利用這種 Atomic Clock 為基準所定義出來的正確時間。例如 1999 年在美國啟用的原子鐘 NIST F-1, 他所產生的時間誤差每兩千年才差一秒鐘!真的是很準吶!這個 UTC 標準時間雖然與 GMT 時間放在同一個時區為基準, 不過由於計時的方式不同,UTC 時間與 GMT 時間有差不多 16 分鐘的誤差呢!(註2)

事實上,在我們的身邊就有很多的原子鐘,例如石英表,還有電腦主機上面的 BIOS 內部就含有一個原子鐘在紀錄與計算時間的進行吶!不過由於原子鐘主要是利用計算晶片 (crystal) 的原子震盪週期去計時的,這是因為每種晶片都有自己的獨特的震盪週期之故。 然而因為這種晶片的震盪週期在不同的晶片之間多多少少都會有點差異性,甚至同一批晶片也可能會或多或少有些許的差異 (就連溫度也可能造成這樣的誤差呢),因此也就造成了 BIOS 的時間會三不五時的給他快了幾秒或者慢了幾秒。

或許你會認為,BIOS 計時器每天快個五秒也沒有什麼了不起的,不過如果你再仔細的算一算,會發現,一天快五秒,那麼一個月快 2.5 分鐘,一年就快了 75 分鐘了!所以說,呵呵!時間差是真的會存在的!那麼如果你的電腦真的有這樣的情況, 那要怎麼來重新校正時間呢?那就需要『網路校時』(Network Time Protocol, NTP) 的功能了!底下我們就談一談那個 NTP 的 daemon 吧!

15.1.4 NTP 通訊協定

老實說, Linux 作業系統的計時方式主要是由 1970/01/01 開始計算總秒數,因此,如果你還記得 date 這個指令的話, 會發現它有個 +%s 的參數,可以取得總秒數,這個就是軟體時鐘。但,如同前面說的,電腦硬體主要是以 BIOS 內部的時間為主要的時間依據 (硬體時鐘),而偏偏這個時間可能因為 BIOS 內部晶片本身的問題,而導致 BIOS 時間與標準時間 (UTC) 有一點點的差異存在!所以為了避免主機時間因為長期運作下所導致的時間偏差,進行時間同步 (synchronize) 的工作就顯的很重要了!

  • 軟體時鐘:由 Linux 作業系統根據 1970/01/01 開始計算的總秒數;
  • 硬體時鐘:主機硬體系統上面的時鐘,例如 BIOS 記錄的時間;

那麼怎麼讓時間同步化呢?想一想,如果我們選擇幾部主要主機 (Primary server) 調校時間,讓這些 Primary Servers 的時間同步之後,再開放網路服務來讓 Client 端連線,並且提供 Client 端調整自己的時間,不就可以達到全部的電腦時間同步化的運作了嗎!那麼什麼協定可以達到這樣的功能呢?那就是 Network Time Protocol ,另外還有 Digital Time Synchronization Protocol (DTSS) 也可以達到相同的功能! 不過,到底 NTP 這個 daemon 是如何讓 Server 與 Client 同步他們的時間呢?

  1. 首先,主機當然需要啟動這個 daemon ,之後,
  2. Client 會向 NTP Server 發送出調校時間的 message ,
  3. 然後 NTP Server 會送出目前的標準時間給 Client ,
  4. Client 接收了來自 Server 的時間後,會據以調整自己的時間,就達成了網路校時咯!

在上面的步驟中你有沒有想到一件事啊,那就是如果 Client 到 Server 的訊息傳送時間過長怎麼辦?舉例來說,我在台灣以 ADSL 的 PC 主機,連線到美國的 NTP Server 主機進行時間同步化要求,而美國 NTP Server 收到我的要求之後,就發送當時的正確時間給我,不過, 由美國將資料傳送回我的 PC 時,時間可能已經延遲了 10 秒鐘去了!這樣一來,我的 PC 校正的時間是 10 秒鐘前的標準時間喔!此外,如果美國那麼 NTP 主機有太多的人喜歡上去進行網路校時了,所以 loading (負荷) 太重啦!導致訊息的回傳又延遲的更為嚴重!那怎麼辦?

為了這些延遲的問題,有一些 program 已經開發了自動計算時間傳送過程的誤差,以更準確的校準自己的時間!當然啦,在 daemon 的部分,也同時以 server/client 及 master/slave 的架構來提供使用者進行網路校時的動作!所謂的 master/slave 就有點類似 DNS 的系統咯!舉例來說,台灣的標準時間主機去國際標準時間的主機校時, 然後各大專院校再到台灣的標準時間校時,然後我們再到各大專院校的標準時間校時!這樣一來,那幾部國際標準時間主機 (Time server) 的 loading 就不至於太大,而我們也可以很快速的達到正確的網路校時的目的呢!台灣常見的 Time Server 有 (註3):

  • tick.stdtime.gov.tw
  • tock.stdtime.gov.tw
  • time.stdtime.gov.tw
  • clock.stdtime.gov.tw
  • watch.stdtime.gov.tw

至於 ntp 這個 daemon 是以 port 123 為連結的埠口 (使用 UDP 封包),所以我們要利用 Time server 來進行時間的同步更新時,就得要使用 NTP 軟體提供的 ntpdate 來進行 port 123 的連線喔!關於網路校時更多的說明,可以到 NTP 的官方網站 (註4) 上察看喔!

15.1.5 NTP 伺服器的階層概念

如前所述,由於 NTP 時間伺服器採用類似階層架構 (stratum) 來處理時間的同步化, 所以他使用的是類似一般 server/client 的主從架構。網路社會上面有提供一些主要與次要的時間伺服器, 這些均屬於第一階及第二階的時間伺服器 (stratum-1, stratum-2) ,如下所示:

由於這些時間伺服器大多在國外,所以我們是否要使用這些伺服器來同步化自己的時間呢? 其實如果台灣地區已經有標準時間伺服器的話,用那部即可,不需要連線到國外啦!浪費頻寬與時間啊! 而如前面提到的,台灣地區已經有標準的時間伺服器了,所以當然我們可以直接選擇台灣地區的 NTP 主機即可。

如果你評估一下,確定有架設 NTP 的需求時,我們可以直接選擇台灣地區的上層 NTP 來同步化時間即可。 舉例來說 tock.stdtime.gov.tw 這個國家單位的主機應該是比較適合的。一般來說,我們在進行 NTP 主機的設定時,都會先選擇多部上層的 Time Server 來做為我們這一部 NTP Server 的校正之用,選擇多部的原因是因為可以避免因為某部時間伺服器突然掛點時, 其他主機仍然可以提供我們的 NTP 主機來自我更新啊!然後我們的 NTP Server 才提供給自己的 Client 端更新時間。如此一來,國家單位的 tock.stdtime.gov.tw 負載才不會太大,而我們的 Client 也可以很快速的達到校時的動作!

Tips 鳥哥 其實 NTP 的階層概念與 DNS 很類似啦,當你架設一部 NTP 主機,這部 NTP 所向上要求同步化的那部主要主機為 stratum-1 時,那麼你的 NTP 就是 stratum-2 囉!舉例來說,如果我們的 NTP 是向台灣的 tock.stdtime.gov.tw 這部 stratum-2 的主機要求時間同步化,那我們的主機即為 stratum-3 ,如果還有其他的 NTP 主機向我們要求時間同步, 那麼該部主機則會是 stratum-4 啦!就這樣啊~ 那最多可以有幾個階層?最多可達 15 個階層喔!

15.2 NTP 伺服器的安裝與設定

NTP 伺服器也是一個很容易就可以架設成功的玩意兒,不過這個軟體在不同的 distribution 上面可能有不一樣的名稱, 你要作的其實就是將他安裝起來之後,規定一部上層 NTP 伺服器來同步化你的時間即可啊! 如果你只是想要進行你自己單部主機的時間同步化,別架設 NTP ,直接使用 NTP 用戶端軟體即可喔!

15.2.1 所需軟體與軟體結構

在 CentOS 6.x 上頭,你所需要的軟體其實僅有 ntp 這個玩意兒而已,請自行使用 rpm 去找找看,若沒有安裝,請利用 yum install ntp 即可啊!不過,我們還需要時區相關的資料檔案,所以你需要的軟體有:

  • ntp: 就是 NTP 伺服器的主要軟體啦,包括設定檔以及執行檔等等。
  • tzdata: 軟體名稱為『 Time Zone data 』的縮寫,提供各時區對應的顯示格式。

與時間及 NTP 伺服器設定相關的設定檔與重要資料檔有底下幾個:

  • /etc/ntp.conf: 就是 NTP 伺服器的主要設定檔,也是唯一的一個;

  • /usr/share/zoneinfo/: 由 tzdata 所提供,為各時區的時間格式對應檔。 例如台灣地區的時區格式對應檔案在 /usr/share/zoneinfo/Asia/Taipei 就是了!這個目錄裡面的檔案與底下要談的兩個檔案 (clock 與 localtime) 是有關係的喔!

  • /etc/sysconfig/clock: 設定時區與是否使用 UTC 時間鐘的設定檔。 每次開機後 Linux 會自動的讀取這個檔案來設定自己系統所預設要顯示的時間說!舉個例子來說, 在我們台灣地區的本地時間設定中,這個檔案內應該會出現一行『ZONE="Asia/Taipei"』的字樣, 這表示我們的時間設定檔案『要取用 /usr/share/zoneinfo/Asia/Taipei 那個檔案』的意思!

  • /etc/localtime: 這個檔案就是『本地端的時間設定檔』啦!剛剛那個 clock 檔案裡面規定了使用的時間設定檔 (ZONE) 為 /usr/share/zoneinfo/Asia/Taipei ,所以說這就是本地端的時間了,此時 Linux 系統就會將 Taipei 那個檔案複製一份成為 /etc/localtime ,所以未來我們的時間顯示就會以 Taipei 那個時間設定檔案為準。

至於在常用於時間伺服器與修改時間的指令方面,主要有底下這幾個啦:

  • /bin/date: 用於 Linux 時間 (軟體時鐘) 的修改與顯示的指令;

  • /sbin/hwclock: 用於 BIOS 時鐘 (硬體時鐘) 的修改與顯示的指令。 這是一個 root 才能執行的指令,因為 Linux 系統上面 BIOS 時間與 Linux 系統時間是分開的,所以使用 date 這個指令調整了時間之後,還需要使用 hwclock 才能將修改過後的時間寫入 BIOS 當中!

  • /usr/sbin/ntpd: 主要提供 NTP 服務的程式囉!設定檔為 /etc/ntp.conf

  • /usr/sbin/ntpdate: 用於用戶端的時間校正,如果你沒有要啟用 NTP 而僅想要使用 NTP Client 功能的話,那麼只會用到這個指令而已啦!

例題:
假設你的筆記型電腦安裝 CentOS 這套系統,而且選擇的時區為台灣。現在,你將有一個月的時間要出差到美國的紐約去, 你會帶著這個筆電,那麼到了美國之後,時間會不一致啊!你該如何手動的調整時間參數呢?
答:
因為時區資料檔在 /usr/share/zoneinfo 內,在該目錄內會找到 /usr/share/zoneinfo/America/New_York 這個時區檔。 而時區設定檔在 /etc/sysconfig/clock ,且目前的時間格式在 /etc/localtime ,所以你應該這樣做:
[root@www ~]# date
Thu Jul 28 15:08:39 CST 2011  <==重點是 CST 這個時區喔!

[root@www ~]# vim /etc/sysconfig/clock
ZONE="America/New_York"       <==改的是這裡啦!

[root@www ~]# cp /usr/share/zoneinfo/America/New_York /etc/localtime
[root@www ~]# date
Thu Jul 28 03:09:21 EDT 2011  <==時區與時間都改變了!
這個範例做完之後,記得將這兩個檔案改回來!不然以後你的時間都是美國時間啦!

接下來,我們先來談一談如何設計那個 /etc/ntp.conf 吧!

15.2.2 主要設定檔 ntp.conf 的處理

由於 NTP 伺服器的設定需要有上游伺服器的支援才行,因此請回頭參考一下 15.1.415.1.5 的介紹,這樣才能夠理解為何底下的設定是這樣呦!好了,我假設俺的 NTP 伺服器所需要設定的架構如下:

  • 我的上層 NTP 伺服器共有 tock.stdtime.gov.tw, tick.stdtime.gov.tw, time.stdtime.gov.tw 三部,其中以 tock.stdtime.gov.tw 最優先使用 (prefer);
  • 不對 Internet 提供服務,僅允許來自內部網域 192.168.100.0/24 的查詢而已;
  • 偵測一些 BIOS 時鐘與 Linux 系統時間的差異並寫入 /var/lib/ntp/drift 檔案當中。

好了,先讓我們談一談如何在 ntp.conf 裡面設定權限控制吧!

    利用 restrict 來管理權限控制

在 ntp.conf 檔案內可以利用『 restrict 』來控管權限,這個參數的設定方式為:

restrict [你的IP] mask [netmask_IP] [parameter]

其中 parameter 的參數主要有底下這些:

  • ignore: 拒絕所有類型的 NTP 連線;
  • nomodify: 用戶端不能使用 ntpc 與 ntpq 這兩支程式來修改伺服器的時間參數, 但用戶端仍可透過這部主機來進行網路校時的;
  • noquery: 用戶端不能夠使用 ntpq, ntpc 等指令來查詢時間伺服器,等於不提供 NTP 的網路校時囉;
  • notrap: 不提供 trap 這個遠端事件登錄 (remote event logging) 的功能。
  • notrust: 拒絕沒有認證的用戶端。

那如果你沒有在 parameter 的地方加上任何參數的話,這表示『該 IP 或網段不受任何限制』的意思喔!一般來說,我們可以先關閉 NTP 的使用權限,然後再一個一個的啟用允許登入的網段。

    利用 server 設定上層 NTP 伺服器

上層 NTP 伺服器的設定方式為:

server [IP or hostname] [prefer]

在 server 後端可以接 IP 或主機名稱,鳥哥個人比較喜歡使用 IP 來設定說!至於那個 perfer 表示『優先使用』的伺服器囉~有夠簡單吧!

    以 driftfile 記錄時間差異

設定的方式如下:

driftfile [可以被 ntpd 寫入的目錄與檔案]

因為預設的 NTP Server 本身的時間計算是依據 BIOS 的晶片震盪週期頻率來計算的,但是這個數值與上層 Time Server 不見得會一致啊!所以 NTP 這個 daemon (ntpd) 會自動的去計算我們自己主機的頻率與上層 Time server 的頻率,並且將兩個頻率的誤差記錄下來,記錄下來的檔案就是在 driftfile 後面接的完整檔名當中了!關於檔名你必須要知道:

  • driftfile 後面接的檔案需要使用完整路徑檔名;
  • 該檔案不能是連結檔;
  • 該檔案需要設定成 ntpd 這個 daemon 可以寫入的權限。
  • 該檔案所記錄的數值單位為:百萬分之一秒 (ppm)。

driftfile 後面接的檔案會被 ntpd 自動更新,所以他的權限一定要能夠讓 ntpd 寫入才行。在 CentOS 6.x 預設的 NTP 伺服器中,使用的 ntpd 的 owner 是 ntp ,這部份可以查閱 /etc/sysconfig/ntpd 就可以知道啦!

    keys [key_file]

除了以 restrict 來限制用戶端的連線之外,我們也可以透過金鑰系統來給用戶端認證, 如此一來可以讓主機端更放心了。不過在這個章節裡面我們暫不討論這個部分,有興趣的朋友可以參考 ntp-keygen 這個指令的相關說明喔!


根據上面的說明,我們最終可以取得這樣的設定檔案內容喔 (底下僅修改部分資料,保留大部分的設定值喔)!

[root@www ~]# vim /etc/ntp.conf
# 1. 先處理權限方面的問題,包括放行上層伺服器以及開放區網用戶來源:
restrict default kod nomodify notrap nopeer noquery     <==拒絕 IPv4 的用戶
restrict -6 default kod nomodify notrap nopeer noquery  <==拒絕 IPv6 的用戶
restrict 220.130.158.71   <==放行 tock.stdtime.gov.tw 進入本 NTP 伺服器
restrict 59.124.196.83    <==放行 tick.stdtime.gov.tw 進入本 NTP 伺服器
restrict 59.124.196.84    <==放行 time.stdtime.gov.tw 進入本 NTP 伺服器
restrict 127.0.0.1        <==底下兩個是預設值,放行本機來源
restrict -6 ::1
restrict 192.168.100.0 mask 255.255.255.0 nomodify <==放行區網來源

# 2. 設定主機來源,請先將原本的 [0|1|2].centos.pool.ntp.org 的設定註解掉:
server 220.130.158.71 prefer  <==以這部主機為最優先
server 59.124.196.83
server 59.124.196.84

# 3.預設時間差異分析檔案與暫不用到的 keys 等,不需要更動它:
driftfile /var/lib/ntp/drift
keys      /etc/ntp/keys

這樣就設定妥當了,準備來啟動 NTP 服務吧!

15.2.3 NTP 的啟動與觀察

設定完 ntp.conf 之後就可以啟動 ntp 伺服器了。啟動與觀察的方式如下:

# 1. 啟動 NTP 
[root@www ~]# /etc/init.d/ntpd start
[root@www ~]# chkconfig ntpd on
[root@www ~]# tail /var/log/messages  <==自行檢查看看有無錯誤

# 2. 觀察啟動的埠口看看:
[root@www ~]# netstat -tlunp | grep ntp
Proto Recv-Q Send-Q Local Address       Foreign Address  PID/Program name
udp        0      0 192.168.100.254:123 0.0.0.0:*        3492/ntpd
udp        0      0 192.168.1.100:123   0.0.0.0:*        3492/ntpd
udp        0      0 127.0.0.1:123       0.0.0.0:*        3492/ntpd
udp        0      0 0.0.0.0:123         0.0.0.0:*        3492/ntpd
udp        0      0 ::1:123             :::*             3492/ntpd
udp        0      0 :::123              :::*             3492/ntpd
# 主要是 UDP 封包,且在 port 123 這個埠口的啦!

這樣就表示我們的 NTP 伺服器已經啟動了,不過要與上層 NTP 伺服器連線則還需要一些時間, 通常啟動 NTP 後約在 15 分鐘內才會和上層 NTP 伺服器順利連接上。 那要如何確認我們的 NTP 伺服器有順利的更新自己的時間呢?你可以使用底下幾個指令來查閱喔 (請自行等待數分鐘後再以下列指令查閱):

[root@www ~]# ntpstat
synchronised to NTP server (220.130.158.71) at stratum 3
   time correct to within 538 ms
   polling server every 128 s

這個指令可以列出我們的 NTP 伺服器有跟上層連線否。由上述的輸出結果可以知道,時間有校正約 538 * 10^(-3) 秒,且每隔 64 秒會主動去更新時間喔!

[root@www ~]# ntpq -p
     remote           refid      st t when poll reach   delay   offset  jitter
==============================================================================
*tock.stdtime.go 59.124.196.87    2 u   19  128  377   12.092   -0.953   0.942
+59-124-196-83.H 59.124.196.86    2 u    8  128  377   14.154    7.616   1.533
+59-124-196-84.H 59.124.196.86    2 u    2  128  377   14.524    4.354   1.079

這個 ntpq -p 可以列出目前我們的 NTP 與相關的上層 NTP 的狀態,上頭的幾個欄位的意義為:

  • remote:亦即是 NTP 主機的 IP 或主機名稱囉~注意最左邊的符號
    • 如果有『 * 』代表目前正在作用當中的上層 NTP
    • 如果是『 + 』代表也有連上線,而且可作為下一個提供時間更新的候選者。
  • refid:參考的上一層 NTP 主機的位址
  • st:就是 stratum 階層囉!
  • when:幾秒鐘前曾經做過時間同步化更新的動作;
  • poll:下一次更新在幾秒鐘之後;
  • reach:已經向上層 NTP 伺服器要求更新的次數
  • delay:網路傳輸過程當中延遲的時間,單位為 10^(-3) 秒
  • offset:時間補償的結果,單位與 10^(-3) 秒
  • jitter:Linux 系統時間與 BIOS 硬體時間的差異時間, 單位為 10^(-3) 秒。

事實上這個輸出的結果告訴我們,時間真的很準了啦!因為差異都在 0.001 秒以內, 可以符合我們的一般使用了。另外,你也可以檢查一下你的 BIOS 時間與 Linux 系統時間的差異, 就是 /var/lib/ntp/drift 這個檔案的內容,就能瞭解到咱們的 Linux 系統時間與 BIOS 硬體時鐘到底差多久?單位為 10^(-6) 秒啦!

要讓你的 NTP Server/Client 真的能運作,在上述的動作中得注意:

  • 上述的 ntpstat 以及 ntpq -p 的輸出結果中,你的 NTP 伺服器真的要能夠連結上層 NTP 才行喔! 否則你的用戶端將無法對你的 NTP 伺服器進行同步更新的!重要重要!

  • 你的 NTP 伺服器時間不可與上層差異太多。舉例來說,鳥哥測試 NTP 伺服器約在 2011/7/28 下午, 如果我的伺服器時間原本是錯誤的 2010/7/28,足足差了一年,那麼上層伺服器恐怕就不會將正確的時間傳給我! 這時就會造成困擾了!

  • 伺服器防火牆在 UDP port 123 有沒有開啊?要特別注意的呢!

  • 等待的時間夠不夠長?鳥哥設定 NTP 等過最久的時間大約是一小時!你有等這麼久過否?

15.2.4 安全性設定

NTP 伺服器在安全的相關性方面,其實剛剛我們在 /etc/ntp.conf 裡面的 restrict 參數中就已經設定了 NTP 這個 daemon 的服務限制範圍了!不過,在防火牆 iptables 的部分,還是需要開啟連線監聽的啦!所以,在你的 iptables 規則的 scripts 當中,需要加入這一段 (我是以開放 192.168.100.0/24 這個網域作為範例的!)

[root@www ~]# vim /usr/local/virus/iptables/iptables.allow
iptables -A INPUT -i $EXTIF -p udp -s 192.168.100.0/24 --dport 123 -j ACCEPT

[root@www ~]# /usr/local/virus/iptables/iptables.rule

若還要開放其他的網段或者用戶端主機,請自行修改 /etc/ntpd.conf 以及你的防火牆機制咯!

15.3 用戶端的時間更新方式

上頭介紹了 NTP 伺服器的安裝與設定,如果我們僅有十部不到的主機時,老實說,實在沒有架設 NTP 伺服器的需求。 只要能夠在你的主機上頭以 NTP 用戶端軟體來進行網路校時就能夠同步化時間了,沒必要時時刻刻進行時間的校正吧!^_^! 但是,如果是類似一定要時間同步的叢集電腦群或登錄伺服器群,那就得要使用時間伺服器比較好囉!

15.3.1 Linux 手動校時工作: date, hwclock

先來複習一下前面談到的重點,那就是 Linux 作業系統當中其實有兩個時間,分別是:

  • 軟體時鐘: Linux 自己的系統時間,由 1970/01/01 開始記錄的時間參數
  • 硬體時鐘: 電腦系統在 BIOS 記錄的實際時間,這也是硬體所記錄的

在軟體時鐘方面,我們可以透過 date 這個指令來進行手動修訂,但如果要修改 BIOS 記錄的時間,就得要使用 hwclock 這個指令來寫入才行。相關的用法如下:

[root@clientlinux ~]# date MMDDhhmmYYYY
選項與參數:
MM:月份
DD:日期
hh:小時
mm:分鐘
YYYY:西元年

# 1. 修改時間成為 1 小時後的時間該如何是好?
[root@clientlinux ~]# date
Thu Jul 28 15:33:38 CST 2011

[root@clientlinux ~]# date 072816332011
Thu Jul 28 16:33:00 CST 2011
# 瞧!時間立刻就變成一個小時後了!
[root@clientlinux ~]# hwclock [-rw]
選項與參數:
-r :亦即 read ,讀出目前 BIOS 內的時間參數;
-w :亦即 write ,將目前的 Linux 系統時間寫入 BIOS 當中啊!

# 2. 查閱 BIOS 時間,並且寫入更改過的時間囉!
[root@clientlinux ~]# date; hwclock -r
Thu Jul 28 16:34:00 CST 2011
Thu 28 Jul 2011 03:34:57 PM CST  -0.317679 seconds
# 看一看,是否剛好差異約一個小時啊!這就是 BIOS 時間!

[root@clientlinux ~]# hwclock -w; hwclock -r; date
Thu 28 Jul 2011 04:35:12 PM CST  -0.265656 seconds
Thu Jul 28 16:35:11 CST 2011
# 這樣就寫入囉~所以軟體時鐘與硬體時鐘就同步啦!很簡單吧!

這樣可以瞭解了嗎?當我們進行完 Linux 時間的校時後,還需要以 hwclock 來更新 BIOS 的時間,因為每次重新開機的時候,系統會重新由 BIOS 將時間讀出來,所以, BIOS 才是重要的時間依據吶。

15.3.2 Linux 的網路校時

在 Linux 的環境當中可利用 NTP 的用戶端程式,亦即是 ntpdate 這支程式就能夠進行時間的同步化。 不過你要知道的是,因為 NTP 伺服器本來就會與上層時間伺服器進行時間的同步化, 所以在預設的情況下,NTP 伺服器不可以使用 ntpdate !也就是說 ntpdate 與 ntpd 不能同時啟用的。 所以你不要在 NTP server 上頭執行這個指令呦!我們就來看看如何處理吧!

[root@clientlinux ~]# ntpdate [-dv] [NTP IP/hostname]
選項與參數:
-d :進入除錯模式 (debug) ,可以顯示出更多的有效資訊。
-v :有較多訊息的顯示。

[root@clientlinux ~]# ntpdate 192.168.100.254
28 Jul 17:19:33 ntpdate[3432]: step time server 192.168.100.254 offset -2428.396146 sec
# 最後面會顯示微調的時間有多少 (offset),因為鳥哥這部主機時間差很多,所以秒數...

[root@clientlinux ~]# date; hwclock -r
四  7月 28 17:20:27 CST 2011
西元2011年07月28日 (週四) 18時19分26秒  -0.752303 seconds
# 知道鳥哥想要表達什麼嗎?對啊!還得 hwclock -w 寫入 BIOS 時間才行啊!

[root@clientlinux ~]# vim /etc/crontab
# 加入這一行去!
10 5 * * * root (/usr/sbin/ntpdate tock.stdtime.gov.tw && /sbin/hwclock -w) &> /dev/null

使用 crontab 之後,每天 5:10 Linux 系統就會自動的進行網路校時囉!相當的簡易吧!不過,這個方式僅適合不要啟動 NTP 的情況。如果你的機器數量太多了,那麼用戶端最好也啟動一下 NTP 服務!透過 NTP 去主動的更新時間吧! 如何達成這個動作呢?也很簡單啊,修改 /etc/ntp.conf 即可:

[root@clientlinux ~]# ntpdate 192.168.100.254
# 由於 ntpd 的 server/client 之間的時間誤差不允許超過 1000 秒,
# 因此你得先手動進行時間同步,然後再設定與啟動時間伺服器呦!

[root@clientlinux ~]# vim /etc/ntp.conf
#server 0.centos.pool.ntp.org
#server 1.centos.pool.ntp.org
#server 2.centos.pool.ntp.org
restrict 192.168.100.254  <==放行伺服器來源!
server 192.168.100.254    <==這就是伺服器!
# 很簡單,就是將原本的 server 項目註解,加入我們要的伺服器即可

[root@clientlinux ~]# /etc/init.d/ntpd start
[root@clientlinux ~]# chkconfig ntpd on

然後取消掉 crontab 的更新程序,這樣你的 client 電腦就會主動的到 NTP 伺服器去更新囉!也是輕鬆愉快啊! 不過針對用戶端來說,鳥哥還是比較習慣使用 crontab 的方式來處理就是了。

15.3.3 Windows 的網路校時

或許你一直都沒發現,其實 Windows 在預設的情況當中,已經幫我們處理了網路校時的工作喔!不管你願不願意... 你可以將滑鼠的指標指在工作列右下角的時間以如下的方式來查閱一下網路時間伺服器的設定:

Windows 7 提供的網路校時功能
圖 15.3-1、Windows 7 提供的網路校時功能

點選上圖中的『變更日期與時間設定值』,出現如下圖示:

Windows 7 提供的網路校時功能
圖 15.3-2、Windows 7 提供的網路校時功能

如上所示,你可以自行填寫台灣的時間伺服器來對應時間,當然也可以填寫你自己的時間伺服器啊! 之後系統就會主動的上網去更新時間了。不過,這是 Windows XP 之後的視窗系統才有的功能,如果是比較早期的 Windows , 例如 Windows 95/2000 預設是沒有這個功能的。不過也沒有關係, 因為國家頻率與時間標準實驗室 (http://www.stdtime.gov.tw/) 也有提供一個用戶端軟體喔!連結資料如下:

你可以下載,直接執行他就知道如何處理了,因為是全中文介面的圖形化軟體嘛!

15.4 重點回顧

  • 地球共有 24 個時區,而以格林威治時間 (GMT) 為標準時間;
  • 台灣本地時間為 GMT + 8 小時;
  • 最準確的時間為使用原子鐘 (Atomic clock) 所計算的,例如 UTC (Coordinated Universal Time) 就是一例;
  • Linux 系統本來就有兩種時間,一種是 Linux 以 1970/01/01 開始計數的系統時間,一種則是 BIOS 記載的硬體時間;
  • Linux 可以透過網路校時,最常見的網路校時為使用 NTP 伺服器,這個服務啟動在 udp port 123;
  • 時區檔案主要放置於 /usr/share/zoneinfo/ 目錄下,而本地時區則參考 /etc/localtime;
  • NTP 伺服器為一種階層式的服務,所以 NTP 伺服器本來就會與上層時間伺服器作時間的同步化, 因此 nptd 與 ntpdate 兩個指令不可同時使用;
  • NTP 伺服器的連線狀態可以使用 ntpstat 及 ntpq -p 來查詢;
  • NTP 提供的用戶端軟體為 ntpdate 這個指令;
  • 在 Linux 下想要手動處理時間時,需以 date 設定時間後,以 hwclock -w 來寫入 BIOS 所記錄的時間。
  • NTP 伺服器之間的時間誤差不可超過 1000 秒,否則 NTP 服務會自動關閉。

15.5 本章習題

  • 什麼是 GMT (格林威治) 時間與 UTC 時間?
    由於地球是圓的,所以同一時間點上,在地球共可分為 24 個時區,其中,我們以歐洲的格林威治時間為一個對照的依據,這個即是 GMT 時間。台灣時間比 GMT 時間快了 8 小時。至於 UTC 時間則是由原子鐘所計算的時間,這個時間是相當的準確的, 主要仍以格林威治時間為時區!
  • Linux 系統的所有時區檔案放置哪一個目錄底下?
    所有的時區檔案放置於:/usr/share/zoneinfo 底下!至於系統時區的設定檔則在 /etc/sysconfig/clock 與 /etc/localtime 喔!
  • 我的 Linux 主機本來放置在日本東京,現在想將他拿到台灣來運作,不過因為日本與台灣有一個小時的時差, 所以我的時間應該需要經過調整才行。不過,因為我的 BIOS Time 主要是依據 UTC 時間來設定的,所以似乎只要更動時區參數即可。請問我該如何設定時區,好讓我的 Linux 主機能夠顯示正確的時間?
    先將 /etc/localtime 刪除,然後將 /usr/share/zoneinfo/Asia/Taipei 這個檔案複製成為 /etc/localtime 即可!
  • 目前 Linux 系統上面的時間伺服器主要是以 NTP 為主,請問這個 daemon 的主要設定檔放在哪裡,而該設定檔中,針對上層 time server 的設定參數為何?而那個 driftfile 參數是幹嘛用的?
    在 /etc/ntp.conf 這個檔案當中,至於上層 time server 的設定參數為 server 啊!那個 driftfile 則是用來做為『時間差額』的計算的!該參數後面接的是一個完整路徑的檔名,該檔案裡面的數值單位為百萬分之一(ppm)。
  • 請問 ntptrace 的功能為何?
    可以用來追蹤上層 time server 的連線時間與目前時間!
  • 我以 date 更新了我 Linux 上面的時間後,該如何將時間數據寫入 BIOS 內?
    必須利用 hwclock 這個程式來寫入,利用 hwclock -w 寫入 BIOS
  • 在 Linux 上面如何進行網路校時?
    最簡單的方法即是使用『 ntpdate time.servers.ip && hwclock -w 』即可!

15.6 參考資料與延伸閱讀

修改歷史:
  • 2003/08/21:首次完成
  • 2006/12/05:將舊的文章移動到此處
  • 2006/12/08:將文章作了個版面修改,同時將一些資料再加強一些。並補充一些額外的查閱 NTP 的指令。
  • 2009/04/28:將 offset 的時間單位寫錯了,應該是 ms 不是 us ,亦即 10^(-3) 秒,而不是 10^(-6) 秒。抱歉。
  • 2011/02/18:由讀者李濤兄提供的資料,發現原本 ntpq 的說明反了! * 應為作用中,而 + 是較佳的另一部候選主機。
  • 2011/03/16:將舊的基於 CentOS 4.x 的文章移動到 此處
  • 2011/03/18:將一些重複性的資料彙整一下,不需要的部分就刪除掉了~
  • 2011/07/28:將基於 CentOS 5.x 的文章移動到此處
  • 2012/06/26:將 ntpq 的時間單位寫錯了,應該是 ms 不是 us ,亦即 10^(-3) 秒,而不是 10^(-6) 秒。抱歉。
2003/08/21以來統計人數
計數器
其他連結
環境工程模式篇
鳥園討論區
鳥哥舊站

今日 人數統計
昨日 人數統計
本月 人數統計
上月 人數統計