ネットワークの「迷宮」を紐解く:tracerouteのTTL制御という職人芸
ネットワークエンジニアとして現場に立っていると、深夜2時に「APIのレスポンスが極端に遅い」というアラートで叩き起こされることがよくある。アプリケーション層のログを見ると確かに遅延しているが、それがアプリ側の処理なのか、あるいは途中のルータがパケットをドロップしているのか、あるいはBGPの経路がフラップしているのか――。
そんな時、我々が真っ先に頼るのが traceroute だ。しかし、単にコマンドを叩いて「*」が表示されたときに「回線が悪いですね」と即断するのは素人のすることだ。今回は、traceroute がIPヘッダーの TTL(Time to Live)をどう操り、ネットワークの深淵を可視化しているのか、その仕組みを現場の視点で深掘りしよう。
—
1. TTL:パケットの「寿命」を利用した逆転の発想
traceroute の核心は、IPヘッダーにある TTL フィールドを意図的にいじる「遊び」にある。
本来、TTL はネットワーク内でのルーティングループを防ぐためのものだ。ルータはパケットを転送するたびに TTL を1減らし、TTL が0になった瞬間にそのパケットを破棄し、送信元に対して「Time Exceeded(時間超過)」というICMPメッセージを返す。
traceroute はこの挙動を逆手に取っている。
1. 最初は TTL=1 でパケットを送る。最初のルータに到達した瞬間に TTL が0になり、ルータが「お前、寿命だぞ」というICMPを返してくる。これで1ホップ目が特定できる。
2. 次に TTL=2 で送る。1台目のルータは TTL=1 にして通過させ、2台目のルータが TTL=0 になってICMPを返してくる。
3. これを繰り返し、目的のホストに到達するまでホップ数をインクリメントし続ける。
実に泥臭く、しかし非常に確実な手法だ。
—
2. 通信シーケンスのリアルな挙動
実際のパケットは、多くのOSで UDP ポート番号を使い分けて送信される。
- 送信側: 送信元ポートは固定、宛先ポートは
33434から始まり、ホップごとにインクリメントされる。 - 受信側(対象のサーバー): 意図しない大きなポート番号へUDPが飛んでくるため、通常は「ICMP Port Unreachable」を返す。ここで
tracerouteは「あ、ここが終点か」と判断するわけだ。
もし、あなたのAPIサーバーがセキュリティのために ICMP を全拒否している場合、traceroute は途中で完全に沈黙する。運用保守の現場では、疎通確認のために最低限の ICMP Type 11(Time Exceeded)を許可しておくのが、インフラ設計上の「大人のマナー」だ。
—
3. 実践:コードで理解するホップ探索
Pythonの scapy ライブラリを使えば、この挙動を自分で実装することもできる。これにより、標準の traceroute コマンドが使えない制限の厳しい環境でも、独自の診断ツールを仕込めるようになる。
from scapy.all import IP, UDP, sr1
# 診断対象のターゲットIP
target_ip = "8.8.8.8"
# TTLを1から順にインクリメントして探索
for ttl in range(1, 30):
# IPヘッダーのTTLを設定し、UDPパケットを作成
packet = IP(dst=target_ip, ttl=ttl) / UDP(dport=33434)
# パケットを送信し、応答を待つ(タイムアウトは2秒)
reply = sr1(packet, timeout=2, verbose=0)
if reply is None:
print(f"{ttl}: * (タイムアウト)")
elif reply.type == 11: # ICMP Time Exceeded
print(f"{ttl}: 経由ルータ {reply.src}")
elif reply.type == 3: # ICMP Port Unreachable (到達成功)
print(f"{ttl}: 目的地に到達 {reply.src}")
break
—
4. 運用エンジニアが教える「現場のTips」
最後に、教科書には載っていない実践的な知見をいくつか共有しておく。
① mtr (My Traceroute) を愛せ
単発の traceroute はその瞬間の経路しか見せない。ネットワークのゆらぎやパケットロスを検知するには、mtr を使え。統計的な損失率(Loss%)を可視化することで、「どのルータで渋滞が起きているか」が瞬時に判別できる。
② TCP tracerouteの活用
ファイアウォールがUDPをブロックしている場合、-T オプション(Linux環境など)で TCP SYN パケットを使った traceroute を試してほしい。HTTP/HTTPSポート(80/443)に向けてパケットを投げることで、実際のAPIトラフィックに近い経路情報を得ることができる。
# 80番ポート宛にTCP SYNを投げて経路を確認する例
sudo traceroute -T -p 80 example.com
③ クラウド環境の落とし穴
AWSやGCPなどのクラウド環境では、仮想ルータが ICMP をフィルタリングしていたり、ECMP(等コストマルチパス)によってパケットごとに経路が変わったりする。traceroute の結果がバラバラでも、「壊れている」のではなく「そういう仕様」であることが多い。
—
ネットワーク診断の本質は、コマンドの結果を鵜呑みにすることではなく、その背後にある「パケットの往来」を脳内でシミュレーションすることにある。今日紹介した TTL の仕組みを理解していれば、画面上の * が示唆する意味が、単なるエラーではなく「何らかの通信制御が行われている証拠」として見えてくるはずだ。
トラブルシューティングは技術者の醍醐味だ。ぜひ、この「迷宮を解く鍵」を使いこなして、現場の障害を鮮やかに解決してほしい。
コメント