1.ICMP出現的緣由
在IP通訊中,常常有數據包到達不了對方的狀況。緣由是,在通訊途中的某處的一個路由器因爲不能處理全部的數據包,就將數據包一個一個丟棄了。或者,雖然到達了對方,可是因爲搞錯了端口號,服務器軟件可能不能接受它。這時,在錯誤發生的現場,爲了聯絡而飛過來的信鴿就是ICMP 報文。在IP 網絡上,因爲數據包被丟棄等緣由,爲了控制將必要的信息傳遞給發信方。ICMP 協議是爲了輔助IP 協議,交換各類各樣的控制信息而被製造出來的。html
制定萬維網規格的IETF 在1981 年將RFC7922做爲ICMP 的基本規格整理出來了。那個RFC792 的開頭部分裏寫着「ICMP 是IP 的不可缺乏的部分,全部的IP 軟件必須實現ICMP協議。也是,ICMP 是爲了分擔IP 一部分功能而被制定出來的。緩存
2.ICMP的用途
在RFC,將ICMP 大體分紅兩種功能:差錯通知和信息查詢。安全
[1]給送信者的錯誤通知;[2]送信者的信息查詢。服務器
[1]是到IP 數據包被對方的計算機處理的過程當中,發生了什麼錯誤時被使用。不只傳送發生了錯誤這個事實,也傳送錯誤緣由等消息。網絡
[2]的信息詢問是在送信方的計算機向對方計算機詢問信息時被使用。被詢問內容的種類很是豐富,他們有目標IP 地址的機器是否存在這種基本確認,調查本身網絡的子網掩碼,取得對方機器的時間信息等。wordpress
3.ICMP做爲IP的上層協議在工做
ICMP 的內容是放在IP 數據包的數據部分裏來互相交流的。也就是,從ICMP的報文格式來講,ICMP 是IP 的上層協議。可是,正如RFC 所記載的,ICMP 是分擔了IP 的一部分功能。因此,被認爲是與IP 同層的協議。看一下RFC 規定的數據包格式和報文內容吧。工具
更加詳細地看一下數據包的格式吧。用來傳送ICMP 報文的IP 數據包上實際上有很多字段。可是實際上與ICMP 協議相關的只有7 個子段。大數據
1)協議;2)源IP 地址;3)目的IP 地址;4)生存時間;這四個包含在IP 首部的字段。spa
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 源點抑制報文,用來使送行方減慢發送速度。
先簡單看一下源點抑制的流程。在用來處理到達數據包的緩存將要溢出的時候,路由器將發送ICMP報文。這時使用的是類型是4,代碼是0 的源點抑制ICMP 報文。Windows 接到路由器發來的源點抑制報文後,主動擴大數據包的送信間隔來下降送信速度。接着,在報文到達(有效)的期間,持續這一動做。這樣就能防止路由器陷入不斷丟棄數據包的狀態。
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 洪水攻擊的可能性也是事實。這些只能由管理者來判斷了。