對於 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 | 應答 | R | ping應答 |
3 | 目的不可達 | E | 很多細分,如主機/協議等 |
4 | 源端抑制 | E | 表示擁塞 |
5 | 重定向 | E | 表示最優的路由路徑 |
8 | 請求 | R | ping請求 |
9 | 路由器通告 | R | 告知路由器地址 |
10 | 路由器請求 | R | 請求路由器通告 |
11 | 超時 | E | TTL=0 |
12 | 參數問題 | E | 有問題的報文 |
注:R表示查詢報文,E表示差錯報文
進一步,對於每種類型,又可以根據代碼字段細分多種子類型,請看第二張表:
第二張表:類型細分表
類型 | 代碼 | 內容 | 解釋 |
---|---|---|---|
3 | 0 | 網絡不可達 | 沒有路由到目的地 |
3 | 1 | 主機不可達 | 已知但不可達的主機 |
3 | 2 | 協議不可達 | 未知的協議 |
3 | 3 | 端口不可達 | 未知的端口 |
3 | 4 | 要分片但設置了不分片位 | 路由器MTU限制需分片但無法分片 |
3 | 5 | 源路由失敗 | 中間跳不可達 |
3 | 13 | 管理禁止通信 | 被過濾策略禁止的通信 |
3 | 14 | 違反主機優先級 | src/dst/port不准許的優先級 |
3 | 15 | 優先級終止生效 | 在最小ToS之下 |
5 | 1 | 主機重定向數據報 | 指示一個可選的路由器/主機 |
11 | 0 | 在傳輸期間時間超時 | 跳數限制/TTL超時 |
11 | 1 | 分片重組時間超時 | 重組計時器超時之前,有分片未到達 |
12 | 0 | 指針指示差錯 | 字節偏移量指示第一個問題字段 |
12 | 2 | 錯誤的長度 | 數據包有無效的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 協議的網絡診斷工具,其中比較知名的就是 ping
和 traceroute
。這兩工具分別利用兩種類型的 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
,相對以上兩個其實是更好的網絡排障工具,只是用的人不多,導致它不太出名。之所以說它好,是因爲它結合了 ping
、nslookup
、traceroute
三款工具的特性。
關於 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面試題(2020最新版)
▼
喜歡,就給我一個“在看”
10T 技術資源大放送!包括但不限於:雲計算、虛擬化、微服務、大數據、網絡、Linux、Docker、Kubernetes、Python、Go、C/C++、Shell、PPT 等。在公衆號內回覆「1024」,即可免費獲取!!