読者です 読者をやめる 読者になる 読者になる

ぎじゅつめも

とある工学系学生が学んだことをメモするだけのブログです。

tracerouteの仕様について

tracerouteは、指定したホストまでの経路(経由したノード)を表示するツールです。自社ネットワークで障害が起こった時に“どのノードまではパケットが正常に届いているのか”等を調べる時に使います。もしも使用者が攻撃者であれば“攻撃パケットが標的リンクを通るかどうか”等を調べるために使うこともできるでしょう。また、あるノードまでは応答が早く、あるノードを境に応答が遅くなる場合、このノード間がボトルネックリンクではないかという推測もできます。

このtracerouteですが、IPヘッダのTTL値を利用していることはよく知られています。しかしIP層以上の仕様/実装がWindowsUnix系OSLinux)では違います。この点について、大学の実験実習で学んだのでメモとして書き留めておこうと思います。

各OSでの仕様を知ることは、Firewallでtracerouteを通したい場合等に役に立ちます。また、AS等では当該パケットを観測することでtracerouteが行われたことを認知し、攻撃者による攻撃前の調査パケット(予兆)を得るといったことも可能になるかと思われます。

 

各OS共通の仕様

IPヘッダまでの仕様は各OSで共通です。IPヘッダにはTTLフィールドといものがあります。TTL値は経由できるホップ数を表しており、IPパケットは経由したノードごとにTTL値を1減らされ、0になるとそのノードにおいて破棄されます。tracerouteでは、調査パケットのIPヘッダのTTL値が1の場合,2の場合,3の場合...と試していき、最終的に対象ホストに到達するまでこれを繰り返すというものです。

つまり、tracerouteコマンドを打つと、まずはIPヘッダのTTLフィールド(パケットが経由できるノード数を表すフィールド)を1としたパケットが送りだされます。経由できるノード数は1なので、最初の中継器でパケットが受け取られてTTL値が1減らされ0になるので、パケットは最初の中継器で破棄されます。次のパケットはTTL値が2なので、2つ目の中継器で破棄されます。次のパケットはTTL値が3なので、3つ目の中継器で破棄され...という風に対象ホストに至るまでのそれぞれのノードで破棄されるパケットがでてくるのです。

traceroute実行ノードは、これらの破棄されたノードからの応答を受け取ることで、対象ホストまでの全ルートを得ます。

 

Windwosでの仕様

Windowsではtracerouteはtracertコマンドとして実装されています。Windowsでのtracerouteは簡単に言うとpingです。すなわち、IPの上層はICMPとなっています。traceroute実行ノードによる調査パケットは全てICMP type8 code0(echo request)として送られます。ただし、それぞれの中継ノードではTTL値が0になってパケットは破棄されるので、中継ノードからtraceroute実行ノードに対してICMP type11 code0(time exceeded)が返されます。唯一宛先ホストのみが、echo requestに対する応答として、ICMP type0 code0(echo reply)を返します。

traceroute実行ノードはecho replyが返ってきたら宛先ホストまでのtraceが完了したと解釈することができます。ちなみにそれぞれの応答(time exceededおよびecho reply)内には送信者の情報が記載されているので、traceroute実行ノードは中継ノードの情報を得られます。

 

※補足

ちなみに、tracerouteでは実行ノードとそれぞれの中継器間の情報(RTT等)しかわかりませんが、現行のWindowsでは中継器間の情報もわかるpathpingなるものがあったりするそうで…

 

Unix系OSLinux)での仕様

Linux等では、IPパケットの中身はICMPではなくUDPになっています(ただし指定すればICMPでも可能)。UDPヘッダの宛先ポート番号を、絶対に使われていないであろうポート番号に設定して送ります。TTL値が0になる中継ノードからは、実行ノードに対して、Windowsのtracertと同じようにICMP type11 code0(time exceeded)が返されます。しかし、宛先ホストには待ちうけていないポート宛ての要求が来たのでパケットを破棄し、実行ノードに対してICMP type3 code3(port unreachable)を返します。

実行ノードはport unreachableを得れば宛先ノードまでのtraceが完了したと判断します。以下はtraceroute後の宛先からのport unreachableをwiresharkで実際にキャプチャした際の画像です。

f:id:white-hawk:20170210034547p:plain

 

※補足

ちなみに、実際に使われるであろう宛先ポートを指定すると、運用されているサービスから応答が来てしまう可能性があるので、使われていないポートを指定します。また、メジャーなサービスの宛先ポート番号はウェルノウンポートとなるので、多くの実装では33434からインクリメントしてパケットを送信しますので、Firewallでもしtracerouteを通す場合これを意識するといいと思います。また念のため1度に2つ(資料によっては3つ)調査パケットを送るようです。(つまり1つのTTLに対して異なる宛先ポート番号を指定した2つ又は3つのパケットを送ります。)

 

結論

IP層より上層で使うプロトコルと、それに伴った宛先ホストまで到達したかどうかの判断方法が異なります。

 

今後のtraceroute関連の記事について

tracerouteの高速化については前から興味がありましたので、tracerouteのコードなんかを見ながら記事がかければなーと思います。あとtracerouteを応用した研究等(既存のものでいうと某大学様のASパス推測など)についても言及できればと思います。