昨天突然被問到traceroute的原理,一時竟也說不出來,有些命令平時雖然經常在用,但實際原理確並不瞭解,趁這次機會就來梳理一下。 traceroute:是網路診斷中,用來分析IP包經過那些路由的命令。 學前知識: IP包中有個欄位TTL,這個是最大跳轉次數的欄位,每經過一個路由器,值會-1,當值 ...
昨天突然被問到traceroute的原理,一時竟也說不出來,有些命令平時雖然經常在用,但實際原理確並不瞭解,趁這次機會就來梳理一下。
traceroute:是網路診斷中,用來分析IP包經過那些路由的命令。 學前知識: IP包中有個欄位TTL,這個是最大跳轉次數的欄位,每經過一個路由器,值會-1,當值為0的時候,這個包就會被路由器丟棄,並返回ICMP-超時包給請求主機。 實現原理: 1、traceroute首先發出三個UDP包(發出三個主要是為了統計,這裡可以不用太在意),其TTL的欄位為1,目的地為目標主機的IP,該UDP包在經過路由器-1時,TTL值會被設置為0該包會被丟棄,並返回ICMP-超時給請求主機; 2、在收到路由器1發來的"ICMP-超時"包時,traceroute會繼續發出三個UDP包,其TTL的欄位被設置為2,該UDP包順利的經過了路由器-1,在到達路由器-2時,TTL值被值為0,隨之丟棄,返回ICMP-超時包給請求主機; …………繼續重覆,每收到一個返回ICMP-超時的包,則繼續發出TTL值+1的UDP包; 3、就這樣,在經歷了4個路由器後,TTL=5的UDP包,歷經千山萬水,終於來到了目的主機,大家可能會覺得目的主機會欣然接受這個UDP包,但實際不是,目的主機做瞭如下的處理:
- 丟棄(不認識你,狗帶)
- 返回ICMP-目標不可達包給請求主機
下麵為了加深一下印象,結合tcpdump命令,對traceroute過程進行一些驗證
主要觀察過程中[發出的UDP包] [路由器返回的ICMP-超時包] [目的主機返回的ICMP-目標不可達包] 1、使用命令,監聽目的主機相關的包tcpdump -i eno33554984 -vvnn host 119.146.184.982、使用traceroute命令對目的主機發起請求
[root@www ~]#traceroute 119.146.184.98 traceroute to 119.146.184.98 (119.146.184.98), 30 hops max, 60 byte packets 1 192.168.0.1 (192.168.0.1) 2.217 ms 1.741 ms 1.509 ms 2 116.24.132.1 (116.24.132.1) 11.348 ms 11.117 ms 11.287 ms 3 113.106.47.93 (113.106.47.93) 7.111 ms 6.848 ms 7.123 ms 4 5.107.38.59.broad.fs.gd.dynamic.163data.com.cn (59.38.107.5) 6.921 ms 6.712 ms 6.434 ms 5 183.59.12.153 (183.59.12.153) 8.635 ms 7.664 ms 7.593 ms 6 183.61.222.102 (183.61.222.102) 11.923 ms 10.220 ms 9.423 ms 7 119.146.184.198 (119.146.184.198) 15.779 ms 119.146.184.94 (119.146.184.94) 47.902 ms 119.146.184.62 (119.146.184.62) 16.571 ms #################################### #返回結果解釋: #列1:[1] 經過的路由器序號; #列2:[192.168.0.1 ] 路由器IP(也叫網關); #列3:[(113.106.47.93) ] 即括弧內的內容,具體用途不明,有懂的可以解釋一下哈; #列4:[7.111 ms] 返回的時間,這裡也可以發現,一共有3個時間,還想起來嗎?traceroute每次發出的UDP包都是3個一起發的; 需要註意的是,大家可以看到最後一列,是有3個地址的,其實也不難理解,路由器是會根據實際情況尋找合適的路徑;3、現在來看看tcpdump採集的結果,觀察由請求主機發出的UDP包
18:56:27.892318 IP (tos 0x0, ttl 1, id 10584, offset 0, flags [none], proto UDP (17), length 60) 192.168.0.200.39914 > 119.146.184.98.33434: [bad udp cksum 0xf19e -> 0xfaae!] UDP, length 32 18:56:27.892798 IP (tos 0x0, ttl 1, id 10585, offset 0, flags [none], proto UDP (17), length 60) 192.168.0.200.38541 > 119.146.184.98.33435: [bad udp cksum 0xf19e -> 0x000b!] UDP, length 32 18:56:27.893869 IP (tos 0x0, ttl 1, id 10586, offset 0, flags [none], proto UDP (17), length 60) #################################### #返回結果解釋: #可以看到我們的主機,往119.146.184.98發出TTL=1的UDP包,而且是三個;這裡大家可以奇怪,不是說經過的網關會返回ICMP-超時的包嗎?為啥沒看到呢? #為什麼呢? #因為ICMP-超時這個包,不是119.146.184.98返回的,那是誰返回的呢?回憶一下上文!是路由器!所以這裡我們需要使用tcpdump指定路由器的ip來抓包。
4、觀察路由器返回的ICMP-超時包
tcpdump -i eno33554984 -vvnn host 116.24.132.1 #溫馨提示:執行完這個命令後,你需要重新執行traceroute 119.146.184.98命令才能進一步觀察116.24.132.1返回的包哦 19:02:26.210530 IP (tos 0xc0, ttl 254, id 52121, offset 0, flags [none], proto ICMP (1), length 56) 116.24.132.1 > 192.168.0.200: ICMP time exceeded in-transit, length 36 IP (tos 0x0, ttl 1, id 10619, offset 0, flags [none], proto UDP (17), length 60) 192.168.0.200.43604 > 119.146.184.98.33437: UDP, length 32 #################################### #返回結果解釋: #這裡我們選擇了採集第二跳的路由器地址116.24.132.1的數據包(為什麼不用第一跳呢?因為第一跳往往是自己家裡的路由器地址,這個地址的包會非常多,不容易觀察到實驗#結果) #從返回的結果中,我們可以看到第二跳路由器確實返回ICMP time exceeded包,實際上會有3個,就不一一列舉了。
5、觀察目的主機返回的ICMP-目標不可達包
#在 [root@www ~/test_traceroute]#tcpdump -i eno33554984 -vvnn host 119.146.184.98 命令返回的結果中查看 18:56:27.972224 IP (tos 0x0, ttl 248, id 20689, offset 0, flags [none], proto ICMP (1), length 56) 119.146.184.98 > 192.168.0.200: ICMP 119.146.184.98 udp port 33455 unreachable, length 36 IP (tos 0x0, ttl 2, id 10605, offset 0, flags [none], proto UDP (17), length 60) 192.168.0.200.56215 > 119.146.184.98.33455: UDP, length 32 #################################### #返回結果解釋: #在返回結果中最後的地方可以看到ICMP 119.146.184.98 udp port 33455 unreachable的字樣。
最後再總結一下traceroute常見返回結果的分析: 1、大家在練習的時候,可能第一個想到的就是拿一些知名網站來測試,下麵我們就拿百度的一個ip地址來測試
[root@www ~]#traceroute -m 10 14.215.177.38 traceroute to 14.215.177.38 (14.215.177.38), 10 hops max, 60 byte packets 1 192.168.0.1 (192.168.0.1) 2.395 ms 2.063 ms 1.583 ms 2 116.24.132.1 (116.24.132.1) 36.296 ms 36.939 ms 36.706 ms 3 183.56.71.225 (183.56.71.225) 6.550 ms 6.304 ms 6.396 ms 4 183.56.66.93 (183.56.66.93) 5.716 ms 5.491 ms 5.713 ms 5 183.56.64.50 (183.56.64.50) 8.059 ms 7.733 ms 7.513 ms 6 * * * 7 14.29.121.194 (14.29.121.194) 9.082 ms 14.29.121.198 (14.29.121.198) 8.977 ms 14.29.121.206 (14.29.121.206) 9.700 ms 8 * * * 9 * * * 10 * * * #################################### 返回結果解釋: *號代表發出去的UDP沒有收到相應的ICMP-超時包,這個主要是因為某些路由器安全原因,拒絕返回ICMP-超時包。
所以大家可以看到第六跳的記錄都是*號,說明,第六跳的路由器沒有返回ICMP-超時包。
同時存在如下一點疑問:
為什麼traceroute沒有結束,一直不斷的檢測呢?(我們在命令中指定檢測10跳的參數),如果你有耐心,可以指定-m 128參數,會發現traceroute始終無法自動結束,每次都需要耗盡所有的檢測次數。
2、那麼,為什麼8 9 10跳返回的也是*呢?這裡合理推測一下:
- 我所在的網路,訪問百度這個網站,至少需要7跳才能到達,在第七條以後,TTL=8的UDP包可能已經到達百度的主機,那麼為什麼traceroute沒有結束呢?
- 一個合理的推測,就是百度14.215.177.38這個主機直接丟棄了我們的UDP包,拒絕返回ICMP-目標不可達包;
- 由於traceroute一直沒有收到ICMP-目標不可達包,所以他會一直生成UDP包,並增加TTL的值發出,直到達到我們指定的檢測跳數(本例中,我們指定的跳數=10)。
- 大家也可以使用如下命令
[root@www ~/test_traceroute]#tcpdump -i eno33554984 -vvnn host 14.215.177.38這個命令可以採集到14.215.177.38的相關包,可以看到只有發出去的包,沒有返回的包,也基本可以驗證我們的推測。