traceroute
/ TRACE-route /
假設一個包裹送到了遙遠的城市,但你完全不知道它一路上經過了哪些分揀站。traceroute 就是揭露封包旅程中每一站的把戲,一次一跳(hop)。當 ping 告訴你某個目的地很慢或連不上時,ping 沒辦法說出問題在哪——traceroute 可以,方法是把你與目的地之間實際的路由器序列畫出來,並為每一個計時。
巧妙之處在於它如何逼路由器現身——它濫用了 IP 的存活時間(time-to-live,TTL)欄位。每個 IP 封包都帶著一個 TTL,每經過一台路由器就減一;當 TTL 歸零時,該路由器丟棄封包並送回一個 ICMP「逾時」(time exceeded)訊息——而這個訊息來自路由器本身,因此洩漏了它的位址。traceroute 刻意利用這一點:它先送一個 TTL=1 的封包(第一台路由器回覆),再送 TTL=2(第二台路由器回覆),再送 TTL=3,依此類推。每一輪它都學到路徑上的下一台路由器以及那趟來回花了多久,就這樣一跳一跳建出整條路徑,直到封包終於抵達目的地。
閱讀輸出時要小心,因為 traceroute 有真實的怪癖。每一行顯示的是到「那一跳」的往返時間,而不是「那一段連結」的延遲,所以單一一個慢的跳可能誤導你——而且延遲合理地跳高之後又安定下來是正常的。許多路由器會降低它們自己產生的 ICMP 回覆的優先序,所以一個顯示高 RTT 或星號(沒回覆)的跳,可能正忙著完美地轉送真實流量;它只是慢慢回 traceroute,或乾脆不回。去程與回程的路徑也可能不同,而負載平衡器可能把連續的探測送上不同的路線。traceroute 把路徑揭露得極好,但它每一跳的時間只是提示,不是定論。
執行「traceroute example.com」會印出像這樣的行:「1 192.168.1.1 1.0 ms」、「2 10.20.0.1 8.3 ms」、「3 * * *」(一個忽略 ICMP 的跳)、「4 72.14.x.x 22.5 ms」、「5 example.com 23.1 ms」。現在你能精確看出往返時間是在路徑上的哪裡跳高的。
traceroute 透過一次把 IP 的 TTL 加一,並讀取每台路由器的「逾時」回覆,一跳一跳地把路徑畫出來。
一個顯示高 RTT 或「* * *」的跳往往不是問題所在:許多路由器在完美轉送真實流量的同時,降低或封鎖它們自己產生的 ICMP。每一跳的時間只是提示;去程與回程的路徑也可能不同。