1. 程式人生 > >[na]完全理解icmp協議

[na]完全理解icmp協議

代表性 工作 事先 執行 個人信息 自帶 時間信息 分享 大數

1.ICMP出現的原因

在IP通信中,經常有數據包到達不了對方的情況。原因是,在通信途中的某處的一個路由器由於不能處理所有的數據包,就將數據包一個一個丟棄了。或者,雖然到達了對方,但是由於搞錯了端口號,服務器軟件可能不能接受它。這時,在錯誤發生的現場,為了聯絡而飛過來的信鴿就是ICMP 報文。在IP 網絡上,由於數據包被丟棄等原因,為了控制將必要的信息傳遞給發信方。ICMP 協議是為了輔助IP 協議,交換各種各樣的控制信息而被制造出來的。

制定萬維網規格的IETF 在1981 年將RFC7922作為ICMP 的基本規格整理出來了。那個RFC792 的開頭部分裏寫著“ICMP 是IP 的不可缺少的部分,所有的IP 軟件必須實現ICMP協議。也是,ICMP 是為了分擔IP 一部分功能而被制定出來的。

技術分享圖片

2.ICMP的用途

在RFC,將ICMP 大致分成兩種功能:差錯通知和信息查詢。

技術分享圖片
[1]給送信者的錯誤通知;[2]送信者的信息查詢。

[1]是到IP 數據包被對方的計算機處理的過程中,發生了什麽錯誤時被使用。不僅傳送發生了錯誤這個事實,也傳送錯誤原因等消息。

[2]的信息詢問是在送信方的計算機向對方計算機詢問信息時被使用。被詢問內容的種類非常豐富,他們有目標IP 地址的機器是否存在這種基本確認,調查自己網絡的子網掩碼,取得對方機器的時間信息等。

## 3.ICMP作為IP的上層協議在工作
ICMP 的內容是放在IP 數據包的數據部分裏來互相交流的。也就是,從ICMP的報文格式來說,ICMP 是IP 的上層協議。但是,正如RFC 所記載的,ICMP 是分擔了IP 的一部分功能。所以,被認為是與IP 同層的協議。看一下RFC 規定的數據包格式和報文內容吧。

技術分享圖片

更加詳細地看一下數據包的格式吧。用來傳送ICMP 報文的IP 數據包上實際上有不少字段。但是實際上與ICMP 協議相關的只有7 個子段。

1)協議;2)源IP 地址;3)目的IP 地址;4)生存時間;這四個包含在IP 首部的字段。

5)類型;6)代碼;7)選項數據;這三個包含在ICMP數據部分的字段。

這裏面,1)協議字段值是1。2)和3)是用來交流ICMP 報文的地址信息,沒有特殊意義。對於理解ICMP 本身,重要的是5),6),7)三個字段。這裏面的可以稱為核心的重要字段是5)類型,6)代碼這兩個字段。所有ICMP 用來交流錯誤通知和信息詢問的報文,都是由類型和代碼的組合來表示的。RFC 定義了15種類型。“報文不可到達”這樣的錯誤通知和“回送請求”這樣的信息查詢是由類型字段來區分的。ICMP報文由類型來表達它的大概意義,需要傳遞細小的信息時由代碼來分類。進一步,需要向對方傳送數據的時候,用7)選項數據字段來放置。

可能的消息列表:

技術分享圖片

4.ICMP實現之MTU探索

所謂路徑MTU 探索,是探索與通信對方之間不用分片IP 數據包,就能交流的MTU 大小的功能。MTU大小是指計算機一次能夠送出去的數據的最大長度,基本上由網路的種類來決定。例如,以太網的話通常是1500 字節,使用PPPoE 的ADSL 通常是1492 字節。為了實現這個路徑MTU 探索,ICMP 被使用著。沿著流程,具體看一下Windows 的MTU 探索的樣子吧。
技術分享圖片

路徑MTU 探索的原理本身是非常簡單的。首先,Windows 向通信對方送IP 數據包時,先設置IP 首部的分片禁止標誌然後再送。這是路徑MTU 探索的基本。假如,Windows 將大於1000 字節的數據包送了出去,通信路徑上有MTU 從1500 字節變成1000 字節的地方。因此,那個路由器將不允許超過1000 字節的數據包通過,而進入MTU 是1000 字節的網路。路由器嘗試著將IP 數據包分片。但是因為數據包的分片禁止標誌是有效的,所以不能分片。該路由器就將該IP 數據包丟棄,並用ICMP 通知送信方“想分片,但不能分片”。這時路由器發送的ICMP的類型字段是3,代碼字段為4。這是“需要分片但不能分片,不能送至終點”的意思。而且,大多數路由器將在數據選項部裏填入不分片就能通過的MTU 大小。Windows 收到該ICMP 報文後就知道了不分片就能夠傳送的數據大小,並暫時將MTU 大小更換掉,然後繼續通信。

5.ICMP實現之改變路由

改變路由是指路由器向送信方計算機指示路徑改變這個功能。計算機根據自己的路由信息(路由表)來決定傳送目標。不知道發給誰好的時候,就將數據包發給設為默認網關的路由器。被指定為默認網關的路由器接收到數據包,發現將數據包發給局域網內的其它路由器會比較快的時候,將這一信息通過ICMP 通知發送方。這時使用的是,類型是5,代碼是1 的ICMP 改變路由報文。在選項數據部分裏寫著應該發送給的路由器IP 地址。Windows 收到這個報文後,重寫自己的路由表,與對方的通信將在一段時間裏經由被指定的路由器來實行。

技術分享圖片

6.ICMP實現之源點抑制

數據包集中到達某一路由器後,數據包因為來不及被處理,有可能被丟棄的情況。這時候,向送信方發送的是ICMP 源點抑制報文,用來使送行方減慢發送速度。

技術分享圖片

7.ICMP實現之ping命令

ping 命令用來在IP 層次上調查與指定機器是否連通,調查數據包往復需要多少時間。為了實現這個功能,ping 命令使用了兩個ICMP 報文。
技術分享圖片

1.向目標服務器發送回送請求。
首先,向目標服務器發出回送請求(類型是8,代碼是0)報文(同2)。在這個回送請求報文裏,除了類型和代碼字段,還被追加了標識符和序號字段。標識符和序號字段分別是16 位的字段。ping 命令在發送回送請求報文時,在這兩個字段裏填入任意的值。對於標識符,應用程序執行期間送出的所有報文裏填入相同的值。對於序號,每送出一個報文數值就增加1。而且,回送請求的選項數據部分用來裝任意數據。這個任意數據用來調整ping 的交流數據包的大小。

2.鸚鵡學舌一樣返回回送回答。
計算機送出的回送請求到達目標服務器後,服務器回答這一請求,向送信方發送回送請求(類型是0,代碼是0)(同3)。這個ICMP 回送回答報文在IP 層來看,與被送來的回送請求報文基本上一樣。不同的只是,源和目標IP 地址字段被交換了,類型字段裏填入了表示回送回答的0。也就是,從送信方來看,自己送出的ICMP 報文從目標服務器那裏象鸚鵡學舌那樣原樣返回了。
送信方的計算機可以通過收到回送回答報文,來確認目標服務器在工作著。進一步,記住發送回送請求報文的時間,與接收到回送回答報文的時間一比較,就能計算出報文一去一回往復所需要的時間(同4)。但是,收到的回送回答報文裏寫的只是類型和代碼的話,發送方計算機將無法判斷它是否是自己發出去請求的回答。因此,前面說到的標識符和序號字段就有它的意義了。將這兩個值與回送回答報文中的相同字段值一比較,送行方計算機就能夠簡單地檢測回送回答是否正確了。執行ping 命令而調查的結果沒什麽問題的話,就將目標服務器的IP 地址,數據大小,往復花費的時間打印到屏幕上。

3.用ping 命令不能確定與對方連通的原因大致有三個。
1)目標服務器不存在;2)花在數據包交流上的時間太長ping 命令認為超時;3)目標服務器不回答ping 命令。如果是原因2),通過ping 命令的選項來延長到超時的等待時間,就能正確顯示結果了。如果原因是1)或3)的話,僅憑ping 命令的結果就不能判斷是哪方了。正如這樣,ping 命令不一定一定能判斷對方是否存在。

8.ICMP實現之traceroute命令

為了調查到通信對方的路徑現在是怎麽樣了,使用的是traceroute 命令。它與ping 並列,是代表網絡命令。這個traceroute 也是ICMP 的典型實現之一。
技術分享圖片

1.執行tracert命令。
在Windows 上執行tracert 命令後,首先計算機向目的服務器發送IP 數據包。Windows 上使用的是與ping 同樣的ICMP 回送請求報文。但是,有一點和通常的回送請求不一樣。那是,最初將IP 首部的TTL(生存時間)字段設為1 這一點。
路由器每轉送一次數據包就將TTL 的值減1。當TTL 變為0 的時候,按規定將丟棄這個數據包。正如這樣,與其說TTL 是時間,還不如說TTL 是經過路由器的個數。對於計算機發送出去的數據包,只要它與目標服務器不在同一局域網內,一定會被哪兒的路由器中繼。這時如果TTL 的值是1,由於路由器的處理會變為0,則該數據包將會被丟棄(同2)。

2.用超時報文來通知送信方。
路由器丟棄數據包的同時,用ICMP 報文來通知錯誤。這時使用的ICMP 報文是,類型為11,代碼為0 的ICMP 超時報文。而且在選項數據字段裏,將填入原先數據包的IP 首部和ICMP 的開始8 字節。正如ping 命令的時候看到的,ICMP 回送請求的先頭8 字節裏包含了標識符和序號字段。因此,送信方的計算機看了超時報文後,就知道是針對自己發出的回送請求的錯誤通知。
計算機接到針對第一個數據包的ICMP 超時報文後,接下來將TTL 加1(TTL=2)並同樣地送出(同3)。這次通過第一個路由器,TTL 變為1,到達第二個路由器。但是第二個路由器象前面一樣,由於TTL變為0,將不能轉發該包。因此,同第一個路由器一樣,將該包丟棄,並返回ICMP 超時報文。以後,收到錯誤的發送方計算機將TTL 加1,重復同樣的工作(同4)。

3.只有目標服務器的反應不同。
如此一個一個增加TTL,某個時候ICMP 回送請求報文將到達最終的目標服務器。這時,只有目標服務器與途中的路由器不同,不返回ICMP 超時報文。為什麽呢?因為即使目標服務器收到TTL 為1 的數據包也不會發生錯誤。
作為代替處理,服務器針對送信方計算機發出的ICMP 回送請求報文,返回ICMP 回送回答報文。也就是,送信方計算機與服務器之間,與ping 命令的執行一樣了(同5)。得到了ICMP 回送回答報文的送信方知道了路經調查已經到了目標服務器,就結束了tracert 命令的執行(同6)。像這樣,通過列出中途路由器返回的錯誤,就能知道構成到目標服務器路徑的所有路由器的信息了。

4.操作系統不同則實現方法略微不同。
到這裏,以Windows 上的tracert 命令為例看了原理,有些別的操作系統的traceroute 命令的原理略微不同。
具體來說,也有用向目標發送UDP 數據包代替ICMP 回送請求報文來實現的。雖說是用UDP,但途中的路由器的處理與図 8完全相同。只是UDP 數據包到達目標後的處理不同。目標計算機突然收到與通信無關的數據包,就返回ICMP 錯誤,因此根據返回數據包的內容來判斷命令的中止。

9.ICMP實現之端口掃描

所謂的端口掃描就是檢查服務器不需要的端口是否開著。服務器管理者用來檢查有沒有安全上有問題的漏洞開著。不是象ping 和traceroute 那樣是操作系統自帶的工具,需要利用網絡工具才行。

端口掃描大致分為“UDP 的端口掃描”和“TCP 的端口掃描”兩種。這裏面,與ICMP 相關的是UDP一邊。使用TCP 的通信,通信之前必定要先遵循三向握手的程序。因此,只要邊錯開端口號邊嘗試TCP連接就能調查端口的開閉。不特別需要ICMP。與此相對,UDP 沒有這樣的連接程序。因此,調查端口是否打開需要想點辦法。這樣,被使用的是ICMP。根據ICMP 規格,UDP 數據包到達不存在的端口時,服務器需要返回ICMP 的“終點不可達”之一的“端口不可達”報文。

技術分享圖片
具體來說,向希望調查的服務器發送端口號被適當指定了的UDP 數據包。這樣,目標端口沒開著的話,服務器就返回ICMP 端口不可達報文。返回的ICMP 數據包的選項數據字段裏放入著,送信方送出的UDP 數據包的IP 首部與UDP 首部的頭8 個字節。送信方通過這個信息來辨別該錯誤通知是針對哪個UDP 數據包的,並判斷端口是否打開著。

UDP 端口掃描一邊一個一個錯開端口號,一邊持續著這個通信。這樣,就知道了哪個端口是“好象開著的”了。但是,UDP 端口掃描與TCP 端口掃描有很大區別的地方。那就是,即使ICMP 端口不可達報文沒有返回,也不能斷定端口開著。端口掃描除了被管理員用來檢查服務器上是否有開著的漏洞,作為黑客非法訪問的事先調查,對服務器實施的情況也是很多的。需要非常小心地來使用。

10.ICMP和安全的關系

10.1 為什麽停止方便的ICMP?

為什麽有停止ICMP 使用的設定項目呢?理由只有一個,那就是確保安全。雖然ICMP 是非常便利的協議,但黑客在嘗試非法訪問的時候會被惡意利用。由於ICMP 被惡意使用而遭受損害的用戶正在不斷增加之中,因此有了限制ICMP 使用的意見。

10.2 ICMP數據包攻擊

那麽實際上,ICMP 被怎樣惡意使用的呢?想考慮安全相關問題,不知道這個就開不了頭。看兩個典型的惡意使用例子吧。

作為惡意使用ICMP 的最有代表性的例子,也就是所謂的 “ping 洪水”的攻擊。它利用ping 的原理,向目標服務器發送大量的ICMP 回送請求。這是黑客向特定的機器連續發送大量的ICMP 回送請求報文。目標機器回答到達的ICMP 回送請求已經用盡全力了,原來的通信處理就變得很不穩定了。進一步,目標機器連接的網絡也可能由於大量的ICMP 數據包而陷入不可使用的狀態。

與ping 洪水相似,以更加惡劣的使用方法而聞名的是稱為“smurf”的攻擊手法。smurf 同樣,黑客惡意的使用ICMP 回送請求報文。這一點同ping 洪水是相同的。不過在smurf,對ICMP 回送請求實施了一些加工。源IP 地址被偽裝成攻擊對象服務器的地址,目標地址也不是攻擊對象服務器的地址,而是成為中轉臺的網絡的廣播地址。
來具體看一下smurf 攻擊的流程吧!
技術分享圖片

黑客發送偽裝了的ICMP 回送請求後,到達在作為踏板的網絡的入口處的路由器。這樣,路由器將回送請求轉發給網內所有的計算機(同2)。假如有100 臺計算機,回送請求將到達100 臺所有的計算機。收到回送請求的計算機對此作出反應,送出回送回答報文(同3)。這樣,黑客送出的一個ICMP回送請求報文,一下子增加到了100 倍。
這樣增加的ICMP 回送回答報文面向的不是黑客的計算機,而是偽裝成回送請求的源IP 地址的攻擊對象服務器。變成到達了,從幾百臺計算機發出的巨大數量的ICMP 回送回答。smurf 與ping 洪水攻擊不同,因為到達服務器的是ICMP 回送回答,服務器不用返回回答。但是為了處理大量的ICMP,服務器承受了大量的負載。網路被撐爆了也是一樣的(同4)。

除此之外,還有很多各種各樣ICMP 被惡意使用的例子。例如,通知錯誤或詢問信息本身,也有被黑客用來傳遞謊言的可能性。同用信鴿來擴展謊言的傳播,通過傳遞與事實不同的信息來使人判斷錯誤是一樣的。而且,反過來也有傳遞錯誤信息而變成問題的例子。例如,在實現篇裏看到的端口掃描,黑客就可以利用它來進行攻擊對象的調查。進一步,推翻了“ICMP 是用來控制IP 的”這一常識的惡意使用方法也登場了。就是將ICMP 的選項數據部分作為信息搬運工的手法。黑客將這種工具隱藏在服務器裏,從外部控制服務器,將用戶的個人信息和重要的情報偷盜出來。如上,僅從安全的方面來說,ICMP 是有百害而無一利的。

10.3 阻止ICMP後將陷入困境

“那阻止所有的ICMP 不就行了嗎!”可能有讀者會這樣認為。不過那就太輕率了。ICMP 作為支持IP的協議是需要的,所以被制作了。即使沒有,也不是說IP 通信本身就完全不行了,實際上會出現幾個難辦的情況。
它的典型例子就是稱為“黑洞路由器”的問題。所謂黑洞路由器,就是通信路徑上的IP 數據包不留痕跡的消失了的現象。原因是,實現篇裏說明的路徑MTU 探索功能不起作用了。

技術分享圖片

假設通信路徑上有因為MTU 大小不同而需要分片的路由器。而且,計算機和路由器之間,為了安全上的原因,設置了阻止ICMP 報文通過的防火墻。這種情況下,計算機實行路徑MTU 探索將會怎麽樣呢?

1.不能調整數據包長度
如果是傳送路徑上不需要分片大小的IP 數據包,它將會毫無問題地到達對方。另一方面,數據包的長度是需要分片的時候,發送就會有問題。
正如實現篇看到的,這樣的數據包到達連接在不同大小MTU 的網絡的路由器後,路由器將用ICMP 終點不可達報文來通知發送方。本來的處理是,送信方接收到該ICMP 報文,根據路徑MTU 探索處理調整MTU 大小後繼續通信。但是,這次的例子,ICMP 報文被路經中的防火墻隔斷了。路徑MTU 探索功能不起作用,MTU 的大小也就不能調整了。

2.不知道原理就不可能理解
最近從局域網的計算機通過ADSL 服務訪問萬維網時,經常看到這個黑洞路由器現象。ADSL 線路的MTU 大小,寬帶路由器的設定,Windows 的路徑MTU 探索功之間互相關聯引起了這個現象。糟糕的是,即使有黑洞路由器,也不是完全不能通信這一點。不管怎麽樣說,被吸進去的只是長度是需要分片的IP 數據包。也就是,考慮一下WEB 訪問,連接WEB 服務器時是沒有問題的,以文字為主體的頁面也大都能被顯示,但是含有比較大圖像的頁面不能被顯示。黑洞路由器就由這種復雜奇怪的現象表現出來了。如果不知道路徑MTU 探索和黑洞路由器的原理的話,碰到這種現象,可能連猜想原因都很困難了。

3.即使阻止了客戶端也沒問題
如最初所見,在現實的萬維網上,如果事先使所有的ICMP 功能有效的話,就會給了黑客各種各樣的機會,安全上就會有問題了。
另一方面,如果一個一個阻止了的話,不僅非常不方便,而且還會發生黑洞路由器等問題。那麽,如何充分運用ICMP 才行呢?客戶端,服務器,還有路由器,從各個方面來看一下。
首先從客戶端開始。最近的寬帶路由器和個人防火墻,通過設置來阻止ICMP 的很多。但是,初期設置是千差萬別的。阻止全部ICMP 的也有,反過來的也有。其中,只允許ping 命令等一部分ICMP 報文通過的也有。
原來,對於安全的考慮方法是根據環境的不同而變化巨大的,並不是一定要這樣才行的。但是,最近的傾向是,使連在萬維網上的個人計算機不應答沒有必要的ICMP 報文。例如Windows XP 的情況下,使用操作系統自帶的個人防火墻的話,默認是將外部來的所有ICMP 報文隔斷。
那麽路由器怎麽樣呢?萬維網中的路由器,不小心阻斷了ICMP 的話,會發生黑洞路由器等問題。還有,大量的數據包湧過來的時候,如果不發送ICMP 源點抑制報文,處理速度就會跟不上。路由器的話,這樣的情況以外,再加上考慮周圍網絡環境的基礎上,再來判斷是否阻斷不需要的或者可能造成攻擊的ICMP數據包比較好吧。
服務器就比較難判斷了。例如,不讓它回應ping 命令的話,連不上服務器的時候,就缺少了調查的有效手段。但是,有受到ping 洪水攻擊的可能性也是事實。這些只能由管理者來判斷了。

參考

[na]完全理解icmp協議