Linuxでのtcpdumpの使い方ガイド:パケットキャプチャと解析によるネットワークデバッグ

Linux tutorial - IT technology blog
Linux tutorial - IT technology blog

アプリでエラーが出るのにpingが通る理由

次のようなトラブルは現場で日常茶飯事です。モバイルアプリでAPI呼び出し時にタイムアウトエラーが発生したとします。サーバーにSSH接続してデータベースや連携先APIのサーバーへpingを実行すると、パケットロスは0%、RTTもわずか2msと正常に応答します。しかし、バックエンドのログには相変わらずConnection timed outやConnection refusedが出力され続けます。

原因は極めてシンプルです。pingはICMPプロトコルを使用しているのに対し、アプリケーションはTCP/UDPで通信しているためです。ICMP Echo Requestが通るからといって、TCPの443番や5432番ポートが接続を受け付けているとは限りません。ファイアウォールが特定のアプリケーションポートのみ遮断している可能性もあれば、Webサーバーのバックログキューが溢れている可能性もあります。ネットワーク上で実際に何が起きているのかを正確に把握するには、tcpdumpを使って物理パケットを直接観察する必要があります。

tcpdumpのパケットキャプチャと解析の仕組み

tcpdumpは、libpcapライブラリをベースにした定番のCLIネットワーク解析ツールです。OSのネットワークスタックやiptablesによる詳細な処理が行われる前に、ネットワークカード(NIC)を出入りするデータフレームを直接インターセプトします。

TCP接続をデバッグする際は、角括弧[...]内に表示される次の4つの主要フラグに着目します。

  • [S] (SYN): 3ウェイハンドシェイク(3-way handshake)の開始パケット。
  • [S.] (SYN-ACK): サーバー側がハンドシェイクを承諾し、クライアントへ応答するパケット。
  • [.] (ACK): 先行パケットを正常に受信したことを示す確認応答。
  • [F] (FIN): 一方からの通常の接続終了要求。
  • [R] (RST): 接続の即時リセット。ポートが開放されていない、受信プロセスが突然クラッシュした、あるいはファイアウォールが能動的にRSTを返してアクセスを拒否した際によく見られます。

実践:現場で使えるtcpdumpコマンド

1. クイックインストール

tcpdumpは主要なLinuxディストリビューションの標準リポジトリで提供されています。

# Ubuntu / Debian
sudo apt update && sudo apt install -y tcpdump

# RHEL / CentOS / Rocky Linux / AlmaLinux
sudo dnf install -y tcpdump

2. ネットワークインターフェースの確認

まず、対象サーバーにどのインターフェースが存在するかを確認します。

sudo tcpdump -D

実行すると、1.eth0、2.ens33、あるいはany(全インターフェースを対象)のように、インデックス番号付きで一覧が表示されます。

3. 必須の基本パラメータ

オプションを指定せずにtcpdumpを実行すると、ターミナルが一瞬でログに埋め尽くされます。必ず以下の最適化フラグを組み合わせて使用しましょう。

  • -i <interface>: 監視対象のネットワークインターフェースを指定(例: -i eth0、-i any)。
  • -n: IPアドレスの名前解決を無効化し、ログ出力の遅延を防ぐ。
  • -nn: ホスト名とポート番号の両方の名前解決を無効化(httpやhttpsではなく80、443と直接表示)。
  • -c <パケット数>: 指定したパケット数をキャプチャしたら自動終了(例: -c 20)。
  • -q: 簡易出力モード。パケットの重要な情報のみを簡潔に表示。

安全に素早く疎通確認を行うためのコマンド例(5パケットのみキャプチャ):

sudo tcpdump -i eth0 -nn -c 5

4. BPF(Berkeley Packet Filter)によるパケットフィルタリング

tcpdump最大の強みは、柔軟なBPFフィルタ構文にあります。and、or、notを使って複数条件を組み合わせることが可能です。

ケースA: 送信元・宛先IPによる絞り込み

特定のクライアント(例: 192.168.1.50)でAPI呼び出しエラーが発生している場合:

# IP 192.168.1.50 との送受信双方向トラフィックをすべてキャプチャ
sudo tcpdump -i eth0 -nn host 192.168.1.50

# クライアントからサーバーへのリクエストのみを追跡
sudo tcpdump -i eth0 -nn src host 192.168.1.50

# サーバーからクライアントへのレスポンスデータのみを追跡
sudo tcpdump -i eth0 -nn dst host 192.168.1.50

ケースB: Webサーバーの接続トラブル調査(ポート 80 / 443)

HTTP/HTTPSトラフィックのみを抽出し、TCPハンドシェイクの状態を確認します。

sudo tcpdump -i eth0 -nn "port 80 or port 443" -c 50

クライアントから[S]が繰り返し送信されているのにサーバーから[S.]が返ってこない場合、iptablesやUFWでパケットがDROPされている可能性が高いです。逆に、サーバーが即座に[R](RST)を返している場合は、NginxやApacheなどのプロセスがダウンしているか、指定ポートで適切にListenできていません。

ケースC: DNSタイムアウト障害の調査(ポート 53)

外部へのcurlコマンドでデータの取得開始までに5〜10秒もかかる場合、DNSの名前解決遅延が原因であることが多々あります。

sudo tcpdump -i eth0 -nn udp port 53

どのDNSリゾルバ(8.8.8.8やローカルリゾルバなど)へA/AAAAクエリが送信され、応答受信までに何ミリ秒要しているかを明確に確認できます。

5. Wireshark解析用のpcapファイル出力

複雑なTLSハンドシェイクやHTTPペイロードをターミナル上で追跡すると、重要な痕跡を見落としがちです。パケットをそのまま保存し、GUIで視覚的に解析できるWiresharkへエクスポートしましょう。

# ポート443で200パケットをキャプチャし、dump.pcapファイルへ書き出す
sudo tcpdump -i eth0 -nn -c 200 port 443 -w /tmp/dump.pcap

サーバー上でGUIを使わずに保存したファイルを直接確認したい場合:

tcpdump -nn -r /tmp/dump.pcap

6. 本番環境(Production)での運用上の注意点

高負荷な本番環境で安易にtcpdumpを実行すると、CPU使用率の急上昇や継続的なディスクI/Oによる容量逼迫を招く恐れがあります。例えば10,000 req/sを捌くAPIクラスターでは、わずか2分で数GB規模のpcapファイルが生成されてしまいます。

リソース枯渇によるサーバーダウンを防ぐため、以下の3原則を必ず遵守してください。

  • 必ず -c フラグを使用する: 既定のパケット数で自動停止させます(例: -c 500、-c 1000)。
  • TCPヘッダーのみ保存する: -s 96(snaplen 96バイト)を指定してデータペイロードを破棄し、ヘッダー部分のみをキャプチャします。ファイルサイズを80%以上削減できます。
  • 無条件(フィルタなし)の全パケットキャプチャは避ける: 特定のIPやポートで必ず絞り込みを行います。

まとめ

tcpdumpは、Linuxシステムを運用するエンジニアにとって不可欠な診断ツールです。原因不明のネットワーク障害が発生した際も、数行のコマンドを実行するだけで、問題がアプリケーションコードにあるのか、内部ファイアウォールにあるのか、あるいはISP経路にあるのかを即座に切り分けることができます。基本的なBPF構文を押さえて、次回のオンコールや障害対応に備えておきましょう。

Share: