【実務・中級編】 tracerouteのTTL(Time to Live)フィールド制御によるホップ数探索の仕組み – トラブルシューティング&ネットワーク運用監視実践ガイド

ネットワークの「迷宮」を紐解く: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 の仕組みを理解していれば、画面上の * が示唆する意味が、単なるエラーではなく「何らかの通信制御が行われている証拠」として見えてくるはずだ。

トラブルシューティングは技術者の醍醐味だ。ぜひ、この「迷宮を解く鍵」を使いこなして、現場の障害を鮮やかに解決してほしい。

コメント

タイトルとURLをコピーしました