概要
Linuxのtracepathコマンドが経路非対称をどのように判定しているのか説明する。
tracepathの経路非対称判定とは
tracepathは指定したアドレスに宛ててパケットを送信し、その経路上でパケットを中継するホストのアドレスを列挙する。つまり、自ホストから投げた測定パケットの経路(往路)が出力される。
tracepathは更に、パケットを中継するホストから自ホストへ戻ってくる応答パケットの経路(復路)が、往路と異なっていることを検知して出力できる。
実はこれはちょっとすごいことで、コマンド一つで分かってしまうのはいい感じだよな、と思うわけ。
実行例
以下はとあるホストからとあるホストへ向けてtracepathを計測した時の例。IPアドレスは伏せてある。TTL6で投げたパケットに対して、asymm 7
という出力が出ておりこれが経路非対称、つまりパケットの往路と復路が異なっていることを示している。TTL8以降も同様だ。
ちなみにasymm 7
は、その機器からの応答パケットがTTL7相当だったという意味。
$ tracepath -n ???.???.???.???
1?: [LOCALHOST] pmtu 1500
1: ???.???.???.??? 0.893ms
1: ???.???.???.??? 0.912ms
2: ???.???.???.??? 0.793ms
3: ???.???.???.??? 0.295ms
4: ???.???.???.??? 0.402ms
5: ???.???.???.??? 0.528ms
6: ???.???.???.??? 1.244ms asymm 7
7: ???.???.???.??? 0.733ms
8: ???.???.???.??? 3.181ms asymm 13
9: ???.???.???.??? 3.458ms asymm 12
10: ???.???.???.??? 10.047ms asymm 13
11: ???.???.???.??? 8.276ms asymm 12
12: ???.???.???.??? 9.553ms asymm 13
13: ???.???.???.??? 11.716ms asymm 14
14: ???.???.???.??? 11.943ms asymm 15
15: ???.???.???.??? 13.631ms asymm 16
16: ???.???.???.??? 11.050ms pmtu 1454
16: no reply
17: no reply
^[^C
tracepathはどのように経路測定しているか
tracepathが経路非対称を検出している方法を理解するためには、前提としてtracepathがどのように(往路を)経路測定しているかを理解する必要がある。
tracepathは以下の様にして経路を測定する。
1. 測定対象に宛ててTTL1のUDPパケット(宛先ポート番号はランダム)を送出する。
2. TTL1のパケットは直上のルータにてTTLが切れる。ルータはそれをtracepathに通知する応答(ICMP time exceeded)を返す
3. 返ってきた応答の送信元を見ることで直上のルータのIPアドレスを取得する
4. 測定対象に宛ててTTL2のUDPパケットを送出する(*1)
5. 同様にして応答が得られ、経路上の次のルータのIPアドレスを得る
6. 以後同様にしてTTLを1ずつ増やしながら測定対象に到達するまで繰り返す
(*1)この時宛先ポート番号は変更しておく。応答のICMP time exceededには送出したUDPパケットのSRCおよびDSTのポート番号が記載されるため、以前に送信したパケット(のDuplicate)に対する応答パケットと区別ができるようになる。CentOS7で確認したところポート番号は+1していた。
ICMP time exceeded以外にも別の応答を得る場合があるのだけれどもここでは省略。
経路非対称の判定方法
さて、ここまでで往路は測定することができた。次に復路に関する情報をどこから得るかといえば、当然tracepathに返される応答パケットである。
我々がアクセスしているのは太古の昔のインターネットではないので、応答パケットに経路を書き込んで返せというやり方は使用できない。ではどうしているのかというと、応答パケットのTTLを見て判断している。
応答パケットのTTLは、応答の送信元ルータで値を設定され、経路上のルータで1ずつ減らされてからtracepathへ届く。だから応答の送信時のTTLが分かれば、受信した応答パケットのTTLと引き算をすることで復路のホップ数を得られることになる。ところがTTLは応答の送信元ルータが自由に値を設定するので、送信時のTTL値はtracepathには分からないのだ。
そこで、IMCP time exceededがTTLは64、128、255のいずれかで送出される事(が多いの)を利用して、tracepathは経験上うまくいくやり方で推測して復路のホップ数を推測している。
往路と復路とでホップ数が異なれば、それは当然経路が非対称である、ということは判断できる。この場合にasymm NUM
という出力が行われるわけだ。
経路非対称の誤判定と機器の推測
応答パケットのTTLを見て判断する方法は、当然ながら誤判定の可能性がある。応答パケットの送出時にTTLが予期しない値に設定されていた場合には正しく判定できないからだ。
実際、ここによれば、 Juniper M/TシリーズのルータはTTL255ではなくTTL254で送出するので、tracepathは経路非対称であると誤判定するとのこと。
逆にインターネットのバックボーンに近い部分で往路と復路のTTLが1だけ異なるasymmが出力された時には、そこにJuniperがいる、と推測できそうだ。
上記の実行例でもTTL6の行など複数の箇所で1だけTTLとasymmの値が異なる出力があるので、Juniper M/Tシリーズが使われているのかもしれない。