LoginSignup
0
0

More than 1 year has passed since last update.

tracerouteを考察する

tracerouteは、ある宛先までのネットワーク経路を調べるもの。IPパケットのTTLを1から徐々に増やしていき、ICMPの「Time Exceeded」応答したルーターのIPアドレスをもとに経路を調査する。ルーターを通過すると、TTLがデクリメントされることを利用している。

UDP vs ICMP

背景

Windowsでは「tracert」がそれに相当し、送るパケットとして、ICMPが使われる。Ciscoルーターでは伝統的(?)にUDPが、Linux/Macでは、ICMPもUDPも選ぶことができる(TCPも?)。UDPの場合、ICMPと比べて、Firewallなどでパケットフィルタリングされる可能性が高いので、なぜUDPが使われるのか不思議に思っていた。少々調べてみると、次の記事が見つかった。

  • Why traceroute sends UDP packets and not ICMP ones?
    引用すると、
    I guess the main motivation was that sending out plain UDP packets requires no special privileges, as sending ICMP packets does (raw sockets or the equivalent). That's why e.g. ping is usually setuid to root, which is a big risk security-wise.

RawソケットをハンドリングするUnix上の権限が関連している、、、との推測。ある程度納得はできるところ。

比較

小生のMacにて、まずは単純に、UDP利用時とICMP利用時のtracerouteとの比較を行った。ターゲットはGoogleのDNSサーバー「8.8.8.8」としている。

UDP

(ドメイン名およびIPアドレスの一部はhidden。)

$ traceroute 8.8.8.8
traceroute to 8.8.8.8 (8.8.8.8), 64 hops max, 52 byte packets
 1  aterm.me (192.168.10.1)  1.647 ms  1.640 ms  1.592 ms
 2  aa.bb.cc.ne.jp (ZZ.146.YYY.74)  4.438 ms  4.274 ms  4.535 ms
 3  dd.ee.ff.ne.jp (XX.146.WWW.73)  4.327 ms  4.555 ms  4.353 ms
 4  gg.hh.ii.ne.jp (VVV.213.UUU.93)  6.401 ms  6.093 ms  17.918 ms
 5  202.213.193.91 (202.213.193.91)  9.083 ms  6.651 ms  5.617 ms
 6  * 142.250.160.100 (142.250.160.100)  9.610 ms  10.062 ms
 7  * * *
 8  dns.google (8.8.8.8)  9.554 ms  5.262 ms  5.041 ms

ICMP

$ traceroute -I 8.8.8.8
traceroute to 8.8.8.8 (8.8.8.8), 64 hops max, 72 byte packets
 1  aterm.me (192.168.10.1)  4.123 ms  1.516 ms  1.287 ms
 2  aa.bb.cc.ne.jp (ZZ.146.YYY.74)  4.072 ms  4.195 ms  3.987 ms
 3  dd.ee.ff.ne.jp (XX.146.WWW.73)  6.707 ms  4.722 ms  4.630 ms
 4  gg.hh.ii.ne.jp (VVV.213.UUU.93)  11.479 ms  5.958 ms  6.980 ms
 5  202.213.193.91 (202.213.193.91)  9.766 ms  6.826 ms  7.543 ms
 6  142.250.160.100 (142.250.160.100)  6.209 ms  22.981 ms  7.530 ms
 7  142.251.52.31 (142.251.52.31)  5.221 ms  6.150 ms  333.949 ms
 8  142.251.60.193 (142.251.60.193)  8.024 ms  6.078 ms  5.022 ms
 9  dns.google (8.8.8.8)  5.187 ms  7.348 ms  5.827 ms

UDPとICMPとの比較

ほぼ同じ時刻に実施しているが、経路が若干異なることがわかる。また、異なる日に実施した場合、同じ経路とはならなかったこともあり。このあたりは、途中経路のルーターの設定(ダイナミックルートなど)に依存するのであろう。

UDPで未応答部分あり

上記UDP結果に、未応答部分がある。

 7  * * *

Wiresharkでは下記のとおり。
未応答.png

途中経路のFirewallでブロックされたのであろう。UDP利用時のtracerouteは、デフォルト時ポート番号33434から一つずつインクリメントされるらしい。以下、「man traceroute」の説明。

     -p port
             Protocol specific. For UDP and TCP, sets the base port number used in probes (default
             is 33434).  traceroute hopes that nothing is listening on UDP ports base to
             base+nhops-1 at the destination host (so an ICMP PORT_UNREACHABLE message will be
             returned to terminate the route tracing).  If something is listening on a port in the
             default range, this option can be used to pick an unused port range.

TTLインクリメント時に、ポート番号をインクリメントする理由がよくわからない(おそらく何かあるはず)。デフォルトポート番号を相当数変えてトライしたが(例:「-p 35000」)、IPアドレス「8.8.8.8」へのtraceroute(UDP)にて、未応答部分が必ず存在していた。

IPアドレス「8.8.8.8」はDNSサーバー

DNSサーバー(UDP)である。DNS queryの応答は必ず得られる(はず)。DNSのポート番号である53を指定し続ければ(TTLをインクリメントしつつ)、少なくとも「8.8.8.8」への経路は判明するはず。なので、それをトライすることとした。

Network Packet Generator

tracerouteコマンドでは、ポート番号を常に同一にしてパケットを送ることができない。そこで、何らかの「Network Packet Generator」を使い、IPヘッダを操作することにした。検索すると、GUI上のアプリケーションも多数見つかるが、Python上で利用する

が、とてもハンドリングしやすいと判断。

Scapy

使用例は、同サイトにも、他にも多数見つかる。

ポート番号53固定で、TTLをインクリメント

下記となる(TTLを1から10まで変化させる)。とてもイージー。

>>> ans=sr1(IP(ttl=(1,10), dst="8.8.8.8")/UDP()/DNS(qd=DNSQR(qname="ietf.org")))
Begin emission:
Finished sending 10 packets.
.*.*.*.*..*.*.**.*.*
Received 20 packets, got 10 answers, remaining 0 packets

その時のWiresharkの状況。
image.png
期待どおり、未応答は存在しない(成功)。また、「8.8.8.8」までのルートも、tracerouteでUDPやICMPでの結果と異なっているようだ。このあたりは深追いしないこととした。

終わりに

やはり、ICMP利用のtracerouteがベターと感じる。

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0