如果要在TCP/IP協(xié)議棧中選擇一個(gè)"最不安全的協(xié)議",那么我會(huì )毫不猶豫把票投給ARP協(xié)議。我們經(jīng)常聽(tīng)到的這些術(shù)語(yǔ),包括"網(wǎng)絡(luò )掃描"、"內網(wǎng)滲透"、"中間人攔截"、"局域網(wǎng)流控"、"流量欺騙",基本都跟ARP脫不了干系。大量的安全工具,例如大名鼎鼎的Cain、功能完備的Ettercap、操作傻瓜式的P2P終結者,底層都要基于A(yíng)RP實(shí)現。
聽(tīng)上去這么"逆天"的協(xié)議,其實(shí)技術(shù)原理又簡(jiǎn)單的難以置信,例如ARP整個(gè)完整交互過(guò)程僅需要兩個(gè)包,一問(wèn)一答即可搞定!但是ARP協(xié)議也有它令初學(xué)者迷惑的地方,例如由它本身延伸出來(lái)的"代理ARP"、"免費ARP"、"翻轉ARP"、"逆向ARP",而這些不同種類(lèi)的ARP,又應用于不同的場(chǎng)景。好吧,在深入到技術(shù)原理之前,作為初學(xué)者,我們先記住下面三句話(huà):
接下來(lái),我們通過(guò)圖解的方式來(lái)深入了解ARP協(xié)議是如何工作的。
同一個(gè)局域網(wǎng)里面,當PC1需要跟PC2進(jìn)行通信時(shí),此時(shí)PC1是如何處理的?
根據OSI數據封裝順序,發(fā)送方會(huì )自頂向下(從應用層到物理層)封裝數據,然后發(fā)送出去,這里以PC1 ping PC2的過(guò)程舉例==>
PC1封裝數據并且對外發(fā)送數據時(shí),上圖中出現了"failed",即數據封裝失敗了,為什么?
我們給PC1指令-"ping ip2",這就告知了目的IP,此時(shí)PC1便有了通信需要的源目IP地址,但是PC1仍然沒(méi)有通信需要的目的MAC地址。這就好比我們要寄一個(gè)快遞,如果在快遞單上僅僅寫(xiě)了收件人的姓名(IP),卻沒(méi)有寫(xiě)收件人的地址(MAC),那么這個(gè)快遞就沒(méi)法寄出,因為信息不完整。
那么,現在PC1已經(jīng)有了PC2的IP地址信息,如何獲取到PC2的MAC地址呢?此時(shí),ARP協(xié)議就派上用場(chǎng)了。我們接著(zhù)上面這張圖,繼續==>
通過(guò)第三和第四步驟,我們看到PC1和PC2進(jìn)行了一次ARP請求和回復過(guò)程,通過(guò)這個(gè)交互工程,PC1便具備了PC2的MAC地址信息。
接下來(lái)PC1會(huì )怎么做呢?在真正進(jìn)行通信之前,PC1還會(huì )將PC2的MAC信息放入本地的【ARP緩存表】,表里面放置了IP和MAC地址的映射信息,例如 IP2<->MAC2。接下來(lái),PC1再次進(jìn)行數據封裝,正式進(jìn)入PING通信,如下==>
小結:經(jīng)過(guò)上面6個(gè)步驟的處理,PC1終于把數據包發(fā)送出去了,之后便可以進(jìn)行正常的通信了?吹搅税,ARP的功能和實(shí)現過(guò)程是如此的簡(jiǎn)單:它在發(fā)送方需要目標MAC地址的時(shí)及時(shí)出手,通過(guò)"一問(wèn)一答"的方式獲取到特定IP對應的MAC地址,然后存儲到本地【ARP緩存表】,后續需要的話(huà),就到這里查找。
既然是"緩存"表,意味著(zhù)它有時(shí)效性,并且如果電腦或者通信設備重啟的話(huà),這張表就會(huì )清空;也就是說(shuō),如果下次需要通信,又需要進(jìn)行ARP請求。在我們的windows/macos系統下,可以通過(guò)命令行"arp -a"查看具體信息=>
上面的圖解過(guò)程看上去簡(jiǎn)單又純粹,好像我們就已經(jīng)把這個(gè)協(xié)議的精髓全部get到,但其實(shí),我們只是剛揭開(kāi)了它的面紗,接下來(lái)我們才真正進(jìn)入正題。例如,上面的圖解過(guò)程中,整個(gè)局域網(wǎng)(LAN)只有PC1和PC2兩個(gè)主機,所以這個(gè)一問(wèn)一答過(guò)程非常的順暢。
而實(shí)際網(wǎng)絡(luò )中,這個(gè)LAN可能有幾十上百的主機,那么請問(wèn),PC1如何將這個(gè)【ARP請求包】順利的交給PC2,而PC2又如何順利的把【ARP回應包】返回給PC1? 我們看下面的圖:
為了營(yíng)造出"幾十上百"的效果,這里多添加了2個(gè)主機進(jìn)來(lái) ( ω ),并且增加了有線(xiàn)和無(wú)線(xiàn)的環(huán)境。那么,在多主機環(huán)境下,PC1現在發(fā)出的ARP請求包,怎么交到PC2手里?
這時(shí),ARP協(xié)議就需要采用以太網(wǎng)的"廣播"功能:將請求包以廣播的形式發(fā)送,交換機或WiFi設備(無(wú)線(xiàn)路由器)收到廣播包時(shí),會(huì )將此數據發(fā)給同一局域網(wǎng)的其他所有主機。
那么,什么是廣播?對于初學(xué)者而言,我們只需要知道,大部分的廣播包,它們有一個(gè)共同特征:二層封裝時(shí)目的MAC是全f(ffff.ffff.ffff)或三層封裝時(shí)目的IP是全1(255.255.255.255)?梢赃@樣更方便的記。耗康牡刂纷畲蟮,就是廣播。
注明:廣播根據所在層次可分為二層廣播和三層廣播,根據發(fā)生范圍可分為本地廣播和定向廣播,小伙伴們有興趣可以自己再去拓展下。
接下來(lái)我們來(lái)看下這個(gè)ARP廣播請求包接下來(lái)是如何工作的?
根據上圖我們看到,PC1發(fā)送的請求廣播包同時(shí)被其他主機收到,然后PC3和PC4收到之后(發(fā)現不是問(wèn)自己)則丟棄。而PC2收到之后,根據請求包里面的信息(有自己的IP地址),判斷是給自己的,所以不會(huì )做丟棄動(dòng)作,而是返回ARP回應包。
ARP請求是通過(guò)廣播方式來(lái)實(shí)現的,那么,PC2返回ARP回應包,是否也需要通過(guò)廣播來(lái)實(shí)現呢?答案是否定的。大部分網(wǎng)絡(luò )協(xié)議在設計的時(shí)候,都需要保持極度克制,不需要的交互就砍掉,能合并的信息就合并,能不用廣播就用單播,以此讓帶寬變得更多讓網(wǎng)絡(luò )變得更快。
那么,ARP回應包是如何處理的?這里需要特別關(guān)注ARP請求包的內容,在上面的圖解里面,ARP請求包的完整信息是:我的IP地址是IP1,MAC地址是MAC1,請問(wèn)誰(shuí)是PC2,你的IP2對應的MAC地址是多少?
簡(jiǎn)單來(lái)說(shuō),ARP請求首先有"自我介紹",然后才是詢(xún)問(wèn)。這樣的話(huà),PC2在收到請求之后,就可以將PC1的IP和MAC映射信息存儲在本地的【ARP緩存表】,既然知道PC1在哪里,就可以返回ARP單播回應包。
這張圖我們需要得到兩個(gè)信息:①被詢(xún)問(wèn)者PC2先生成了ARP映射信息,然后才是詢(xún)問(wèn)者PC1;②PC3和PC4等其他主機,無(wú)法收到這個(gè)ARP回應包,因為是單播形式。
小結:ARP協(xié)議通過(guò)"一問(wèn)一答"實(shí)現交互,但是"問(wèn)"和"答"都有講究,"問(wèn)"是通過(guò)廣播形式實(shí)現,"答"是通過(guò)單播形式。
四、ARP數據包解讀
為了讓大家更好的理解ARP協(xié)議以及廣播和單播的概念,我們來(lái)看一下用Wireshark抓取到的真實(shí)網(wǎng)絡(luò )中的ARP過(guò)程,通過(guò)數據包的方式來(lái)呈現,地址信息如下,部分MAC信息隱去。(建議初學(xué)者用GNS3配合Wireshark來(lái)抓取協(xié)議包進(jìn)行分析,相比真實(shí)網(wǎng)絡(luò )更加干凈,方便分析)
主機1 <---> 主機2
主機1: IP1 10.1.20.64 MAC1:00:08:ca:xx:xx:xx
主機2: IP2 10.1.20.109 MAC2:44:6d:57:xx:xx:xx
【ARP請求包】
【ARP回應包】
【ARP協(xié)議字段解讀】
Hardware type :硬件類(lèi)型,標識鏈路層協(xié)議
Protocol type: 協(xié)議類(lèi)型,標識網(wǎng)絡(luò )層協(xié)議
Hardware size :硬件地址大小,標識MAC地址長(cháng)度,這里是6個(gè)字節(48bti)
Protocol size: 協(xié)議地址大小,標識IP地址長(cháng)度,這里是4個(gè)字節(32bit)
Opcode: 操作代碼,標識ARP數據包類(lèi)型,1表示請求,2表示回應
Sender MAC address :發(fā)送者M(jìn)AC
Sender IP address :發(fā)送者IP
Target MAC address :目標MAC,此處全0表示在請求
Target IP address: 目標IP
這個(gè)問(wèn)題的難度堪比另外一個(gè)世界級難題:世界上最好的編程語(yǔ)言是什么?
其實(shí)早在20世紀時(shí),W.Richard Stevens在《TCP/IP詳解卷一》里面就提到了這個(gè)難題。這里給出我個(gè)人的協(xié)議分層思路,給大家作為參考=>
協(xié)議到底所屬哪一層,可以從應用/功能來(lái)考慮,也可以從層次/包封裝來(lái)考慮。
以ARP協(xié)議為例,它的功能最終是獲取到MAC信息,服務(wù)于鏈路層,從這點(diǎn)考慮,ARP是鏈路層協(xié)議;但是從層次來(lái)看,ARP基于Ethernet協(xié)議,IP協(xié)議基于Ethernet協(xié)議,它們在Ethernet協(xié)議里面有獨立的Type類(lèi)型,前者是0x0806,后者是0x0800,既然ARP和IP協(xié)議"平起平坐",那么IP是網(wǎng)絡(luò )層,ARP難道就不是網(wǎng)絡(luò )層?
小結:基于功能來(lái)考慮,ARP是鏈路層協(xié)議;基于分層/包封裝來(lái)考慮,ARP是網(wǎng)絡(luò )層協(xié)議。(此方法對于ICMP協(xié)議同樣管用)