1. 程式人生 > 其它 >mtr和traceroute的區別,以及為什麼traceroute不顯示路徑mtr卻可以顯示路徑

mtr和traceroute的區別,以及為什麼traceroute不顯示路徑mtr卻可以顯示路徑

最近工作主要都是網路策略的開通和網路測試,在測試的過程當中發現當網路不通時,用traceroute來看路由路徑的時候總是無法顯示出來,於是就換了個工具-mtr,發現mtr可以正常顯示出路由路徑,幫助我解決了網路測試當中遇到的很多問題,十分的方便,於是想要記錄一下,寫一篇有關traceroute和mtr兩個網路測試工具的區別和原理,達到融會貫通的效果。
首先先放兩張我在測試過程當中兩個工具的測試結果,可以看出兩者的結果存在的區別,很明顯mtr要比traceroute詳細並且好用很多,於是我就上網開始查閱資料,想弄清兩者的區別到底是什麼。


下面通過網上查閱到的資料,來解釋下有關兩者的區別,以及一些原理:


如果你traceroute或者mtr兩個工具都用過,肯定會比較偏向於使用mtr,因為總感覺traceroute不太好用,經常會出現***的情況。比如我們用IP: 61.135.185.32來做個測試,

使用traceroute得到的結果是:


但是如果用mtr:

通過mtr,我們可以很明確的看到從源到目的IP一共有12跳。但是traceroute卻是一堆的******************

在繼續下面的內容之前,要先講一下traceroute和mtr等這種網路探測工具的實現方法:

它們通過傳送具有較小ttl的探測資料包,然後偵聽來自閘道器的ICMP“TTL=0”的答覆,來跟蹤IP資料包到達Internet上的路由。我們從ttl為1開始探測,然後增加1,直到得到ICMP“埠不可達”(或TCP重置或icmp應答或無響應等)。大致過程如下圖:


主機1.1.1.10最後收到了1.1.1.1、2.2.2.2、2.2.2.10的icmp響應包,也就相當於知道了傳送資料包經過的路由。

知道了實現原理,現在我們來探究它們之間的區別,目前最容易想到的辦法:抓個包。

於是traceroute的資料包如下:(traceroute -n 61.135.185.32)

從資料包中可以看到:

traceroute預設請求使用UDP協議,而響應是ICMP協議。
traceroute發包方式是每次同一個TTL資料包連著發三次,並逐步增加TTL。而且請求埠和目的埠一直在變化。
再看一下mtr的資料包:(mtr -n -c 3 61.135.185.32)

從資料包中可以看到:

mtr預設請求和響應都是ICMP協議。
mtr發包方式是先每次傳送一個逐步增加TTL的資料包,再迴圈3次。
這樣對比下來之後,他們之間的區別顯而易見。

但是你可能還會有下面幾個疑問:

為什麼上圖traceroute第10跳之後,一直都是*?
為什麼傳送UDP請求包,會響應ICMP包?
為什麼目的是同一個IP,traceroute和mtr返回的路徑會不一樣?

問1:為什麼上圖traceroute第10跳之後,一直都是*?
從上面的抓包可以看出來,traceroute和mtr的發包方式是不一樣的,traceroute是udp包,mtr是icmp包。於是我們測試用traceroute傳送icmp包。通過man命令得知使用引數 -I(大寫的i)可使用ICMP探測。於是執行:

traceroute -n -I 61.135.185.32

神奇的發現結果和mtr一樣了!看到這裡,才打消我對traceroute的偏見。原來不是traceroute不好用,而是我使用的方法不當。至此,回到問題,我們大膽推測:從第10跳之後,第11跳這個路由器遮蔽了對UDP包的響應(甚至連ICMP都遮蔽了),而第12跳到了目標IP,它不是路由器,所以收到UDP之後,會嘗試尋找主機中對應埠的UDP服務,因為沒有此UDP服務,所以目的主機一般會通過icmp協議響應埠不可達,但這裡沒有返回任何資訊(可能是安全策略),到第13跳,還是到了目的主機,依舊沒有響應,如此直到第30跳結束(traceroute預設最多30跳)。接下來做個測試來驗證假設:

首先在虛擬機器192.168.2.104上tranceroute我的一臺雲主機198.x.x.82:

雲主機上沒有任何限制,所以可以看到tranceroute正常顯示,一共有16跳。接下來我在雲主機上配置了一條iptables規則如下:

我們再在虛擬機器192.168.2.104上執行tranceroute命令,結果顯示如下:
https://pic4.zhimg.com/80/v2-bb13dd1426c5a31a34edd4692605853f_720w.jpg
可以看到第16跳已經顯示為了,且後續的結果均為,因為後面的請求都到了這臺雲主機,在雲主機上抓包如下:

共收到 ttl=1到ttl=15的資料包各3個,即對應了tranceroute中的16-30的*。這足以證明之前的假設成立。
問2:為什麼傳送UDP請求包,會響應ICMP包?

這個東西,其實我也很好奇,但是靜下心來想一想,這個ICMP是路由器傳送的,並不是我們比較熟悉的主機。所以我們大膽推測:路由器在收到TTL為1的資料包時,會把該資料包TTL-1,此時TTL為0,就不再往後轉發了,而是給源主機發送一個ICMP響應,告訴主機這個資料包TTL為0了也沒到達目的地址。我們做個測試:使用nping命令傳送UDP包給目標主機,然後設定TTL為一個達不到目標主機的值,觀察到:

果真收到了路由器發來的ICMP響應。再試一下其他協議:


果然證明了剛剛的假設。路由器不管是什麼協議,只要TTL在它那為0了,它就會給源主機發送ICMP響應。當然,前提是路由器沒有禁用這個功能。

問3:為什麼目的是同一個IP,traceroute和mtr返回的路徑會不一樣?

上面可以看到traceroute預設使用的UDP協議,返回的內容和mtr不一樣,將traceroute改為icmp的方式探測,結果就一樣了。這說明使用不同的協議資料包,路由器的轉發會有區別。這時就引起了我的思考了,我們平時往往是因為業務服務出現問題了,才會用mtr去排查網路問題。所以假設你的業務是用HTTP協議的的話,它底層用的是tcp,而不是icmp。那麼你就應該用tcp的方式探測,否則你得到的結果很可能是不準確的。我們用mtr中的tcp模式探測:

mtr -n -T 61.135.185.32

發現與mtr預設的icmp探測的結果是不一樣的。這再一次證明了之前的理論:使用不同的協議資料包,路由器的轉發會有區別。*