ARP 工作層次和原理解析
概述
ARP(Address Resolution Protocol,地址解析協議)是用來將 IP 地址解析爲 MAC 地址的協議。
主機 (客戶端) 和三層網絡設備 (例如路由器,三層交換機) 上會維護一張 ARP 表,用於存儲 IP 地址和 MAC 地址的映射關係,每一個表項表示一個 IP 地址到 MAC 地址的轉換關係。
工作層次
第一種看法
ARP 屬於二層協議,工作在數據鏈路層,因爲 ARP 無法脫離廣播域的限制。
第二種看法
ARP 協議工作在 OSI (或 TCP/IP) 模型的第二層(數據鏈路層)和第三層(網絡層)之間,也許這個結論會顛覆你對網絡分層的已有認知,但是如果分析 ARP 的工作方式之後,你會發現情況確實如此。
ARP 不屬於二層網絡,不能把數據發送到目標主機,因爲 ARP 報文數據是包裝在二層以太網幀中的,同時 ARP 也不屬於三層網絡,因爲它不具備三層網絡中的路由尋址功能 (無法跨越網段)。
具體來說,ARP 通過 ARP 請求和 ARP 應答,將網絡層的邏輯地址(IP 地址)映射到數據鏈路層的物理地址(MAC 地址)。
工作流程
這裏假設主機 A 第一次和主機 B 通信。
-
當主機 A 需要發送數據到主機 B 時,首先會檢查主機 B 的 IP 地址是否位於同一子網內 (兩臺主機是否連接的同一個交換機)
-
如果主機 B 的 IP 地址位於同一子網內,主機 A 會發起 ARP 廣播請求,主機 B 收到 ARP 請求後,會回覆一個 ARP 回覆,其中包含了目標 B 的 MAC 地址
-
如果主機 B 的 IP 地址不在同一子網內,主機將向默認網關發送 ARP 請求,ARP 請求中包含了目標 IP 地址和請求者的 MAC 地址,獲取主機 B 的 MAC 地址
-
在向默認網關發送 ARP 請求之前,需要獲取默認網關路由器的 MAC 地址,所以 會先發出一個 ARP 請求
-
默認網關收到 ARP 請求後,發送一個 ARP 回覆到主機 A,其中包含了自己的 MAC 地址
-
此時主機 A 再次向默認網關發送 查詢主機 B 的 ARP 請求
-
默認網關收到 ARP 請求後,會將 ARP 請求轉發出去然後等待應答 (這裏的細節先忽略),接收到應答之後,發送一個 ARP 回覆到主機 A,其中包含了主機 B 的 MAC 地址
-
主機 A 將主機 B 的 MAC 地址保存在 ARP 緩存中,後續再向主機 B 發送數據時,就可以直接從 ARP 表中獲取到主機 B 的 MAC 地址了
示例
ARP 通過廣播 ARP 請求和單播 ARP 應答這兩個過程完成 IP 地址到 MAC 地址解析和映射,下面以兩個相同子網內的主機來說明 ARP 的工作流程。
這裏假設主機 Host_1 要向主機 Host_3 發送主機,但是不知道 Host_3 的 IP 地址,所以需要先通過 ARP 請求來獲得 Host_3 的 IP 地址。
- Host_1 查找本地的 ARP 緩存表,確認是否存在 Host_3 的 MAC 地址表項
-
如果在 ARP 緩存表中 找到了 Host_3 的 MAC 地址 (假設爲 MAC_3),直接將數據報文進行幀封裝 (
目的 MAC 地址: MAC_3
) -
如果在 ARP 緩存表中 找不到 Host_3 的 MAC 地址,先緩存要發送的數據報文,然後通過廣播方式發送一個 ARP 請求報文,其中:
源 MAC 地址: Host_1 的 MAC 地址
,源 IP 地址: Host_1 的 IP 地址
,目的 MAC 地址: FF:FF:FF:FF:FF:FF
,目的 IP 地址: Host_3 的 IP 地址
-
交換機 Switch_1 收到 ARP 請求報文後,轉發到在同一廣播域內 (也就是轉發到 Host_2, Host_3)
-
Host_2 收到 ARP 請求後,發現目的 IP 地址不是自己的,直接丟掉,Host_3 收到 ARP 請求後,發現目的 IP 地址是自己,開始處理:
-
首先將 ARP 請求中的 源 IP 地址和源 MAC 地址存入自己的 ARP 表中 (也就是存儲 Host_1_IP -> Host_1_MAC 的映射關係)
-
然後使用單播發送 ARP 應答報文給 Host_1, 其中:
源 MAC 地址: Host_3 的 MAC 地址
,源 IP 地址: Host_3 的 IP 地址
,目的 MAC 地址: Host_1 的 MAC 地址
,目的 IP 地址: Host_1 的 IP 地址
- 交換機 Switch_1 收到 ARP 應答報文後,轉發到 Host_1, Host_1 收到 ARP 應答後:
-
首先將 ARP 應答中的 源 IP 地址和源 MAC 地址存入自己的 ARP 表中 (也就是存儲 Host_3_IP -> Host_3_MAC 的映射關係)
-
然後將要發送的數據進行報文封裝,併發送給 Host_3
不同子網
剛纔的示例說明了,位於同一子網內的兩臺主機之間的 ARP 請求和應答過程,那麼對於不同子網的兩臺主機,其中的流程又是怎樣的呢?例如下圖中的 主機 Host_1 要向主機 Host_4 發送主機。
因爲 Host_1 已經配置了默認網關,所以 Host_1 會先發送 ARP 請求報文獲取默認網關路由器的 MAC 地址,收到默認網關的應答報文後,將默認網關的 IP 地址和 MAC 地址存入自己的 ARP 表中,然後將發送給 Host_4 的數據報文發送給默認網關,經由默認網關轉發到 Host_4。
**網關需要學習 Host_4 的 ARP 表項嗎?**需要,因爲網關必須先把數據報文封裝成以太網幀,其中當然必須包含 Host_4 的 MAC 地址。
後序的通信過程中,Host_1 學習 Host_4 的 ARP 表項 (IP -> MAC 映射關係) 過程,和前文中 Host_1 學習 Host_3 的 ARP 表項過程類似,唯一的區別在於多了一層默認網關和一層交換機 (Switch_2) 的轉發,這裏不再贅述。
Wireshark 抓包
下面通過抓包工具 Wireshark
分別來演示 ARP 請求正常應答和無應答兩種情況。
正常應答
向一臺正常的主機發送 ping
時,對應的 ICMP 應答爲對應的 ttl。
# 本機 IP: 192.168.3.210
$ ping 192.168.3.200
PING 192.168.3.2 (192.168.3.2) 56(84) bytes of data.
64 bytes from 192.168.3.200: icmp_seq=1 ttl=63 time=428 ms
64 bytes from 192.168.3.200: icmp_seq=2 ttl=63 time=181 ms
64 bytes from 192.168.3.200: icmp_seq=3 ttl=63 time=106 ms
64 bytes from 192.168.3.200: icmp_seq=4 ttl=63 time=438 ms
64 bytes from 192.168.3.200: icmp_seq=5 ttl=63 time=357 ms
^C
--- 192.168.3.200 ping statistics ---
5 packets transmitted, 5 received, 0% packet loss, time 5004ms
接下來,通過 Wireshark 抓包來看看 ARP 請求的報文數據:
通過抓包數據,可以將報文中的關鍵數據摘取出來:
-
Opcode: 1, 表示該報文爲 ARP 請求報文
-
源 MAC: 本機 MAC 地址
-
源 IP : 本機 IP 地址
-
目的 MAC: FF:FF:FF:FF:FF:FF, 說明這是一個廣播請求
-
目的 IP: 192.168.3.200
然後通過 Wireshark 抓包來看看 ARP 應答的報文數據:
通過抓包數據,可以將報文中的關鍵數據摘取出來:
-
Opcode: 2, 表示該報文爲 ARP 應答報文
-
源 MAC: 對端主機 MAC 地址
-
源 IP : 對端主機 IP 地址
-
目的 MAC: 本機 MAC 地址
-
目的 IP: 本機 IP 地址
和剛纔 ARP 請求時的廣播報文不同,這裏的 ARP 應答爲單播報文,直接從對端主機發送到本機。
無應答
向一臺不存在的主機發送 ping
時,對應的 ICMP 應答爲 Destination Host Unreachable。
# 本機 IP: 192.168.3.200
$ ping 192.168.3.100
PING 192.168.3.100 (192.168.3.100) 56(84) bytes of data.
From 192.168.3.200 icmp_seq=3 Destination Host Unreachable
From 192.168.3.200 icmp_seq=6 Destination Host Unreachable
From 192.168.3.200 icmp_seq=9 Destination Host Unreachable
From 192.168.3.200 icmp_seq=12 Destination Host Unreachable
From 192.168.3.200 icmp_seq=15 Destination Host Unreachable
^C
--- 192.168.3.100 ping statistics ---
16 packets transmitted, 0 received, +5 errors, 100% packet loss, time 15328ms
使用 Wireshark 抓包,對應的 ARP 報文如下:
如圖所示,雖然連續發了好幾個 ARP 請求,但是沒有收到任何應答。
ARP 表
如果每次發送數據包之前,都要發起 APR 請求查詢目標主機 IP 地址,網絡中就會增加很多 ARP 包,這顯然是沒有必要的 (因爲單個主機的 IP 地址和 MAC 地址並不會頻繁變動),所以會將 APP 查詢結果緩存起來。
這個緩存表就是 ARP 表
,裏面存儲着當前局域網上的各主機和路由器的 IP 地址到 MAC 地址的映射關係。
如果主機 A 知道主機 B 的 IP 地址,但是 ARP 高速緩存中沒有該 IP 地址到 MAC 地址的映射,此時主機 A 通過廣播的方式發送 ARP 請求分組,主機 B 收到該請求後會發送 ARP 響應分組給主機 A 告知其 MAC 地址,隨後主機 A 向其高速緩存中寫入主機 B 的 IP 地址到 MAC 地址的映射。
也就是說,在主機發送數據包時,先查詢一下 ARP 表,如果其中已經保存了目標主機的 MAC 地址,就不需要發送 ARP 查詢請求,而是直接使用 ARP 緩存中的地址,只有當 ARP 表中不存在目標主機的 MAC 地址時,才發送 ARP 查詢請求。
Linux 中使用 arp
命令來查看 ARP 表緩存相關信息:
# 查看 ARP 表緩存
$ arp -a
# 查看 ARP 表緩存詳細信息
$ arp -an
Windows 中使用相同的命令和參數。
ARP 表項
ARP 表是以每個網絡接口爲單位保存的,也就是每個以太網卡、無線網卡、虛擬網卡 (例如 Docker) 都有自己的 ARP 表,當一個數據包到達某個網絡接口時,操作系統會檢查該接口的 ARP 緩存表。
Linux 中使用 ip
命名查看 ARP 表項信息:
# 查看 ARP 表
$ ip neigh show
# 每個網絡接口都有自己的 ARP 表
# 以太網卡
10.0.5.91 dev eth0 lladdr ee:ff:ff:ff:ff:ff REACHABLE
10.0.5.253 dev eth0 lladdr ee:ff:ff:ff:ff:ff REACHABLE
# 虛擬網卡
172.27.0.2 dev br-31a91bfb5058 lladdr 15:24:ef:1b:00:02 STALE
172.17.0.2 dev docker0 lladdr 15:24:ef:11:00:02 STALE
172.29.0.4 dev br-37adcdbf3e5f lladdr 15:24:ef:1d:00:04 STALE
172.17.0.4 dev docker0 lladdr 15:24:ef:11:00:04 STALE
172.22.0.2 dev br-456c812bc240 lladdr 15:24:ef:16:00:02 STALE
172.17.0.3 dev docker0 lladdr 15:24:ef:11:00:03 REACHABLE
ARP 表項狀態
在 ARP 表的結果輸出中,每一行的末尾帶有一個 “狀態值”, ARP 包含如下的狀態。
REACHABLE
表示該 IP 地址的 MAC 地址信息是最新的,並且正常進行通信。
STALE
表示該 IP 地址的 MAC 地址信息仍然可用,但已經超過了過期時間,主機可能會繼續使用這個 MAC 地址進行通信,但應儘快發送 ARP 請求來更新 MAC 地址。
DELAY
表示主機已經發送了 ARP 請求,但尚未收到應答。
PROBE
表示主機正在發送 ARP 請求,以確認該 IP 地址是否仍然可用,通常發生在主機重啓或重新連接到網絡時。
FAILED
表示 ARP 請求失敗,主機無法獲取到該 IP 地址對應的 MAC 地址。
PERMANENT
表示靜態 ARP 表項,在管理員手動刪除之前一直生效。
緩存老化
使用 ARP 緩存可以減少 ARP 包的數量,但是和所有 “緩存數據” 一樣,ARP 緩存也存在數據失效的問題。
當某個主機的 IP 地址或者 MAC 地址發生變化時,ARP 緩存的數據就會失效,爲了最大化減少 ARP 緩存失效帶來的問題,ARP 緩存數據會定期刪除,緩存數據刪除之後,主機發送數據請求之前,重新執行一次 ARP 請求查詢就又可以獲取到目標主機的 MAC 地址了。
Linux 中可以使用 sysctl
命令來查看 ARP 緩存的默認有效期。
# 查看 ARP 緩存的默認有效期
$ sysctl net.ipv4.neigh.default.gc_stale_time
# APR 緩存默認有效期: 1 分鐘
# 每隔 1 分鐘,定期刪除 ARP 緩存
net.ipv4.neigh.default.gc_stale_time = 60
除了定期刪除策略外,在網絡接口下線時 (例如無線網卡被拔出),其 ARP 緩存會被立刻刪除。
ARP 攻擊
ARP 攻擊利用 ARP 協議的工作方式來欺騙網絡中的主機,使其將網絡流量發送到錯誤的目標,通常有下面幾種常見的方式。
1.ARP 欺騙(ARP Spoofing)
攻擊者發送僞造的 ARP 應答消息,欺騙網絡中的其他主機,告訴它們 攻擊者的 MAC 地址對應於指定主機的 IP 地址,這樣,當其他主機想要發送數據給指定主機時,數據包實際上會被髮送到攻擊者的主機上,攻擊者可以對數據進行監視、修改或丟棄。
爲了防止 ARP 欺騙,可以使用 ARP Anti-Spoofing 技術來保護網絡安全,交換機會對 ARP 報文進行檢查,一旦發現 IP 與 MAC 地址有僞造的情況,立馬丟包甚至關閉端口。
當用戶手動修改 IP 時,其實已經通過 DHCP Release 報文將自動獲取到的的 IP 釋放了。所以當交換機檢查到該 IP 已經被釋放後,任何非 DHCP 數據報文,全部拒絕丟掉。
2. ARP 洪泛(ARP Flooding)
攻擊者發送大量僞造的 ARP 請求和應答包,導致網絡設備的 ARP 緩存表被填滿。當設備的 ARP 緩存被僞造的條目填滿時,合法的 ARP 條目無法被正確存儲和更新,導致設備無法進行正常的網絡通信,從而引發網絡癱瘓。
ARP 表類型
1. 動態類型
通過 ARP 請求和 ARP 應答自動生成和維護,表項可以被更新和 (過期) 刪除,也可以被靜態 ARP 表項覆蓋。
2. 靜態類型
由網絡管理員手動建立的 IP 地址和 MAC 地址之間的映射關係,表項不會被 (過期) 刪除,也不會被靜態 ARP 表項覆蓋。
靜態 ARP 表項可以限制指定本端主機和指定 IP 的對端主機通信時只使用指定的 MAC 地址,此時攻擊報文無法修改本端主機的 ARP 表中的 IP 地址和 MAC 地址的映射關係,從而保護了本端主機和對端主機之間的正常通信,一般會在網關設備上配置靜態 ARP 表項。
免費 ARP
主機使用自己的 IP 地址作爲目的 IP 地址發送 ARP 請求 (主機自己向自己發送 ARP 請求),此種方式稱免費 ARP, 主要起到如下作用:
-
IP 地址衝突檢測: 主機對外發送 ARP 請求,正常情況下不會收到 ARP 應答,如果收到了,說明網絡中已經存在與自身 IP 重複的主機,檢測到重複 (衝突) 之後,主機會週期性地發送 ARP 免費應答報文,直到衝突解決
-
通告新的 MAC 地址: 主機更換了網卡,這時會產生新的 MAC 地址,爲了通知網絡中的其他主機更新 ARP 表項,主機會發送一個免費的 ARP 請求
Reference
-
An Ethernet Address Resolution Protocol[1]
-
ARP[2]
-
ARP 協議解析 [3]
鏈接
[1]
An Ethernet Address Resolution Protocol: https://datatracker.ietf.org/doc/html/rfc826
[2]
ARP: https://info.support.huawei.com/info-finder/encyclopedia/zh/ARP.html
[3]
ARP 協議解析: https://cizixs.com/2017/07/31/arp-protocol/
本文由 Readfog 進行 AMP 轉碼,版權歸原作者所有。
來源:https://mp.weixin.qq.com/s/ttMRt-G2O0xcX-mMFiNstQ