最近工作主要都是網絡策略的開通和網絡測試,在測試的過程當中發現當網絡不通時,用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探測的結果是不一樣的。這再一次證明了之前的理論:使用不同的協議數據包,路由器的轉發會有區別。*