排查網絡問題,請務必掌握這款工具
traceroute 介紹
traceroute 就如同它的名字一樣,能夠追蹤到一個網絡數據包傳輸經過的路由器路徑。這是 Linux 上的一個命令,Windows 上類似的命令是 tracert。
tracert 默認使用 ICMP 包探測,traceroute 使用 UDP 包,也可以使用 ICMP 和 TCP 包探測,分別帶上參數 -I和 -T 即可。
traceroute 主要用途
traceroute 利用 ICMP 差錯報文,主要用來確定這幾件事:
- 確定通信雙方路徑上經過的路由器設備
- 確定 UDP 包是否成功達到目的地
- 發現路徑 MTU
(1) 確定通信雙方路徑上經過的路由器設備 。利用 IP 包的 TTL 字段和超時類型的 ICMP 報文來實現。首先, traceroute 向目的地發送 IP 包,剛開始的時候,將 TTL 設置為 1,當經過第一個路由器時,TTL -1 = 0 引發超時錯誤,第一個路由器回復 ICMP 超時報文,源主機就可以知道路徑第一個路由器的信息,隨后 TTL 被設置為 2、3、4, ...,直到到達目的地,這樣,沿途每個路由器都會向源主機回復 ICMP 超時報文, traceroute 就可以拿到所有的路由器信息了。
不過這里要 注意 ,并不是所有路由器都會返回 ICMP 報文,因為出于安全性考慮,大多數防火墻以及啟用了防火墻功能的路由器都默認配置為不返回任何 ICMP 報文,管理員也會主動配置,所以這時使用 traceroute 就不一定能拿到所有路由器信息了。
(2) 確定包是否成功達到目的地 。使用上面的方法能拿到路由器信息,但并不能確定發的包是否到達目的地。traceroute 通過設置所發 UDP 包的端口號來解決了這個問題,因為 UDP 包的可用端口號范圍 <3000,只要在發送 UDP 包的時候填入一個 >3000 的端口號,當包到達了目的地,但是由于端口不匹配,就會返回一個端口不可達的 ICMP 報文,這樣源主機就可以確定包確實到了目的地了。
(3) 發現路徑 MTU 。利用了 “需要分片但設置了不分片位” 類型的 ICMP 報文,如果某個源主機在發送一個 IP 包之前,對該 IP 包中的首部字段 DF 位設為 1,也就是“分片禁止位=1”,表示該包在傳輸的過程中不允許分片,如果中間某個路由器允許傳輸的最大路徑 MTU 小于該包大小,就需要分片才能傳輸,但是由于設置了不分片位,路由器會將該包丟棄,并向源主機發送一個攜帶 MTU 信息的 ICMP 包,提醒源主機下次發包的大小不應超過該 MTU 的值。traceroute 就可以利用這種類型報文來逐一地確認傳輸路徑上各個路由器之間的 MTU 值。
常用命令案例
traceroute 使用格式是:
traceroute「參數」「主機」
- # traceroute --help
- Usage:
- traceroute [ -46dFITnreAUDV ] [ -f first_ttl ] [ -g gate,... ] [ -i device ] [ -m max_ttl ] [ -N squeries ] [ -p port ] [ -t tos ] [ -l flow_label ] [ -w MAX,HERE,NEAR ] [ -q nqueries ] [ -s src_addr ] [ -z sendwait ] [ --fwmark=num ] host [ packetlen ]
其中,選項主要有:
- -4:使用 IPv4
- -6:使用 IPv6
- -d:開啟 socket 層的debug
- -F:設置不分片位
- -f first_ttl:設置第一跳 TTL 值,默認是1
- -g gate:指定網關 gate 可路由的最大數據包數
- -I:使用 ICMP echo 包探測
- -T:使用 TCP SYN 包探測
- -m max_ttl:設置 TTL 最大跳數,默認是 30
- -N squeries:同時發送探測包的數量
- -n:不進行 IP 到域名的解析
- -p port:設置目的端口的值(默認是 33434),ICMP 就是設置初始序列號(默認為1 )
- -t tos:設置 TOS 值(IPv6 是 TC 值)
- -w max,here,near:設置等待每一跳響應的時間,有三個值,max表示最大不能超過的時間(默認是5s),here表示同一跳時間的參考因子,near表示下一跳參考因子(這兩個值意義不大)
- -q nqueries:設置每一跳探測的次數,默認是 3
- -r:繞過中間的路由探測,直接將包送達目的地
- -s srcaddr:使用 srcaddr 作為發送包的源地址
- --mtu:發現路徑 MTU,等價于參數 -F-N1
① 最簡單的用法
traceroute www.baidu.com
- [root@localhost ~]# traceroute www.baidu.com
- traceroute to www.baidu.com (61.135.169.125), 30 hops max, 40 byte packets
- 192.168.74.2 (192.168.74.2) 2.606 ms 2.771 ms 2.950 ms
- 211.151.56.57 (211.151.56.57) 0.596 ms 0.598 ms 0.591 ms
- 211.151.227.206 (211.151.227.206) 0.546 ms 0.544 ms 0.538 ms
- 210.77.139.145 (210.77.139.145) 0.710 ms 0.748 ms 0.801 ms
- 202.106.42.101 (202.106.42.101) 6.759 ms 6.945 ms 7.107 ms
- 61.148.154.97 (61.148.154.97) 718.908 ms * bt-228-025.bta.net.cn (202.106.228.25) 5.177 ms
- 124.65.58.213 (124.65.58.213) 4.343 ms 4.336 ms 4.367 ms
- 202.106.35.190 (202.106.35.190) 1.795 ms 61.148.156.138 (61.148.156.138) 1.899 ms 1.951 ms
- * * *
- * * *
- [root@localhost ~]#
可以看到,第一行輸出探測的主機名和對應 IP,允許探測的最大跳數,以及發送的數據包字節數,后面每一行表示每一跳的信息,包括 IP 信息,3 個時延值(因為每一跳默認會發 3 次探測包)。
最后還會看到三個 ***,表示當前這一跳被防火墻過濾,探測包被丟棄。
② 設置 TTL 最大跳數:-m max_ttl
默認 TTL 是 30 跳。
- [root@localhost ~]# traceroute -m 10 www.baidu.com
- traceroute to www.baidu.com (61.135.169.105), 10 hops max, 40 byte packets
- 192.168.74.2 (192.168.74.2) 1.534 ms 1.775 ms 1.961 ms
- 211.151.56.1 (211.151.56.1) 0.508 ms 0.514 ms 0.507 ms
- 211.151.227.206 (211.151.227.206) 0.571 ms 0.558 ms 0.550 ms
- 210.77.139.145 (210.77.139.145) 0.708 ms 0.729 ms 0.785 ms
- 202.106.42.101 (202.106.42.101) 7.978 ms 8.155 ms 8.311 ms
- bt-228-037.bta.net.cn (202.106.228.37) 772.460 ms bt-228-025.bta.net.cn (202.106.228.25) 2.152 ms 61.148.154.97 (61.148.154.97) 772.107 ms
- 124.65.58.221 (124.65.58.221) 4.875 ms 61.148.146.29 (61.148.146.29) 2.124 ms 124.65.58.221 (124.65.58.221) 4.854 ms
- 123.126.6.198 (123.126.6.198) 2.944 ms 61.148.156.6 (61.148.156.6) 3.505 ms 123.126.6.198 (123.126.6.198) 2.885 ms
- * * *
- * * *
- [root@localhost ~]#
可以看到,最大跳數被該為 10 跳。
③ 每一跳不進行 DNS 解析,不顯示主機名:-n
traceroute-n www.baidu.com
- [root@localhost ~]# traceroute -n www.baidu.com
- traceroute to www.baidu.com (61.135.169.125), 30 hops max, 40 byte packets
- 211.151.74.2 5.430 ms 5.636 ms 5.802 ms
- 211.151.56.57 0.627 ms 0.625 ms 0.617 ms
- 211.151.227.206 0.575 ms 0.584 ms 0.576 ms
- 210.77.139.145 0.703 ms 0.754 ms 0.806 ms
- 202.106.42.101 23.683 ms 23.869 ms 23.998 ms
- 202.106.228.37 247.101 ms * *
- 61.148.146.29 5.256 ms 124.65.58.213 4.386 ms 4.373 ms
- 202.106.35.190 1.610 ms 61.148.156.138 1.786 ms 61.148.3.34 2.089 ms
- * * *
- * * *
- [root@localhost ~]#
可以看到相關的主機名已經去除。
④ 設置 UDP 端口號為 6666:-p
traceroute-p6666www.baidu.com
- [root@localhost ~]# traceroute -p 6888 www.baidu.com
- traceroute to www.baidu.com (220.181.111.147), 30 hops max, 40 byte packets
- 211.151.74.2 (211.151.74.2) 4.927 ms 5.121 ms 5.298 ms
- 211.151.56.1 (211.151.56.1) 0.500 ms 0.499 ms 0.509 ms
- 211.151.224.90 (211.151.224.90) 0.637 ms 0.631 ms 0.641 ms
- * * *
- 220.181.70.98 (220.181.70.98) 5.050 ms 5.313 ms 5.596 ms
- 220.181.17.94 (220.181.17.94) 1.665 ms !X * *
- [root@localhost ~]#
可以看到,報文到達了目的地,但是顯示 !X,意思是“管理禁止通信”,對應 ICMP type=3,code=13 的報文。除此之外,還有以下這些標志:
- !H、!N 、!P:分別表示 host、network、protocol 不可達
- !S:源路由抑制(source route failed)
- !F:需要分片但是沒分片(fragmentation needed)
- !V:違反主機優先級(host precedence violation)
- !C:優先級終止生效(precedence cutoff in effect)
- !\:ICMP 不可達代碼(ICMP unreachable code \)
⑤ 設置探測包的個數:-q
traceroute-q4www.baidu.com
- [root@localhost ~]# traceroute -q 4 www.baidu.com
- traceroute to www.baidu.com (61.135.169.125), 30 hops max, 40 byte packets
- 211.151.74.2 (211.151.74.2) 40.633 ms 40.819 ms 41.004 ms 41.188 ms
- 211.151.56.57 (211.151.56.57) 0.637 ms 0.633 ms 0.627 ms 0.619 ms
- 211.151.227.206 (211.151.227.206) 0.505 ms 0.580 ms 0.571 ms 0.569 ms
- 210.77.139.145 (210.77.139.145) 0.753 ms 0.800 ms 0.853 ms 0.904 ms
- 202.106.42.101 (202.106.42.101) 7.449 ms 7.543 ms 7.738 ms 7.893 ms
- 61.148.154.97 (61.148.154.97) 316.817 ms bt-228-025.bta.net.cn (202.106.228.25) 3.695 ms 3.672 ms *
- 124.65.58.213 (124.65.58.213) 3.056 ms 2.993 ms 2.960 ms 61.148.146.29 (61.148.146.29) 2.837 ms
- 61.148.3.34 (61.148.3.34) 2.179 ms 2.295 ms 2.442 ms 202.106.35.190 (202.106.35.190) 7.136 ms
- * * * *
- * * * *
- [root@localhost ~]#
可以看到,每一跳探測輸出了 4 個時延值。
⑥ 設置探測包的等待響應時間:-w
traceroute-w3www.baidu.com
- [root@localhost ~]# traceroute -w 3 www.baidu.com
- traceroute to www.baidu.com (61.135.169.105), 30 hops max, 40 byte packets
- 211.151.74.2 (211.151.74.2) 2.306 ms 2.469 ms 2.650 ms
- 211.151.56.1 (211.151.56.1) 0.621 ms 0.613 ms 0.603 ms
- 211.151.227.206 (211.151.227.206) 0.557 ms 0.560 ms 0.552 ms
- 210.77.139.145 (210.77.139.145) 0.708 ms 0.761 ms 0.817 ms
- 202.106.42.101 (202.106.42.101) 7.520 ms 7.774 ms 7.902 ms
- bt-228-025.bta.net.cn (202.106.228.25) 2.890 ms 2.369 ms 61.148.154.97 (61.148.154.97) 471.961 ms
- 124.65.58.221 (124.65.58.221) 4.490 ms 4.483 ms 4.472 ms
- 123.126.6.198 (123.126.6.198) 2.948 ms 61.148.156.6 (61.148.156.6) 7.688 ms 7.756 ms
- * * *
- * * *
- [root@localhost ~]#
⑦ 繞過中間的路由探測,直接將包送達目的地
traceroute-r www.baidu.com
- [root@localhost ~]# traceroute -r www.baidu.com
- traceroute to www.baidu.com (61.135.169.125), 30 hops max, 40 byte packets
- Network is unreachable
- [root@localhost ~]#
可以看到,直接顯示網絡不可達。
⑧ 探測路徑 MTU
traceroute--mtu www.baidu.com
- root@pclcache:~# traceroute --mtu www.baidu.com
- traceroute to www.baidu.com (14.215.177.39), 30 hops max, 65000 byte packets
- 1 192.168.109.1 (192.168.109.1) 3.063 ms F=1500 2.908 ms *
- 2 192.168.98.36 (192.168.98.36) 1.686 ms 1.422 ms *
- 3 113.98.59.57 (113.98.59.57) 7.075 ms 7.544 ms 5.851 ms
可以看到,探測到 MTU F=1500。
OK,除此之外,還有更多的用法,大家有興趣可以通過 man traceroute 查看更多的用法。