兩種位址,兩種不同的工作
到這裡,這個段落已經幫你搭出一個能動的 LAN:一個乙太網路框架一跳一跳地載著資料,一台交換器學會了每個人坐在哪、只把框架轉發到對的埠,而一個 VLAN 還能把一台交換器切成好幾個邏輯上的 LAN。但有個安靜的謎題一直藏在這一切底下。每台裝置都有兩個截然不同的位址,住在兩個不同的層,而我們目前看過的東西都還沒解釋它們是怎麼連起來的。
第一個是 MAC 位址,一個 48 位元的數字,像 a0:b1:c2:d3:e4:f5,在出廠時就燒進了網路卡裡。它屬於連結層,是交換器用來在本地線路上投遞框架時所讀的東西。把它想成蓋在裝置背面的永久序號——全球唯一,但它完全沒告訴你這台裝置在世界上的哪個位置。第二個是像 192.168.1.42 的 IP 位址,它屬於網路層,根據你插進了哪個網路而被分配。IP 是郵遞地址;MAC 則是刻在信箱上的名字。
關鍵就在這裡。當你的筆電想送一個封包到 192.168.1.1,軟體知道目的地的 IP,但線路上的交換器根本不在乎 IP——它只轉發位址寫成某個 MAC 的框架。所以要真的把封包放上 LAN,你的筆電必須先回答一個問題:哪一個 MAC 位址屬於 192.168.1.1?這一次翻譯——從一個網路層位址往下換成一個連結層位址——就是 ARP 的全部工作。而更前面的問題——你的筆電當初是怎麼拿到一個能用的 IP、又怎麼知道 192.168.1.1 存在——則是 DHCP 的工作。
DHCP:一抵達就被遞上你的設定
一台剛接上 LAN 的全新裝置什麼都不知道:沒有 IP 位址、不知道本地的位址範圍是哪一段、不知道出口在哪。它就像一位走進大飯店、卻沒有房卡也沒有地圖的客人。DHCP,動態主機設定協定,就是那個櫃台——在一段短短的往返裡,把客人需要的一切都遞給他:通常包括一個可用的 IP 位址、那個用來判斷哪些位址算本地的子網路遮罩、那個通往外面世界之門的閘道位址,以及一台 DNS 伺服器的位址。
但這個櫃台比喻藏了一個雞生蛋、蛋生雞的問題。新來者沒辦法對 DHCP 伺服器送一個普通訊息,因為它還沒有一個可以用來當寄件人的 IP 位址,而且它也不知道伺服器的位址。訣竅是同時對所有人喊話。裝置把它的第一個訊息當成連結層廣播送出——一個位址寫成 ff:ff:ff:ff:ff:ff 的框架,這個特殊的 MAC 意思是「這個 LAN 上的每一個人」。因為這個請求是廣播,它會傳到廣播網域裡的每一台裝置,而坐在那個網域某處的 DHCP 伺服器,就是回答的那一個。
- DISCOVER(探索)——新裝置廣播喊:「外面有 DHCP 伺服器嗎?我什麼都沒有。」這個框架送給每一個人,因為裝置根本不知道該問誰。
- OFFER(提供)——一台或多台 DHCP 伺服器回覆,各自提出一個它可以借出的位址,連同搭配的遮罩、閘道與 DNS 伺服器。
- REQUEST(請求)——裝置挑中一個提供,並廣播:「我要那一個。」這同時也告訴其他伺服器:它們的提供被婉拒了。
- ACK(確認)——被選中的伺服器以最終設定確認,並附上一個租約(lease)——一個時間期限,過了就必須續租,否則該位址會回到位址池裡。
ARP:找出某個 IP 背後的 MAC
現在你的筆電設定好了:它有 IP 192.168.1.42、遮罩 255.255.255.0(一個 /24,所以本地網路是 192.168.1.0/24),還有一個位於 192.168.1.1 的閘道。假設你打開一個網頁。軟體建好一個瞄準某台遠方伺服器的 IP 封包,但實體上的第一步是把這個封包送到閘道 192.168.1.1,因為目的地不在本地網路上。要把一個框架放上線路,筆電需要閘道的 MAC 位址——而它沒有。這正是 ARP 啟動的那一刻。
ARP 用的是和 DHCP 一樣的「對所有人喊話」訣竅。筆電廣播一個 ARP 請求:一個送往 ff:ff:ff:ff:ff:ff 的框架,實質上問:「擁有 192.168.1.1 的那位,請告訴我你的 MAC 位址。」廣播網域裡的每台裝置都聽到了,但只有真正擁有 192.168.1.1 的那一台——閘道——會回覆,而且關鍵是它直接回覆,當成一個普通的單播框架直接送回筆電,而不是廣播。這個回覆載著答案:「192.168.1.1 在 MAC a0:b1:c2:d3:e4:f5。」
Laptop wants to reach the gateway 192.168.1.1 but has no MAC for it.
Request (broadcast to ff:ff:ff:ff:ff:ff):
"Who has 192.168.1.1? Tell 192.168.1.42"
Reply (unicast straight back to the laptop):
"192.168.1.1 is at a0:b1:c2:d3:e4:f5"
Laptop's ARP cache now holds:
192.168.1.1 -> a0:b1:c2:d3:e4:f5 (expires in a few minutes)
Next packets to the gateway skip ARP entirely -- the answer is cached.筆電把這個對應存進它的 ARP 快取——一張記著最近學到的 IP 對 MAC 配對的小表,每筆都有一個短短的逾時。手上有了閘道的 MAC,筆電就把它的 IP 封包包進一個位址寫成 a0:b1:c2:d3:e4:f5 的乙太網路框架,交給交換器,而交換器用的正是你兩篇前認識的那張 MAC 學習表來轉發。從此之後,送往閘道的封包就重用那個被快取的 MAC、跳過 ARP——直到快取那筆過期,才會重新再問一次。
本地還是遠端?那個驅動一切的單一判斷
你的筆電在每次發送前都會做一個小但關鍵的判斷,而它正是把 IP 與遮罩綁在一起的那一步。給定一個目的地 IP,筆電用它的子網路遮罩問一個本地還是遠端的問題:這個位址在我自己的本地網路上,還是在它之外?以一個 /24 遮罩來說,前 24 位元是網路部分。筆電把目的地的網路部分拿來和自己的比對。如果相符,目的地就是同一個 LAN 上的鄰居;如果不同,它就是遠端的,必須經由閘道出去。
用那台位於 192.168.1.42、/24 的筆電走一遍。一個送往 192.168.1.99 的封包,前三段(192.168.1)相同,所以是本地的——筆電直接對 192.168.1.99 做 ARP,並把封包框成送往那位鄰居自己的 MAC。一個送往 8.8.8.8 的封包,跟 192.168.1 完全不符,所以是遠端的——筆電對閘道做 ARP,並把封包框成送往閘道的 MAC,即使封包裡頭的 IP 仍然寫著 8.8.8.8。這就是關鍵的微妙之處:IP 的目的地始終是最終的伺服器,但框架的 MAC 目的地只是下一跳。
為什麼廣播型輔助協定強大——又會在哪裡反咬一口
退一步,注意這個共有的模式。DHCP 與 ARP 都在解一個「啟動」難題——需要跟一個你還不知道其位址的人說話——而它們用的是同一個漂亮的招式:對所有人廣播,讓那台答得出來的裝置來回答。這正是為什麼第 3 篇的廣播網域在這裡如此重要。ARP 與 DHCP 只能傳到廣播所及之處,而一台普通的交換器會把廣播傳下去,所以一個大而扁平的 LAN 就是一個大池子,這些輔助協定在裡面都能運作。這也是為什麼用 VLAN 切分一個 LAN,就會切分廣播網域:每個 VLAN 都需要自己的 DHCP 可達範圍,也把自己的 ARP 嘮叨關在裡頭。
同樣的力量也是它的弱點,而這是誠實的部分。ARP 是在一個信任的年代設計的,完全沒有任何認證。當那個單播回覆傳回來說「192.168.1.1 在這個 MAC」,沒有任何東西去檢查回覆者是不是真的擁有 192.168.1.1。同一個 LAN 上的攻擊者可以乾脆送出偽造的回覆,宣稱閘道的 IP 屬於攻擊者的 MAC,受害者就會乖乖把流量送到錯的機器上。這就是 ARP 欺騙,也是許多「路徑上」攻擊的基礎。教訓是這整個主題反覆出現的那一個:一個能證明「可達」的機制,並不能證明「身分」。
再兩個誠實的提醒。第一,ARP 屬於 IPv4;IPv6 把它退役了,改用一個相關但獨立的「鄰居探索(Neighbor Discovery)」機制,所以別以為 ARP 放諸四海皆準。第二,DHCP 同樣是便利、不是安全——你 LAN 上一台流氓 DHCP 伺服器可以發出一個被下毒的閘道或 DNS 位址,悄悄地把你的流量繞經它自己。這兩個協定都是那種不起眼的水電管路,讓即插即用的網路感覺像魔法;它們也都提醒我們,早期的網際網路協定是為了「讓事情在彼此信任的同儕之間動起來」而優化的,把安全留到後來、在協定堆疊更高處才補上。