1. 程式人生 > >DHCP 協議如何工作?

DHCP 協議如何工作?

原文

How does DHCP work?
Posted 2018-10-09 to Ben Burwell’s blog

譯文

DHCP(Dynamic Host Configuration Protocol)是大多數網路的組成部分,從小型家庭網路到服務於數千個裝置的校園網路。 我最近意識到我對它的運作方式沒有充分的理解。 我知道在加入網路時,DHCP 用於從中央伺服器獲取IP地址,但不清楚它是如何進行協商。 沒有IP地址的機器如何與它甚至都不知道地址的伺服器通訊?

為了解更多資訊,我開始使用 Wireshark 抓包並且將計算機連線到網路來檢視發生了什麼。 我立即發現 DHCP 是 Bootstrap 協議(也稱為 BOOTP )的一部分,它通過 UDP / IP 傳輸。 DHCP 伺服器在埠 67 上讀寫,而 DHCP 客戶端在埠 68 上讀寫。在客戶端獲取 IP 地址之前,它使用 0.0.0.0

作為其傳輸的資料包的源地址,並將其資料包傳送到廣播地址 255.255.255.255

對於這個簡單情況,我發現獲取IP地址涉及四條訊息:發現,提供,請求和 ACK 。 在高級別的客戶端廣播對地址的請求, DHCP 伺服器響應提議,客戶端基於其接收的提議發出請求,最後 DHCP 伺服器確認該請求。

Step 1: 發現

客戶端從 0.0.0.0:68 傳送UDP廣播包到 255.255.255.255:67 。 這是 BOOTP Discover 訊息,其中包含有關從網路的權威 DHCP 伺服器請求資訊的詳細資訊。 在我觀察到的情況下,要求提供以下資訊:

  • 子網掩碼
  • 無類靜態路由
  • 路由器
  • DNS 伺服器
  • 域名
  • 代理自動發現
  • LDAP 伺服器
  • NetBIOS 名稱伺服器
  • NetBIOS 節點型別

請求DHCP租用時間為90天,還包括我的DHCP客戶端識別符號(MAC地址)和主機名。

在我觀察到的情況下,在傳送的第一個發現數據包在 1.125 秒後沒有響應時,傳送了第二個發現數據包。 由於 UDP 不保證傳遞,因此基本重放機制將成為處理丟棄資料包的協議的一部分。 雖然 TCP 使用序列號來正確地對資料包進行排序,但 BOOTP 似乎使用了一個有些令人驚訝的度量標準:其資料頭包含 “seconds elapsed” 欄位,第一個被發現的資料包設定為 0 , 1.125 秒後設置為 1 。

Step 2: 提供

伺服器傳送包含 DHCP Offer 訊息的 192.168.1.1:67192.168.1.2:68 的 UDP 資料包。 我們可以通過以下幾種方式判斷這是提供給我們的:

  • BOOTP Transaction ID欄位設定為我們在Discover資料包中傳送的值
  • BOOTP訊息中的客戶端MAC地址欄位設定為我們的
  • 在乙太網層,目標地址也設定為我們的MAC地址

在此提供的資訊中,我們會收到在 Discover 資料包中提出的一些問題的回覆。 在這種情況下,我們的租約時間為3600 秒 (也就是一小時,遠低於我們要求的90天)。 我們被要求在30 分鐘後更新,在 52 分 30 秒後重新繫結,並給出一個 255.255.255.0 的網路掩碼。 我們還被告知路由器/ DNS 伺服器的地址 192.168.1.1 並提供域名 home(因此我們機器的“FQDN”將是 <hostname> .home )。

Step 3: 請求

現在我們收到了提供資訊,我們為此做一個請求。 這主要涉及重複初始請求,再次從 0.0.0.0:68 傳送到 255.255.255.255:67 。 此外,該訊息包括 “Requested IP” 欄位,該欄位的IP地址來自上一步的提供資訊。

Step 4: ACK

最後,DHCP 伺服器確認我們的請求。 這樣就完成了 IP 地址獲取過程。 伺服器重申提供的正確引數,包括重新繫結和續訂期,網路掩碼等。


一些觀察結果表明:看到 UDP 用於此協議而不是 TCP 是有意義的,因為 TCP 是面向連線的,並且在此過程開始時我們不知道伺服器的地址(也不是我們自己的地址)。 很容易想到通過建立一個提供具有衝突IP地址的虛假租約的欺詐DHCP伺服器,能夠在網路上造成嚴重破壞。

憑藉我對 DHCP 功能的基本知識,我想更好地理解我在實驗過程中遇到的一些問題。 例如,“重新繫結”和“續約”之間有什麼區別? 使用“seconds elapsed”作為一種序列號的原因是什麼? 我的下一站找到答案的是 IETF RFC 。

在撰寫本文時,DHCP RFC 已經進行了三次迭代,還有一些其他擴充套件/選項 RFC。 這三個都是由巴克內爾大學的 Ralph Droms 編寫的。 前兩個(RFC 1531 和 RFC 1541 )於 1993 年 10 月釋出,最新版本 RFC 2131 於 1997 年 3 月釋出。對於歷史背景,我想了解整個版本中發生的變化,因此我運行了 $ diff rfc1531.txt rfc1541.txt(這是我喜歡在本地使用RFC儲存庫的時間之一。在 RFC 1531 和 RFC 1541 之間似乎沒有任何協議更改,只是一些格式和措辭更改。執行差異 RFC 1531 和 RFC 2131 產生了相當大的輸出,我並不急於閱讀,但方便的是,RFC 2131 的 1.1 節被稱為“ RFC 1541 的變更”。1997 年的變化描述如下:

本文件更新了 RFC1541 中出現的 DHCP 協議規範。 添加了新的 DHCP 訊息型別 DHCPINFORM ; 有關詳細資訊,請參見第 3.4,4.3 和 4.4 節。 用於將 DHCP 客戶端標識到 DHCP 伺服器的分類機制已擴充套件為包括 4.2 和 4.3 節中定義的“供應商”類。 已刪除最短租約時間限制。 最後,由於在 DHCP 互操作性測試中獲得的經驗,已經進行了許多編輯性修改以澄清文字。

有趣的是,我們習慣在 RFC 2119(必須,必須,不需要等)中定義的術語在文件中有明確定義。 經過仔細檢查,RFC 2119 也於 1997 年 3 月釋出!

認真考慮讓我沉思的問題,我瞭解到“更新”是指客戶試圖通過重新關聯最初授予它的伺服器來續訂租約。 如果無法聯絡伺服器,或拒絕續訂租約,則客戶端進入“重新繫結”狀態,在該狀態下,客戶端嘗試聯絡任何 DHCP 伺服器以續訂其租約或獲取新租約。

我只能在“秒”欄位中找到一個實際用途的提及(第15頁):

為了幫助確保任何 BOOTP 中繼代理將 DHCPREQUEST 訊息轉發到接收原始 DHCPDISCOVER 訊息的同一組 DHCP 伺服器, DHCPREQUEST 訊息必須在 DHCP 訊息頭的 ‘secs’ 欄位中使用相同的值併發送到相同的 IP 廣播地址作為原始 DHCPDISCOVER 訊息。

我注意到有很多部分都有例如“ DHCP 伺服器只有在具有本地管理許可權的情況下才可以擴充套件客戶端的租約”(強調新增)的文字。 但是,如果有人要在網路上放置一個流氓 DHCP 伺服器,那個沒有“本地管理許可權”的人呢? 通過建立一個流氓 DHCP 伺服器可能會造成一些破壞,儘管可能並不像看起來那麼容易。 由於 DHCP 租約通常持續一段時間(數小時或數天),因此現有客戶端可能不會受到新伺服器出現的長時間影響。 此外,由於繫結機制,當客戶端需要更新其租約時,它直接向伺服器傳送單播訊息,它最初獲得租約,而不是立即訴諸廣播 DHCPDISCOVER 訊息。

由於 DHCP 通常用於連續的物理網段,因此可能無法始終使用防火牆來阻止到伺服器埠的流量(67)。 這需要某種第 2 層防火牆,我確信它存在,但似乎沒有被廣泛部署(或推薦)。 當然可以在第 3 或 第 4 層防火牆上設定規則,以阻止未授權充當 DHCP 伺服器的機器上的埠 67 的流量,以防止惡意伺服器在其物理段之外產生任何影響。

總結:

  • Wireshark 是一個很好的學習工具。
  • RFC 從技術和歷史角度來看都具有教育意義。
  • 現在我知道了 DHCP 是如何更深入地工作的。