可能是目前最全的講 ICMP 的文章了

對於 ICMP 協議,你想知道的,可能包括以下幾點:

  • ICMP 是啥

  • 爲啥需要 ICMP

  • ICMP 有哪些報文類型

  • ICMP 報文格式長啥樣

  • 有哪些命令用了 ICMP

  • ICMP 有哪些內核參數

  • ICMP 的問題

帶着這些問題,下面我們就來一一解答。

01 ICMP 是啥

ICMP,全稱是 Internet Control Message Protocol,即互聯網控制報文協議,所謂控制,就是通過下發指令來感知和控制網絡環境,所以它一定是配合一個無法感知網絡環境的協議來工作的,這個協議就是 IP(包括 IPv4 和 IPv6)。

所以,ICMP 通常被認爲是 IP 協議的一部分,它封裝在 IP 層中,使用 IP 協議進行傳輸。因此,嚴格來說,ICMP 既不是一個網絡層協議,也不是一個傳輸層協議,而是介於兩者之間的一個協議。

它的主要功能是傳輸網絡診斷信息,信息主要包括兩類:

  • 一類是 查詢類報文 :主要用於信息的查詢和採集,比如採集傳輸路徑上的每個路由器都是誰,本次傳輸的報文是否達到目的地等等。

  • 另一類是 差錯診斷類報文 :主要用於診斷網絡故障,比如傳輸報文被丟棄的原因是什麼等等。

02 爲啥需要 ICMP

我們都知道,IP 協議是一個不可靠協議,如果 IP 包在傳輸過程中出現錯誤,比如 checksum 對不上,擁塞,超時等等,那麼 IP 包是會直接被丟棄的,之後也不會有進一步的努力來修正。

這是 IP 協議的一個設計準則決定的,也就是 best effort,盡力而爲,這樣的好處是讓 IP 協議儘量保持簡單的形態,只負責有效率的數據傳輸,而更多的質量控制交給高層的協議去處理(比如 TCP)。

但高層能提供質量控制的協議畢竟在少數,所以就需要在下層有協議來輔助 IP 完成必要的網絡質量管理。ICMP 協議自然就被提出來了。

通過 ICMP 協議,當 IP 包發生錯誤的時候,上層發送 IP 包的主機或路由器並不知道下層發生了錯誤,這個時候,下層的主機或路由器就可以通過發送 ICMP 包,將錯誤信息彙報給上層,從而讓上層的主機或路由器進行調整。

不過需要注意的是,ICMP 僅僅只能提供某些特定類型的錯誤信息彙報,並不能幫助 IP 協議成爲可靠的協議。它能做的事還是有限,但用於基本的網絡質量管理是足夠了。

03 ICMP 報文格式長啥樣

如下圖所示,ICMP 報文是被封裝在 IP 數據報中傳輸的。

IP 報頭中的 Protocol 字段爲 1 即表示該報文攜帶的是 ICMP 報文。(此處只是爲了說明問題,因此 IP 報頭是簡化了的)

進一步看,ICMP 報頭爲 4 個字節:

  • 類型 type:佔 1 個字節,表示較大範圍類型分類的 ICMP 報文

  • 代碼 code:佔 1 個字節,表示較小範圍類型分類的 ICMP 報文(type的細分)

  • 校驗和 checksum:佔 2 個字節,ICMP checksum 的計算方法類似於 IP checksum,但是不同的是 IP 只校驗頭部,ICMP 校驗頭部+數據部分

後面緊接的 ICMP 數據部分,根據前面的類型和代碼字段的不同,具有不同的內容。

04 ICMP 有哪些報文類型

ICMP 支持的報文類型非常多,詳細看下錶:

類型字段指代了一大類,代碼字段又細分了幾大小類。

上面可能不夠明確,我們通過下面這兩張表來列舉一下,由於類型太多了,而且有些平時非常少見,因此,這裏我們只列舉常見的一些類型。

第一張表:類型表

類型內容種類解釋
0應答Rping應答
3目的不可達E很多細分,如主機/協議等
4源端抑制E表示擁塞
5重定向E表示最優的路由路徑
8請求Rping請求
9路由器通告R告知路由器地址
10路由器請求R請求路由器通告
11超時ETTL=0
12參數問題E有問題的報文

注:R表示查詢報文,E表示差錯報文

進一步,對於每種類型,又可以根據代碼字段細分多種子類型,請看第二張表:

第二張表:類型細分表

類型代碼內容解釋
30網絡不可達沒有路由到目的地
31主機不可達已知但不可達的主機
32協議不可達未知的協議
33端口不可達未知的端口
34要分片但設置了不分片位路由器MTU限制需分片但無法分片
35源路由失敗中間跳不可達
313管理禁止通信被過濾策略禁止的通信
314違反主機優先級src/dst/port不准許的優先級
315優先級終止生效在最小ToS之下
51主機重定向數據報指示一個可選的路由器/主機
110在傳輸期間時間超時跳數限制/TTL超時
111分片重組時間超時重組計時器超時之前,有分片未到達
120指針指示差錯字節偏移量指示第一個問題字段
122錯誤的長度數據包有無效的Total Length字段

通過這兩張表,每一種類型的 ICMP 包的意思應該都比較清楚了。

有一種可能不太好理解,這裏再重點講解一下:

① 源端抑制

屬於差錯信息。如果某個源主機向目的主機快速地發送數據包,但目的主機來不及處理,就會向源主機發出該類型的 ICMP 包,提醒源主機放慢發送速度。

② 重定向

屬於差錯信息。如果某個源主機向網絡中發送一個 IP 包,路徑中某個路由器收到這個 IP 包,對照其路由表,發現自己不應該接收該包(包需要原路返回,或者不是最佳路由路徑),就會向源主機發送該類型的 ICMP 包,提醒源主機修改自己的路由表,下次路由到另外一個更好的路由器。

③ 需要分片但設置了不分片位

屬於差錯信息。如果某個源主機在發送一個 IP 包之前,對該 IP 包中的首部字段 DF 位設爲 1,也就是“分片禁止位=1”,表示該包在傳輸的過程中不允許分片,但是中間某個路由器允許傳輸的最大路徑 MTU 小於該包大小,需要分片才能傳輸,但是由於設置不分片位,路由器會將該包丟棄,並向源主機發送一個攜帶 MTU 信息的 ICMP 包,提醒源主機下次發包的大小不應超過該 MTU 的值。

這種類型的 ICMP 包通常用來發現傳輸路徑上的 MTU 值。

④ TTL超時

屬於差錯信息。超時定義了數據包在網絡中存活的最長時間,IPv4 中的 TTL 字段和 IPv6 中的 Hop Limit 字段都表示了這層意思,它們是一個整數值,會隨着經過的路由器而遞減,當減爲 0 時,就認爲該 IP 包超時,然後當前減爲 0 的路由器會向源主機發送 ICMP 包,通知它發生了超時錯誤。

05 有哪些命令體現了 ICMP

ICMP 的這些包的類型,用戶可以充分用來診斷網絡的故障情況。

因此誕生了一些利用 ICMP 協議的網絡診斷工具,其中比較知名的就是 pingtraceroute。這兩工具分別利用兩種類型的 ICMP 報文:

  • ping 使用查詢類型報文

  • traceroute 使用差錯類型報文

① ping

ping 使用了查詢報文中的請求報文(類型爲 8)和應答報文(類型爲 0),主要查詢某個網絡節點的連通性,如果出現網絡不連通的情況,具體是什麼問題,會在應答報文中附帶相關的差錯信息予以告知。比如網絡不可達(Network Unreacheable)、主機不可達(Host Unreachable)等等,然後用戶就可以根據這些信息來分析具體是哪個環節出現問題。

下面一張圖,顯示了一個 ping 包的完整流程:

可以看到,通過各層協議棧的層層封裝和解封裝,一個 ping 包從一臺主機發送到另一臺主機,包括請求包和應答包。其中,如果目標 MAC 地址未知的話,需要先發出 ARP 請求拿到,然後再進行封裝。

關於 ping 命令的使用案例可以參考這篇文章:ping容易忽略的10點用法和排查問題技巧

② traceroute

traceroute 是類 Linux 系統自帶的工具,Windows 上類似的工具是 tracert,兩者有些許不同,tracert 默認使用 ICMP 報文探測,而 traceroute 默認使用 UDP,但是也可以使用 TCP/ICMP 三種報文探測。

traceroute 利用 ICMP 差錯報文,主要用來確定這幾件事:

  • 確定通信雙方路徑上經過的路由器設備

  • 確定 UDP 包是否成功達到目的地

  • 發現路徑 MTU

確定通信雙方路徑上經過的路由器設備 。就是利用上面提到的超時類型的 ICMP 報文來實現。traceroute 向目的地發送 IP 包,剛開始的時候,將 TTL 設置爲 1,當經過第一個路由器時,TTL -1 = 0 引發超時錯誤,第一個路由器回覆 ICMP 超時報文,源主機就可以知道路徑第一個路由器的信息,隨後 TTL 被設置爲 2、3、4, ...,直到到達目的地,這樣,沿途每個路由器都會向源主機回覆 ICMP 超時報文,traceroute 就可以拿到所有的路由器信息了。

不過這裏要 注意 ,並不是所有路由器都會返回 ICMP 報文,因爲出於安全性考慮,大多數防火牆以及啓用了防火牆功能的路由器都默認配置爲不返回任何 ICMP 報文,管理員也會主動配置,所以這時使用 traceroute 就不一定能拿到所有路由器信息了。

確定 UDP 包是否成功達到目的地 。使用上面的方法能拿到路由器信息,但並不能確定發的包是否到達目的地。traceroute 通過發送 UDP 包來解決了這個問題,因爲 UDP 包的可用端口號範圍 <3000,所以就可以在發送 UDP 包的時候填入一個 >3000 的端口號,這樣,如果當包確實到達了目的地,由於端口不匹配,就會返回一個端口不可達的 ICMP 報文,源主機就可以確定包確實到了目的地了。

發現路徑 MTU 。這塊在上面講 “需要分片但設置了不分片位” 類型報文的時候已經講過,traceroute 就是利用這種類型報文來逐一地確認傳輸路徑上各個路由器之間的 MTU 值。

關於 traceroute 命令的使用案例可以參考這篇文章:排查網絡問題,請務必掌握這款工具

③ MTR

MTR 全稱 my traceroute,相對以上兩個其實是更好的網絡排障工具,只是用的人不多,導致它不太出名。之所以說它好,是因爲它結合了 pingnslookuptraceroute 三款工具的特性。

關於 MTR 的安裝和使用分析詳見這篇文章:這款網絡排查工具,堪稱神器!

④ tcptraceroute

這塊工具從名稱就可以看出,是基於 TCP 的 traceroute,也就是它使用 TCP 包(具體是 TCP 的 SYN 包)來進行網絡探測,而不是 ICMP 包。

從上面我們已經知道,traceroute -T 就是使用 TCP 包進行探測,所以 tcptraceroute 其實等效於 traceroute -T

使用 TCP 包進行探測的原因,主要是因爲現代廣泛使用的防火牆,出於安全的考慮,都會攔截 UDP 包和 ICMP 包,而通常不會攔截 TCP SYN 包。所以使用 TCP 包探測能夠通過大多數的網絡設備,使探測結果更加精確。

06 ICMP 有哪些內核參數

總結了下面一幅圖,其中比較常用的是 net.ipv4.icmp_echo_ignore_all,這是禁 ping 的一個參數,禁 ping 有幾種方法,可以參考這篇文章:Linux禁止ping以及開啓ping的方法

其他的參數大家有興趣也可以看看,遇到不懂的直接查這個圖即可。

07 ICMP 的問題

ICMP 協議是 IP 協議的助手,能夠爲 IP 協議提供相關的故障診斷和控制信息,但 ICMP 仍然不能爲 IP 提供可靠性,最常見的丟包(路由器緩衝區溢出)並不會觸發任何的 ICMP 信息,只能由其他協議如 TCP 來處理這種情況。

此外,正因爲 ICMP 能夠查詢網絡設備相關的配置信息,並且使用簡單,黑客們都比較青睞使用 ICMP 報文來構建攻擊報文。所以很多的網絡設備都會用防火牆來阻止 ICMP 報文,這讓很多診斷工具,比如上面介紹的幾種,都很難發揮用武之地。

常見的 ICMP 攻擊是 ICMP 泛洪攻擊,這是一種 DDoS 攻擊。簡單說就是攻擊者向一個子網的的廣播地址發送多個 ICMP echo 包,包的源地址僞裝成他想要攻擊的目的主機的 IP,然後該子網的所有主機的 ICMP reply 包都會送到被攻擊主機,該主機瞬時收到大量的 ICMP 回覆包,消耗大量資源,來不及處理,便會進入癱瘓或無法提供正常服務。

解決 ICMP 泛洪攻擊最簡單的方法就是禁 ping 了。只要禁 ping,不管黑客有多少肉機,他都無可奈何了。

當然還有更高級的攻擊的方式,以及更好的防護方式,道高一尺魔高一丈,大家有興趣可以查閱相關資料瞭解。

OK,以上就是今天的文章了,大家覺得不錯,不煩給我個「在看」或者分享哦。


後臺回覆“加羣”,帶你進入高手如雲交流羣

推薦閱讀:

Linux 硬盤結構長啥樣,瞭解一下

謹慎使用的 Linux 命令

史上最硬核的Linux依賴問題解決方案

一文搞懂HTTP+TCP的長連接和短連接

正確理解CPU使用率和平均負載的關係

和面試官之間關於操作系統的一場對弈

Linux 系統 UDP 丟包問題分析思路

如何擁有一臺屬於自己的私有云!

晉升、面試中繞不開的性能優化問題
史上最全Linux面試題(2020最新版)

什麼是物聯網?這裏有你需要了解的一切

Kubernetes的架構爲什麼是這個樣的?

任何人都能看得懂的網絡協議之ARP


喜歡,就給我一個“在看”


10T 技術資源大放送!包括但不限於:雲計算、虛擬化、微服務、大數據、網絡、Linux、Docker、Kubernetes、Python、Go、C/C++、Shell、PPT 等。在公衆號內回覆「1024,即可免費獲取!!

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章