有玩過traceroute或win下的tracert朋友,不曉得有沒有遇過一些trace的怪象?
嗯…這些怪象就像,我明明用來trace的封包已經到了Internet但傳回來的hop位置是
private ip...
Example
bash-2.05$ traceroute a.b.c.d
.....
.....
.....
(此時封包已經到了Internet上)
4 10.0.x.x 1ms 1ms 1ms
.....
.....
.....
又或者traceroute的目標IP會出現在最後的兩個hop?
Example 1.______________________________________________________________
bash-2.05$ traceroute -p 26 -q 1 59.121.189.191
traceroute to 59.121.189.191 (59.121.189.191), 30 hops max, 40 byte packets
.....
.....
.....
4 tp-s2-c76r5.router.hinet.net (168.95.82.194) 1.271 ms
5 h25.s82.ts.hinet.net (168.95.82.25) 2.086 ms
6 59-121-189-191.dynamic.hinet.net (59.121.189.191) 58.531 ms
7 59-121-189-191.dynamic.hinet.net (59.121.189.191) 567.928 ms
Example 2.______________________________________________________________
bash-2.05$ traceroute -p 25 -q 1 59.121.189.191
traceroute to 59.121.189.191 (59.121.189.191), 30 hops max, 40 byte packets
.....
.....
.....
4 tp-s2-c76r5.router.hinet.net (168.95.82.194) 1.943 ms
5 h25.s82.ts.hinet.net (168.95.82.25) 1.946 ms
6 59-121-189-191.dynamic.hinet.net (59.121.189.191) 58.467 ms
7 *
8 *
9 *
10 59-121-189-191.dynamic.hinet.net (59.121.189.191) 64.505 ms
_________________________________________________________________
通常像第一個問題會出現private ip是因為封包到了大型的網路,然而這網路之中的router
分別都是以private ip互相連接,會出現private ip的那個router通常是沒有直接對internet的需求.
所以說你如果在win下用pathping去偵測的話,碰到出現private ip的那個hop你可能就沒輒了.
至於第二個問題...有次我用windows pc去tracert一台機器,結果出現像Example 1的情況,
這情況通常是因為防火牆造成的,最近在家裡配合NAT和網外的一台solaris的機器實作出來了.
首先,大略介紹一下,windows下的tracert是送出ICMP request的封包,
然後第1個Hop會把ip的ttl值設為1,會收到第一個router送來的icmp ttl exceeded封包,
因為router每把經過的封包ip欄的ttl減1,如果一個封包的ttl為0的話,那麼這封包就被router丟棄,
丟掉後會告知來源端說你的封包已經逾時time exceeded了.這樣的設計是為了避免internet上有無窮盡的封包.
tracert利用這種方式去計算來源跟目的機器間的機器數目.
然後收到router送的time exceeded的icmp封包,它會送出封包比上一個hop的封包ttl值再加1,
最後收到目標機器送出的ICMP reply就結束了.
而unix底下的traceroute是送出UDP的封包,ttl值也是以每次遞增1的方式,方式其實都大同小異.
只差在traceroute是送出幾乎不可能有在listen的udp port去,預期對方目標機器會送出一個icmp
的port unreachable封包,收到此封包,traceroute的工作即結束.
我實作的方式就是將NAT開一個udp port轉送到我的內網pc來,所以你就會看到像第一個example一樣
譬如我在nat上開一個對外的udp port 99,然後轉送到我內網192.168.1.50這台機器的99 port好了
然後我在外面那台solaris機器下
traceroute -p 94 -q 1 59.121.189.191
這行指令是說,我一開始的udp port指定為94,每個hop只送出一個udp packet.
然後traceroute的udp port每次也會增加1
(整個traceroute就是設計成這樣,聽說後來的版本可以用選項固定port),
因為從solaris機器到我的NAT,中間會經過5部router,所以到達我的NAT的udp封包在solaris送出前
要把ttl設為6才能到達,然後port也已經從94遞增到99了,所以我的NAT會收到來自solaris的udp封包,
帶有目的端port為99,TTL值已經被中間的5部router扣到只剩下1了,然後NAT看到這個封包會想要往內網送,
可是NAT本身因為也是一台router所以它也會把這個要往內送的封包TTL再扣1,這一扣就把封包扣成0了,所以
NAT就會把這個封包丟掉,再傳回一個icmp time exceeded的封包給solaris說你的封包被我丟了,這時solaris
的traceroute就會再送出比剛送出的封包再加1的ttl值udp封包出去,這時到了我的NAT就有TTL=2的udp封包,
然後NAT就可以成功的再往內送給192.168.1.50這台機器,然後192.168.1.59這台機器收到這個TTL=1,udp port=100
的封包,如果這台機器本身沒有listen這個udp port(可以用Netcat來實驗)的話,就會送出icmp的port unreachable給
外網的solaris機器.所以說我如果在NAT那端開很多個udp port對到網內這台機器時,然後這個udp封包被192.168.1.100的
防火牆欄掉,或者192.168.1.100有在listen這個udp port的話,就會直接把封包丟到OS裡處理,
並不會送出port unreachable,所以traceroute設計上就是開啟較高的port去偵測避免這種情況,像Example2這樣,
最後在第10個hop會成功是因為NAT剛好沒有開這個udp,所以port unreachable是由
NAT送出的,不是由192.168.1.50這台機器送的.
2007/05/03 新增註記--
其實像第一個問題,trace route中會出現private ip更正確的解釋應該是這樣的
當A主機要trace route到B主機時,中間的router如果其中有2台彼此是以private ip
相連結的話,那麼從A主機trace或B主機trace都會出現其中有個hop會是private ip.
e.g.
A machine----->router A<----->router B<----->router C<----->router D<-----
B machine
其中router B對router C相連的那個網路介面設為192.168.1.5
然後router C對router B相連的網路介面設為192.168.1.6
那麼從A主機trace到B主機的過程中(先不考慮其它路徑的選擇),在第三個hop會遇到router C
然後會出現的ip位址就是192.168.1.6
如果從B主機trace到A主機的過程中(先不考慮其它路徑的選擇),會在第三個hop遇到router B
然後出現ip為192.168.1.5的位址...
這些是在TCP/IP Illustrated Volume 1中的章節翻到的trace route概念