TCP通信の可視化:Wiresharkとtcpdumpによる実践的解析

ネットワーク通信において、TCPの挙動を「見える化」するには、適切なツールと環境構築が不可欠です。本稿では、パケットの損失、順序乱れ、再送制御、フロー制御といったTCPの核心機能を、実際にキャプチャしたデータで明確に解説します。

目に見えないパケットを可視化する

ネットワーク上のデータ交換は通常、肉眼では確認できません。この抽象性がコンピュータネットワーク学習の障壁となります。しかし、tcpdumpWireshark の2つのツールを使えば、不可視だった通信が視覚的に把握可能になります。

  • tcpdump:Linuxサーバー向けのコマンドラインツール。特定条件でパケットを収集し、pcap形式で保存。
  • Wireshark:GUIベースの解析ツール。保存されたpcapファイルを開き、プロトコルごとに色分けして詳細なレイヤー情報を表示。

例として、ICMPのping通信をキャプチャする場合:

$ tcpdump -i eth0 icmp and host 183.232.231.174 -w ping.pcap

上記コマンドで取得したファイルをWiresharkで開くと、データリンク層からIP層、ICMP層までの各ヘッダ情報が階層的に表示されます。これにより、MACアドレス、TTL、ICMPタイプなどの詳細を即座に確認できます。

HTTP通信におけるTCPハンドシェイクの観察

HTTP通信を例に、TCPの3ウェイハンドシェイクと4ウェイ切断を観察します。

$ tcpdump -i eth0 host 192.168.3.200 -w http.pcap
$ curl http://192.168.3.200

Wiresharkでhttp.pcapを開くと、最初の3パケットがSYN → SYN-ACK → ACKのハンドシェイク、最後の3パケットがFINによる切断処理です。統計メニューの「フローグラフ」を使うと、時系列で通信フローを視覚化できます。

なお、ウィザードのデフォルト設定では相対シーケンス番号が表示されますが、「プロトコル設定」→「TCP」→「Relative sequence numbers」を無効にすると、実際のランダムな初期シーケンス値を確認できます。

異常ケースの実験:SYNパケット消失時の挙動

仮想マシン2台(クライアント: 192.168.12.37, サーバー: 192.168.12.36)を使用し、以下の3つの異常ケースを検証しました。

ケース1:最初のSYNパケットが消失

サーバーのネットワークケーブルを抜いた状態でcurlを実行。クライアントはSYNパケットを5回まで指数バックオフ(1s, 3s, 7s, 15s, 31s)で再送。最大再送回数は/proc/sys/net/ipv4/tcp_syn_retriesで制御されます。

ケース2:SYN-ACKパケットが消失

クライアント側でiptablesによりサーバーからの応答を破棄:

$ iptables -A INPUT -s 192.168.12.36 -j DROP

このとき、クライアントはSYNを再送し、サーバーもSYN-ACKを再送(最大5回)。再送上限はtcp_synack_retriesで設定可能です。

ケース3:最終ACKパケットが消失

サーバー側でACKパケットを破棄:

$ iptables -A INPUT -p tcp --tcp-flags ACK ACK -j DROP

サーバーはSYN-ACKを5回再送後、接続を破棄。一方クライアントはESTABLISHED状態のまま維持され、データ送信時に最大15回(tcp_retries2)再送を試みた後に切断されます。

TCP Fast Openによる高速接続

Linux 3.7以降では、TCP Fast Open(TFO)が利用可能です。初回接続時にサーバーがCookieを発行し、次回以降はSYNパケットにCookieを含めて送信することで、ハンドシェイク完了前にデータ転送が可能になります。

$ sysctl -w net.ipv4.tcp_fastopen=3

値の意味:
0 = 無効、1 = クライアント有効、2 = サーバー有効、3 = 両方有効

高速再送とSACK

受信側が順序違いのパケットを受信すると、同じACKを繰り返し送信します。送信側は同一ACKを3回受信すると、そのパケットを即時再送(高速再送)します。SACK(Selective Acknowledgment)が有効であれば、欠落部分のみを再送可能で効率的です。

$ sysctl -w net.ipv4.tcp_sack=1

フロー制御とゼロウィンドウ

受信バッファが満杯になると、受信ウィンドウサイズが0(ゼロウィンドウ)を通知します。送信側は定期的に「ウィンドウプローブ」パケットを送信し、ウィンドウ復活を確認します。プローブ間隔は3.4秒 → 6.8秒 → 13.5秒と倍増します。

Nagleアルゴリズムと遅延ACKの干渉

小規模データの送信を抑えるNagleアルゴリズムと、ACKをまとめて送る遅延ACKが同時に有効だと、最大200msの待ち時間が発生します。リアルタイム性が必要なアプリ(SSHなど)では、以下のように無効化すべきです。

// Nagle無効化
setsockopt(sock, IPPROTO_TCP, TCP_NODELAY, &flag, sizeof(flag));

// 遅延ACK無効化
setsockopt(sock, IPPROTO_TCP, TCP_QUICKACK, &flag, sizeof(flag));

タグ: Wireshark tcpdump TCP/IP ネットワーク解析 フローコントロール

7月22日 18:58 投稿