1. 程式人生 > >關於DHCP協議和dhcpd配置檔案的講解

關於DHCP協議和dhcpd配置檔案的講解

在瞭解了DHCP協議的基礎內容後,我們來對它的dhcpd配置檔案的相關內容進行一下了解。首先我們來了解一下這方面的基礎概念。然後再對它的應用進行一下分析。

名稱

dhcpd.conf - dhcpd配置檔案

描述

dhcpd.conf 檔案包括ISC DHCP的dhcpd的配置資訊。

dhcpd.conf檔案是一個普通格式的ASCII碼文件, 它由內建的遞迴解析器解釋。

dhcpd.檔案可能會包含許多額外的tab和空格、空行,它們的目的是讓檔案更容易閱讀。 其中的關鍵字對大小寫不敏感。註釋語句可以放在任何位置(除了引號中)註釋語句用# 開頭,這一行結束時註釋語句自然結束。

檔案包括一組語句,語句在一對大括號中,包含引數和宣告。

引數語句說明如何做一件事(例如,租期是多長時間),或者是否做一件事情。 (例如, dhcpd 是否為未知客戶提供地址),或者給客戶提供哪種引數(例如,使用閘道器220.177.244.7)。

宣告用來描述網路的拓撲結構、網路上的客戶,提供可以為客戶端分配的地址,或者對某個客戶端組應用組(group)引數。在任何組引數中,所有的這些組引數必須比使用這些組引數的語句先出現。

網路宣告包含多子網的網路(有些地方譯為:超網,但超網太難理解了,這裡叫“多子網網路”)和子網的拓撲宣告。對於子網的客戶端被動態分配地址,子網宣告中必須有一個range宣告語句。對於靜態分配的地址,或者是已知客戶的安裝,每個客戶端都必須使用一個host宣告語句。如果一個引數應用到一組宣告中,這些宣告並不只與某個子網相關,可以定義一個“組引數”。

對每一個要服務的子網,每個dhcp協議的伺服器連線的子網,都必須有一個子網宣告,用來告訴dhcpd如何處理那個子網上的地址。即使一個子網不需要分配任何地址,也需要一個子網宣告。

一些物理網路上不只有一個IP子網存在,例如,如果一個網路需要一個8位的子網,但是當業務發展使總的節點數超過了254臺,就需要增加一個8位的子網。這時,就增加了一個新的物理網路,這種情況下,2個網路的子網宣告必須包含在一個“多子網網路宣告(超級作用域)”中。

有些網路的客戶端不只有一個子網,可能會為同一子網中一些客戶端分配的一些引數與其它的客戶端不同。這樣的使用者可以使用host語句來定義,一些引數也可以定義在“組引數”語句中,它被這些客戶端共同呼叫。對於需要根據不同情況獲得不同地址的客戶端,可能會使用“類宣告(class declarations)”和“條件宣告(conditional declarations)”語句,這樣可以根據客戶端傳送的資訊來決定分配給客戶端的引數。

當一個客戶端啟動時,伺服器先檢視是否有匹配客戶端的host語句,如果沒有,再看是否有匹配的“類宣告(class declarations)”語句,接著檢視是否有“池pool”匹配,“子網subnet”匹配和“多子網網路(超級作用域)shared-net-work”匹配。(根據這些匹配,)將符合這個客戶端的引數提供給它。每種引數都不會被分析第2次,如果它們出現了2次或2次以上,那麼會使用那個最精確出現的地方。

dhcpd首先查詢客戶端是否有包含固定IP地址的host語句,這個地址要在客戶端啟動的那個子網中,或者“多子網網路”中,如果沒有對應的host語句匹配,那就查詢非固定地址的宣告。

例如:

一個典型的dhcpd.conf 檔案將會象下面這樣:

  1. global parameters...  
  2. subnet 204.254.239.0 netmask 255.255.255.224 {  
  3. subnet-specific parameters...  
  4. range 204.254.239.10 204.254.239.30;  
  5. }  
  6. subnet 204.254.239.32 netmask 255.255.255.224 {  
  7. subnet-specific parameters...  
  8. range 204.254.239.42 204.254.239.62;  
  9. }  
  10. subnet 204.254.239.64 netmask 255.255.255.224 {  
  11. subnet-specific parameters...  
  12. range 204.254.239.74 204.254.239.94;  
  13. }  
  14. group {  
  15. group-specific parameters...  
  16. host zappo.test.isc.org {  
  17. host-specific parameters...  
  18. }  
  19. host beppo.test.isc.org {  
  20. host-specific parameters...  
  21. }  
  22. host harpo.test.isc.org {  
  23. host-specific parameters...  
  24. }  

圖 1

注意檔案的開始,它是全域性引數放置的地方,可能會是:

組織的域名,DNS伺服器的地址(如果這個伺服器對整個網路都是一樣的)和其它一些。比如:

  1. option domain-name "isc.org";  
  2. option domain-name-servers ns1.isc.org, ns2.isc.org; 

圖 2

如圖2中所示,可以使用DNS伺服器的名稱而不使用它的IP地址,如果指定不只一個DNS伺服器地址,那麼只要有可能,所有地址都會提供給客戶端。

每個子網都要指明的最可能必須的引數是router,如圖1所示。因此對於第一個子網,它就應該是這個樣子的

  1. option routers 204.254.239.1; 

注意這裡的地址是數字形式的,如果每個閘道器都有域名,這就不是必須的,使用域名也是合法的。然而,很多情況下,多個閘道器只有一個域名,這樣就不能使用域名了。

在圖1中,有一個group 語句,它為一組host語句zappo,beppo和harpo提供了通用的引數。如你所見,這些主機都在test.isc.org這個域裡,這樣它在“組引數”中指明就會覆蓋全域性設定的引數:

  1. option domain-name "test.isc.org"; 

而且,指明它們的域,可能用在測試機器中,如果我們要測試DHCP協議的租約機制,可以在這裡設定比預設值更短的租約:

  1. max-lease-time 120;  
  2. default-lease-time 120; 

你可能注意到有些引數以option 關鍵字開頭,有些不。以option 關鍵字開頭的語句對應實際的DHCP選項,不以option關鍵字開頭的選項控制服務端(例如,租期) 或客戶端的選項不在DHCP協議中(例如,伺服器名或檔名)

在圖1中,每個host 都有指定的引數,它會包含象hostname選項,要上傳的檔名(filename 引數),還有要上傳的伺服器的地址(next-server 引數)。通常,任何引數都可以在任何可以出現的地方出現,並且按照引數出現位置確定應用範圍。

假設你的環境中有許多沒有CD的X終端,這些終端有不同的型號,你想為每種型號確定一個啟動檔案,一種方法是給每個伺服器和組都使用host語句:

  1. group {  
  2. filename "Xncd19r";  
  3. next-server ncd-booter;  
  4. host ncd1 { hardware ethernet 0:c0:c3:49:2b:57; }  
  5. host ncd4 { hardware ethernet 0:c0:c3:80:fc:32; }  
  6. host ncd8 { hardware ethernet 0:c0:c3:22:46:81; }  
  7. }  
  8. group {  
  9. filename "Xncd19c";  
  10. next-server ncd-booter;  
  11. host ncd2 { hardware ethernet 0:c0:c3:88:2d:81; }  
  12. host ncd3 { hardware ethernet 0:c0:c3:00:14:11; }  
  13. }  
  14. group {  
  15. filename "XncdHMX";  
  16. next-server ncd-booter;  
  17. host ncd1 { hardware ethernet 0:c0:c3:11:90:23; }  
  18. host ncd4 { hardware ethernet 0:c0:c3:91:a7:8; }  
  19. host ncd8 { hardware ethernet 0:c0:c3:cc:a:8f; }  

地址池

“池”語句(pool)用來定義一個地址池,即便是在同一個網段或者子網,也可以定義幾個池,系統將通過“池”來區分它們。例如,你可能想提供一大段地址分配給DHCP客戶端時同時提供很短的租約的一小段地址,用來給未知客戶。如果有防火牆,你可能會安排一段地址池能上網,另一個地址池不能上網,這可以鼓勵使用者註冊到DHCP協議的系統中來,也就需要建立兩個地址池:

  1. subnet 10.0.0.0 netmask 255.255.255.0 {  
  2. option routers 10.0.0.254;  
  3. # Unknown clients get this pool.  
  4. pool {  
  5. option domain-name-servers bogus.example.com;  
  6. max-lease-time 300;  
  7. range 10.0.0.200 10.0.0.253;  
  8. allow unknown-clients;  
  9. }  
  10. # Known clients get this pool.  
  11. pool {  
  12. option domain-name-servers ns1.example.com, ns2.example.com;  
  13. max-lease-time 28800;  
  14. range 10.0.0.5 10.0.0.199;  
  15. deny unknown-clients;  
  16. }  

上面這個例子中,已知客戶和未知客戶在相同的子網中,也可能將已知和未知客戶分配在不同的子網中,或者在“多子網層次(超級作用域)”,這樣地址池的範圍可能跨越不同的子網。正如前面的例子,地址池可以允許或拒絕一個控制使用者存取的組,這個組名前面要有allow或 deny 關鍵字。

如果一個池有一個允許列表,只有匹配的客戶端才可以獲得地址池的地址,如果這個池有一個拒絕列表,只有不匹配的客戶端才可以獲得池中的地址,如果同時存在允許和拒絕列表,那麼只有在允許列表並且不在拒絕列表中的客戶端才可以獲得池中的地址。

動態地址分配

地址分配實際只在客戶端在初始狀態並且傳送一個 DHCPDISCOVER資訊時完成。如果客戶端認為它有一個有效的租約並且傳送了一個DHCPREQUEST資訊來初始化或者更新租約,伺服器就只有3個選擇:(1)它可以忽略DHCPREQUEST資訊,並且返回一個DHCPNAK 資訊來告訴客戶端,要求客戶端停止使用這個地址,(2)或者傳送一個DHCPACK資訊,告訴客戶端繼續再使用這個地址一段時間,如果伺服器找到客戶端要求的地址,並且這個地址對於這個客戶也是可用的,伺服器會發送一個DHCPACK資訊,如果這個地址已經不能用了,客戶端就不能使用它,此時伺服器將會發送一個DHCPNAK資訊,(3)如果伺服器不知道這個地址,它會先保持沉默,除非這個地址對於客戶端依附的地址段是不正確的,這種情況下伺服器會發送一個DHCPNAK,即便它完全不知道這個地址。

如果有一個host語句定義了客戶端,同時host語句中包含了固定地址(fixed-address),這個IP地址對於客戶端實際連線的網段也是合法的,此時DHCP協議的伺服器不動態分配地址,而是傳送host語句指明的地址。如果此時使用者傳送了DHCPREQUEST資訊來獲得其它地址,伺服器會迴應一個DHCPNAK資訊,來拒絕為使用者分配其它地址。

當一個DHCP伺服器為客戶端分配一個新的地址時(記住,這隻發生在客戶端傳送DHCPDISCOVER資訊時),它首先查詢lease檔案,看客戶機是否存在一個有效的地址租約,或者此客戶機原來是否有一個地址(這個地址已經過期),如果有,伺服器就會檢查那個地址,看客戶端是否被允許使用這個地址,如果客戶端已經不被允許使用這個地址(通常是客戶機從另外一個子網登入了,或者此地址被其它客戶端佔用),並且伺服器lease檔案中顯示原來的租約還存在,伺服器就釋放這個租約,事實上,此時是客戶端傳送的DHCPDISCOVER資訊,它已經證明客戶端實際並沒有使用這個租約。如果沒有找到存在的租約,或者客戶端被強迫接收一個已經存在的租約,那麼伺服器就會查詢客戶端所在網段的地址池,找一個允許客戶端使用而又沒有使用的地址,它會按順序遍歷每個地址池(所有地址池外的“範圍”range定義語句都組成一個沒有允許列表的單獨的池)。如果地址池的允許列表允許客戶端得到一個池中的地址,這個地址池會被檢查是否有可用的地址,如果有,客戶端將會得到這個地址;否則,會檢查下一個地址池。如果一直都沒有找到可用的地址,伺服器就不傳送迴應。如果找到一個地址,這個地址以前從未被任何客戶端使用過,這個地址將立即分配給這個客戶,如果這個地址曾經分配給另一個客戶端,伺服器會嘗試查詢一個從未分配的地址給客戶端。

DHCP伺服器使用雜湊表(hash table)來產生一組可用的IP地址,這意味著地址不以任何特定的順序存放,這樣也就不能預測DHCP伺服器下一個要分配的地址。前一個版本的ISC DHCP伺服器使用降序來分配地址,現在不是了,並且在這個版本里也沒有辦法配置伺服器分發地址的順序 (ISC DHCP 3)。

防止IP地址衝突

DHCP伺服器在分配IP地址前檢查它們是否被使用來防止衝突。它通過向準備分配的IP地址傳送ICMP Echo請求資訊來完成,如果1秒內沒有接收到ICMP Echo reply資訊,就假定這個地址是可用的。這隻對在range語句中指明的租約,並且租約被DHCP伺服器認為可用時有效。例如,DHCP伺服器或者它的熱備機沒有列出這個租約在使用中。如果收到ICMP Echo迴應,DHCP伺服器會假定出現了配置錯誤――IP地址被網路上的主機使用了,然後它標記這個地址為“廢棄地址”,不再把它分配給客戶端。如果DHCP協議的客戶端試圖得到一個地址,但是卻沒有可用的地址,伺服器會(隨機)標記一個“廢棄地址”為“可用”,然後向這個地址傳送同樣的ICMP Echo 請求,如果沒有得到 ICMP Echo reply迴應,這個地址就會分配給這個客戶。

如果要收回的第一個IP地址是可用的,DHCP伺服器不會去迴圈使用“廢棄地址”。而且,當下一個客戶的DHCPDISCOVER資訊到達時,它會用相同的方法開始一個新的分配,並且嘗試分配一個新的IP地址。