- 訪問者がWebサイトを開くと、サーバーが公開IPに対して traceroute を実行し、パケットがルーターやネットワークを経由して移動する経路をリアルタイムのテキストのように表示する
- 独自ツール ktr はICMPパケットのTTL値を増やしながら各ホップのエラー応答を集め、同時にホップごとのネットワーク情報を照会する
- 画面更新はJavaScriptではなく、開いたHTTPレスポンスにHTMLとCSSを流し続ける方式で実装されており、ページの読み込み中に結果が段階的に表示される
- 表示される経路は、サーバーから訪問者IPへ送った 逆方向traceroute を反転したものなので、双方向のルーティング差により実際の経路と完全には一致しない場合がある
- インターネット経路は自律システム(AS)間の BGPピアリング とルーティングテーブルの伝播によって作られ、トラフィックは相互接続されたネットワークをたどって移動する
アクセスするたびに生成されるパーソナライズされたtraceroute
- ページ上部の緑色のテキストは事前に保存された例ではなく、Webサイトの読み込み中に訪問者に合わせて その場で生成されたtraceroute である
- tracerouteは、訪問者のコンピュータまたはパケットがインターネットを経由してこのWebサイトをホストしているサーバーに到達するまでの旅程を示す
- 例の経路は訪問者のルーターから始まり、ISPネットワークを通過し、複数のネットワークを経由してHetzner内部ネットワークに入り、サーバーに到達する
- 最初のルーターがpingに応答しないことがあり、公開ルーターやVPNの背後ではよくある状況である
- 途中で
(no response) が表示されることがあり、すべてのサーバーが常に応答するわけではない
core3.sto.hetzner.com のような名前は、tracerouteで得られたIP 213.239.252.74 に 逆引きDNSルックアップ を行い、人間が読みやすい名前に変換した結果である
- 逆引きDNS名は主にデバッグを容易にするためのものであり、元のIPへ再びマッピングされないことも多い
ktrとICMPベースのtraceroute
- Webサイトの実装には独自のtracerouteプログラム ktr が使われている
- サイトのソースコードも GitHub で公開されている
- ktrは結果をリアルタイムにストリーミングしながら、各ホップの情報を同時に照会する
- インターネットルーティングでは、パケットを処理するコンピュータやルーターが次の転送先を選択し、宛先へ直接送れるルーターに到達するまでこの処理が続く
- ktrの実装は ICMP を使用する
- ICMPはインターネット上で診断情報を送るために設計されたプロトコルである
- ほぼすべてのインターネット接続デバイスがICMPをサポートしている
- ICMPパケットの TTL(time to live) フィールドは実際の時間ではなくカウントダウン値である
- ルーターがICMPパケットを転送するたびにTTLを1減らす必要がある
- TTLが0になると、ルーターはパケット転送を停止し、最大ホップ数に達したというエラーメッセージを元の送信元IPへ送る
- tracerouteはTTLを1、2、3のように徐々に増やしたICMPパケットを送り、各ホップから返るエラー応答を収集する
- エラーパケットには、エラーを送ったデバイスのIPアドレスなどの診断情報が含まれる
- これにより、インターネットを横断したおおよそのパケット経路を追跡できる
JavaScriptなしでリアルタイムのように見える画面
- ページは JavaScriptを無効化した状態 でも動作する
- ブラウザから見ると、Webサイトがゆっくり読み込まれているように見える
- ユーザーにはtracerouteがリアルタイムに表示されているように見える
- アクセス時、サーバーは訪問者のIPアドレスから届いたHTTPリクエストを受け取り、すぐにそのIPへtracerouteを実行する
- サーバーはHTTPレスポンスの先頭部分を先に送信し、その後も接続を開いたまま維持する
- ktrがtracerouteの更新をサーバーに渡す
- サーバーは関連するHTMLをレンダリングして訪問者のコンピュータへ送信する
- tracerouteが終わると、残りのテキストとWebサイトの内容を送信してから接続を閉じる
- tracerouteの行が下ではなく上側で段階的に更新されるように見える理由は CSSブロックの挿入 にある
- Webページは基本的に前方向にしか読み込めない
- traceroute表示を更新するたびに、以前の表示を隠すCSSを一緒に挿入する
- ブラウザが読み込み中にCSSをレンダリングするため、画面が時間とともに編集されているように見える
逆方向tracerouteの限界
- ページが示す経路は「訪問者のパケットがサーバーに到達した経路」と完全には同じではない
- 実際の経路を計算するには、訪問者のコンピュータからサーバーへtracerouteを実行できる必要がある
- 実装ではサーバーから訪問者のコンピュータへtracerouteを実行し、その結果を 反転して表示 している
- そのため上部のtracerouteが逆順に読み込まれるように見える
- 逆方向tracerouteは精度を一部犠牲にする
- パケットが反対方向に移動すると、各デバイスが別のルーティング判断をする場合がある
- 1つのデバイスだけが別の判断をしても、その後の経路が変わる可能性がある
- それでも経路はおおよそ似ており、違いは主に特定のどのルーターがパケットを見るかという程度である可能性がある
自律システムとWHOIS照会
- tracerouteに登場する「ネットワーク」は 自律システム(AS) を指す
- ASは互いに私的に接続されたルーターとサーバーの集合である
- 一般的には同じ会社が所有している
- ASの所有者は、どの他のASと接続するかを選択してインターネットの形を決める
- インターネットトラフィックは互いに ピアリング契約 のあるASを通って移動する
- インターネットは開かれたネットワークのように見えるが、実際には企業が所有するネットワーク同士のネットワークであり、アクセスと制御は金融取引と官僚的手続きに左右される
- 独自の自律システムが欲しい場合は、5つの 地域インターネットレジストリ(RIR) のいずれかにASNを申請できる
- 会社の後ろ盾がない、または十分なインターネット接続点がない場合、受け入れられにくい
- tracerouteの
AS4766 のような数字がASNである
- ktrは各ホップIPを所有するAS情報を得るために WHOISプロトコル を使用する
- 複数の組織が、どのASがどのIPアドレスを含むかを追跡している
- 多くの組織がWHOISでASN照会を提供している
- 会社情報を把握するためには PeeringDB も使われる
- PeeringDBは全自律システムの約1/3について情報を持っている
- 照会結果と数百行のif文を組み合わせて、ネットワーク通過の説明を生成する
- WHOISプロトコル仕様 は構造をほとんど定めていない
- TCP接続を作り、照会したい内容を送ると、サーバーが情報を返して接続を終了する、という程度だけを定めている
- 実際のWHOIS応答構造はサーバー管理者が作った慣例に近く、必要なフィールド名も
origin、originas のように異なる場合がある
- ktrのパーサーは厳密なパーサーというより、人間がWHOIS結果を読みながら必要なASNを探す方法に近い
BGPがインターネット経路を作る仕組み
- ネットワーク境界にあるルーターは、次にどのネットワークへパケットを送るかを決定し、宛先デバイスのあるネットワークに到達するまで同じ処理が続く
- こうした境界ルーターは Border Gateway Protocol(BGP) によって、互いに到達可能なネットワーク情報を交換する
- BGPはインターネットの形を作るプロトコルである
- 一般ユーザーが直接BGPを話すことはできない
- BGPの初期バージョンは、1989年にCiscoとIBMのエンジニアが出した RFC 1105 に記述されている
- 1969年のARPANETプロトタイプでメッセージが部分的に送信された後、複数の大学・政府機関・企業がそれぞれのネットワークを作り、相互接続を始めた
- 1990年に BGP v2 が登場した
- 1994年にBGP v4が RFC 1654 として規定された
- BGP v4は1995年と2006年に改訂とパッチを経ており、現代インターネットの相互接続ネットワークにおける経路選択に今も使われている
BGP経路、ピアリング、ルーティングテーブル
- 自律システム境界のルーターである border gateway は、自分が知っているすべてのBGP経路の一覧であるルーティングテーブルを保持する
- 各BGP経路は、特定のIPアドレス集合を制御するASに到達するためにたどれる ASN経路 を指定する
- BGP経路はAS間のピアリング関係を通じて形成される
- 2つのASのborder gatewayがpeerすると、2つのルーター間でトラフィックが移動できる
- 互いに知っているBGP経路情報を最新の状態で共有する
- 例として、AS0001のRouter AとAS0002のRouter Bが物理的に接続されてピアリングするには、BGPメッセージをやり取りして BGPセッション を確立する
- Router Aは、AS0002で始まるBGP経路についてRouter Bを経由する必要があることを知る
- Router Bも反対方向の情報を知る
- peerたちは 経路広告(route advertisement) の過程で自分が知っている経路を共有する
- Router AがRouter Bに自分の知るすべての経路を知らせると、Router BはAS0001で始まる経路をルーティングテーブルに追加する
- Router Aの別のpeerが新しい経路を広告すると、Router AはそれをRouter Bにも転送する
- この広告がASネットワーク全体に広がることで、各border gatewayはインターネット上のどのIPに到達できる1つ以上のAS pathを知るようになる
- ルーターが特定のIPへパケットを送るときは、ルーティングテーブルからそのIPを制御するASへの経路を探す
- その後、複数のヒューリスティックで「最良」の経路を選択する
- ヒューリスティックには最短経路探索と、特定ASに対するハードコードされた優先または非優先が含まれる
- ルーターは選択した経路の最初のASとピアリングしているgateway routerへパケットを送る
traceroute結果をBGPの観点から読む
- 例のtracerouteのAS pathは AS4766 → AS201011 → AS24940 である
- ある時点でパケットはAS4766のルーターの1つに到達し、そのルーターはAS201011のルーターとピアリングしていた
- ルーターはルーティングテーブルから、宛先IPがAS201011で始まる経路を通じて到達可能だと判断する
- その後、パケットを接続先のAS201011ルーターへ送る
- 同じASN内でも複数のホップが現れることがある
- Hetzner Onlineを通過する6ホップのように、tracerouteはAS境界ルーターだけでなく、パケットが通過したすべてのルーターを表示する
- AS内部のルーターは、効率的な内部経路を知っていれば外部BGP経路より内部経路を優先できる
- 内部経路は内部BGP、他の内部ルーティングプロトコル、またはハードコードによって学習される場合がある
- インターネットの到達可能性を決める核心は内部ホップではなく、異なるAS間の ピアリング契約 である
1件のコメント
Hacker Newsのコメント
こんにちは、Lexiです。17歳で、最近の関心はコンピュータがどう動くのかをより深く理解し、それを新しい形で見せることです。
数か月前に https://cpu.land を公開し、関連する議論は https://news.ycombinator.com/item?id=37062422 にあります。
cpu.land のあと、また別の大きな成果物を作らなければというプレッシャーが強かったのですが、これといって惹かれるアイデアがなく、個人プロジェクトをいろいろ試しているうちに、インターネットの仕組みを偶然学ぶ過程で、リアルタイムで traceroute をウェブサイトにストリーミングするプログラムをゼロから作ることになりました。
こういう形のものをウェブで見たことがなく、インターネットの構造を可視化するかなり新しくてクールな方法だと思ったので、磨き上げて見た目のよいサイトにしました。
その過程でBGPとインターネットの構造について面白いことをたくさん学んだので、traceroute ツールとその知識を共有する記事を組み合わせました。
まだ手を入れ続けていて、どこかでコードが壊れるのは間違いないので、提案があればぜひ教えてほしいです。
ちなみに、なぜ Rust かというと、プログラミング言語の選択がそこまで重要だとは思っていませんが、信頼性の高い低レベルプログラムを素早く書きたくて、Rust のエラー処理の基本要素が気に入ったからです。
30年近く前、私が最初に作った CGI プログラムの1つは、Perl で traceroute をラップし、サーバープッシュで結果をストリーミングするスクリプトでした。
古いものがまた新しく見えるのはよくあることですが、それでもこのサイトの見せ方はとても良いです。
参考までに、IPv4 TTL は法的には秒単位ですが、どのルーターも1秒以上は消費せず、最小減少値が1なので、実際にはホップ数として使われています。隠れたいミドルボックスは、そもそも減少させないこともあります。
また Linux/Unix の traceroute はデフォルトで、探索用パケットに ICMP ではなく高い番号の通常は閉じているポート宛ての UDP を使います。歴史的に UDP のほうが ICMP よりドロップされたりフィルタされたりしにくかったためです。
traceroute がどう動くかを尋ねるのは面接質問の1つですが、ほとんどの人は知らず、知っていたとしても質問としての価値はやや下がります。TCP/IP についていくら質問されても第一原理から推論できないことが多く、それでも解きほぐせるかを見るという意味では、妥当な問題解決の質問だと思います。
例: https://www.bgplookingglass.com/
https://www.oreilly.com/openbook/cgi/ch06_06.html
ICMP の代わりに TCP や UDP を使うと、より正確な結果が得られるのか気になります。伝統的な traceroute にも UDP オプションがありますし、mtr [1] は TCP や UDP を使え、tcptraceroute [2] は TCP を使えます。
それから Talking Heads の引用を入れる絶好の機会です。"And you may ask yourself, well, how did I get here?" [3]
[1] https://github.com/traviscross/mtr
[2] https://linux.die.net/man/1/tcptraceroute
[3] https://en.wikipedia.org/wiki/Once_in_a_Lifetime_(Talking_He...
あとは、特定のワークステーションから会社の Cisco アクセススイッチ、コアスイッチ、AWS transit gateway へ向かう BGP トンネルを通り、EC2 インスタンスの VPC ルーティングテーブルに到達するまで、各ホップで traceroute を動作させる方法さえ突き止めれば、ネットワーク担当者と呼べそうです。
残念ながら、あまりに多くのノードが traceroute パケットを無視するので、私の出口ノードが Linode に接続し、Linode があなたのコンピュータに接続しているようにしか見えませんでした。
順方向の traceroute でも似たようなもので、ルーターが応答し、サーバーが応答し、運が良ければ ISP ネットワークのノードが1つ見える程度です。残りはがっちり塞がれています。
「BGP はインターネットに形を与えるプロトコルで、直接しゃべることはできない」とありましたが、実際には個人が ASN を取得して BGP を話すのは驚くほど簡単です。
こういうツールを作るのが面白そうなら、一度やってみる価値はあります。興味があれば、以前に書いた入門記事もあります: https://qt.ax/asn
これは「私のコンピュータがあなたのサーバーに到達する方法」というより、あなたのサーバーが私のコンピュータに到達する方法の逆向きに近いです。双方向のルーティングはたいていかなり異なる可能性があります。
要するに、私の経験では経由するネットワークはたいてい非常によく似ていて、どちらの方向であっても内容は関連性があり興味深いです。
tracerouteがどのように動作するかに関連して、興味深い論文がある。ネットワーク畑ではない人がよく見落とす点は、tracerouteは必ずしも対称ではないということ。返りの経路は異なる場合がある
https://archive.nanog.org/sites/default/files/traceroute-201...
これまでインターネット上で見たECMP数の2倍と言っていい
そしてカイロのオフィスから英国コアへ向かうトラフィックと、その逆方向のトラフィックも異なる経路を通っていた。London→Cairoは直通で、依然として大量の損失があるが、Cairo→Londonは今はntt経由になっていて問題なさそうだ。明日までに直らなければローカルプリファレンスを変える必要があるかもしれない
「WHOISはパーサを作るには興味深いプロトコルだ」と言っていたが、実際には不可能に近い
応答が本質的に自由形式で、サーバーが応答しないこともある。自分も試したが、10年前の時点でアドレスやドメインの90%に対して動くその場しのぎのパーサは作れたものの、残りは処理不能だった
今ではさらに悪化していて、ほとんどすべてがプライバシー保護の幕の後ろに隠れている。PIIを保護するためだと主張されているが、WHOISレコードはもともと個人情報を載せるものではなく、ネットワーク運用者の連絡先を載せるものだった
これはICANNの責任だと思う。ICANNにはネットワークが公開WHOISサーバーを提供しなければならないという規則があったが、執行せず、今ではその規則自体を廃止してしまった
ただし、どこもRDAPサーバーを運用しているわけではない。ICANN/IANAであれ誰かであれ、これを義務化してくれるとよいのだが
ネットワーク運用者の情報もPIIになりうる。自分の情報はPIIだし、自分はドメイン名を持っているのだから、自分の情報をWHOISに入れるのはPIIをWHOISに入れることになる
プライバシー保護サービスは、スパムを除けばすべて自分に転送してくれるだけだ
企業ならプライバシー保護サービスを認める妥当な理由はないと思うが、まだすべてのドメインが大企業の所有というわけではない
別個のICMP ECHO追跡の代わりに、クライアントブラウザとWebサーバーの間にある既存のHTTP TCP接続を利用すれば、一歩先へ進める
そうすればクライアント側のNATやステートフルファイアウォールを通過できる
reverse tracerouteに関する以前の研究がある
https://research.cs.washington.edu/networking/astronomy/reve...
論文: http://www.cs.washington.edu/homes/ethan/papers/reverse_trac...
動画: http://www.usenix.org/multimedia/nsdi10katz-bassett
TCPセッションのパケットがインターネットを通過する際に非対称経路をたどることが多い、という点も知っておく価値がある。自分の経験では、もっとも一般的な理由はコストに関するビジネスルールと、人為ミスだった
IPがどのように動作するかを考えれば、それ自体は特に問題ではないが、ルーティングの理解はより難しくなりうる
Boise State UniversityとUniversity of Idahoは、Idaho州の両端にある学校だ。北側のUIdahoはSpokaneに近く、接続の大半はSeattleから来ており、BoiseはSalt Lake寄りなのでPortlandやSalt Lake City経由で接続されることが多い
両校の間にある州中央部は山岳地帯のため大規模な接続がほとんどなかったが、以前UofIdahoは南部地域の遠隔教室を持っていたため、小さな回線が1本あった
90年代後半のある時点で、BSUのネットワークエンジニアとUofIのエンジニアは、同じ建物内にスイッチとルーティング機器を置いていることを知り、その間をイーサネットケーブルでつないだ
結果は大惨事だった。両ネットワークが互いにBGPを広告し始め、その接続がインターネット全体に広まってしまった。突然、Seattle側のネットワークとSalt Lake City側のネットワークの間に非常に短いジャンプが生まれ、哀れな小さなT1回線は完全に飽和した
興味深いことに、それは片方向だけで起きた。Boiseは経路を広告したがIdahoはしなかったため、トラフィックは実質的に一方向だけ壊れた
当然ケーブルは引き抜かれ、その数年後に自分がUofIdahoで働いていた頃にも、この2つのネットワークは絶対に再接続してはいけないというのがよく知られていた。皮肉なことに、その当時自分は両大学にI2を構築するプログラムを進めていた
自分の端末では、自分の端末とサーバーの間の中間ホップがまったく表示されない。参考までに
今まさに対応中で、すぐにもっとよく動くようになるはずだ。それまではタイムアウトを延ばすので、読み込みは長くなるが、もう少しましに動作すると思う
mtr も言及する価値がある。私は traceroute よりはるかに頻繁に使っている
断続的なパケットロスの診断に役立ち、フローを平均的に把握できる
APNIC のこの記事では、mtr とその結果の読み方をより詳しく説明しており、MPLS が実際の経路をどのように見えにくくするかについても扱っている
https://blog.apnic.net/2022/03/28/how-to-properly-interpret-...
UDP で追跡するのも時には有用で、多くのルーターは負荷がかかると ICMP を選択的にドロップすることも知っておくとよい
良い記事で、表現も素晴らしい