「pingが通るのに繋がらない」を即座に解決する:TCP Tracerouteの現場的活用術
ネットワーク運用において、最もフラストレーションが溜まるのは「疎通確認はできるのに、肝心のアプリケーションが動かない」という瞬間です。ping(ICMP)は平然と応答を返すのに、Web APIはタイムアウトで死んでいる。そんな時、新人エンジニアは「ファイアウォール(FW)のせいかな?」と曖昧な推測に終始しがちですが、我々シニアエンジニアは違います。
答えはパケットの挙動の中にあります。今回は、ICMPベースの標準的な traceroute では見抜けない、L4(トランスポート層)の壁を突破するための「TCP traceroute」の極意を解説します。
—
なぜ「TCP」のtracerouteが必要なのか
多くのネットワークエンジニアが最初に習う traceroute(あるいはWindowsの tracert)は、デフォルトでUDPパケット、あるいはICMP Echo Requestを使用します。しかし、現在のデータセンター環境では、ステートフルなFWやロードバランサー(LB)が、アプリケーションのポート番号を厳格に監視しています。
ICMPやUDPは優先度が低く、あるいはセキュリティポリシーによって破棄されていることが多い。一方、APIサービスが待ち受けているポート(例えば 443 や 8080)へ直接TCP SYNパケットを送り込む手法なら、「そのポートが本当に通信を許可しているか」と「どこでドロップされているか」を同時に検証できます。
TCP Tracerouteの仕組みと「SYN」の威力
TCP tracerouteの基本は、ターゲットのポートに対してSYNパケットを投げ、TTL(Time To Live)を徐々に増加させていく手法です。
1. TTL=1で送信: 最初のルータが「Time Exceeded」を返してくる。
2. TTLを増やす: 次のホップが応答する。
3. ターゲットに到達: サービスが稼働していれば SYN/ACK が返り、ポートが閉じられていれば RST が返る。もしFWでドロップされていれば、そこから先は無反応(Timeout)となります。
これにより、「ルータの経路」ではなく「アプリ通信の経路」が可視化されるわけです。
—
実践:CLIツールでTCP経路を追い込む
Linux環境であれば、traceroute コマンドに -T オプションを付けるだけで、簡単にTCPモードへ切り替えられます。
# TCP SYNパケットを使い、80番ポートへの経路を調査する
# -T: TCPモード
# -p 80: ターゲットポートを80に指定
traceroute -T -p 80 192.168.1.100
# より詳細なプローブを投げたい場合は -n (DNS解決無効) も併用する
traceroute -n -T -p 443 api.example.com
Pythonでパケットフローを制御する(Scapy活用)
もし、より複雑なヘッダー操作や、特定のフラグ(ACKフラグ付きのプローブなど)が必要な場合は、Pythonの scapy ライブラリが最強の武器になります。
from scapy.all import *
# ターゲットIPとポートを指定
target_ip = "192.168.1.100"
target_port = 443
# TTLを1から30までインクリメントしながら送信
for i in range(1, 31):
pkt = IP(dst=target_ip, ttl=i) / TCP(dport=target_port, flags="S")
reply = sr1(pkt, timeout=2, verbose=0)
if reply is None:
print(f"{i}: * (タイムアウト)")
elif reply.type == 11: # ICMP Time Exceeded
print(f"{i}: {reply.src}")
elif reply.haslayer(TCP): # ターゲットに到達!
print(f"{i}: 到達成功! {reply.src}")
break
—
運用現場での「見落としがちな罠」
この手法を使う際、現場でよくある失敗談を共有しておきます。
- L4バランサーの挙動: 大規模環境のLB(F5 BIG-IPやAWS NLBなど)は、TCP SYNを受信すると、バックエンドのサーバーの状態に関わらず、LB自身が
SYN/ACKを返すことがあります。つまり、traceroute上は「到達成功」となっていても、実際にはバックエンドへの通信がヘルスチェックで失敗しているケースです。 - RSTの正体: もし経路の途中で
RSTパケットが返ってきたら、それはFWが「アクセス拒否」の意思表示をしている証拠です。ログを確認する前に、どのホップでRSTが発生したかを特定するのが、問題解決の近道です。
まとめ:ツールを「目的」に合わせる
教科書的なコマンドを打つだけでは、本当の障害は見抜けません。
ping で疎通確認し、traceroute で経路を確認し、そして TCP traceroute でアプリケーションの入り口までパケットが届いているかを確認する。この三段構えこそが、我々NOCエンジニアの現場の作法です。
皆さんのインフラに「不可解な通信断」が発生した際は、ぜひこのTCPベースのプローブを試してみてください。パケットがどこで、なぜ弾かれているのか。その答えは、常にCLIのログの中に眠っています。
コメント