tcpdump 入門 - パケットキャプチャで通信を可視化する
この記事で解決できること
tcpdumpで パケットを取り始める最短手順 が分かる- BPF フィルタで 見たい通信だけに絞り込む 方法が身につく
- pcap 保存 → Wireshark で読む 連携の型が分かる
- 「接続できない」「応答が遅い」を パケットレベルで切り分け できる
結論(実務の型)
- まず
sudo tcpdump -i any -nnで生きている通信を眺める - 騒がしいときは
host/portフィルタで対象を絞る - 後で解析するなら
-w cap.pcapで保存し Wireshark へ - 原則
-nnを付ける(名前解決の待ちで固まらない)
前提(対象環境)
- OS:Ubuntu / 一般的な Linux
tcpdumpはパケットキャプチャに root 権限(CAP_NET_RAW)が必要 →sudo前提- 未インストールなら
sudo apt install tcpdump
tcpdump とは何か?
結論: tcpdump は CLI のパケットキャプチャツール。NIC を流れる生のパケットを取得・表示し、通信の有無や中身を直接確認できる。
tcpdump は、ネットワークインターフェイス(NIC)を通過するパケットをそのまま取得して表示する CLI ツール。Web の応答が返らない、TCP が確立しない、といった事象を「サーバまでパケットが届いているか」「応答が返っているか」という事実ベースで切り分けられる。
GUI の Wireshark と内部のキャプチャ基盤(libpcap / BPF)は共通で、tcpdump はその CLI 版にあたる。サーバ上で SSH 越しに即実行できるのが強み。
パケットキャプチャは通信内容(場合によっては認証情報)を観測する行為。自分が管理する環境・許可された環境でのみ実行すること。
最短でキャプチャを始めるには?
結論:
sudo tcpdump -i any -nnが出発点。インターフェイス指定-i、名前解決抑止-nn、件数制限-cの3つを押さえれば十分動かせる。
まず流れている通信を眺める
$ sudo tcpdump -i any -nn
-i any:すべてのインターフェイスを対象(特定なら-i eth0)-nn:ホスト名もポート名も解決しない(DNS 逆引き待ちで固まらない / 数値のまま速く読める)
取得可能なインターフェイスを確認する
どの IF を指定すべきか分からないときは一覧を出す。
$ tcpdump -D
1.eth0 [Up, Running, Connected] 2.any (Pseudo-device that captures on all interfaces) [Up, Running] 3.lo [Up, Running, Loopback]
件数を区切って止める
tcpdump は止めるまで流れ続ける。-c で件数を区切ると扱いやすい。
$ sudo tcpdump -i any -nn -c 20
手動で止めるときは Ctrl + C。終了時に「received / dropped by kernel」の統計が表示される。dropped が多い場合は取りこぼしが発生している。
出力の1行をどう読むのか?
結論: 各行は「時刻 送信元 > 宛先 フラグ・シーケンス・長さ」の順。
>の向きと TCP フラグ(S/F/P/R/.)で通信の流れと状態を読む。
典型的な TCP の1行は次の形。
10:11:12.345678 IP 192.168.1.10.54322 > 93.184.216.34.443: Flags [S], seq 123456, win 64240, length 0
| 要素 | 意味 |
|---|---|
10:11:12.345678 |
タイムスタンプ |
192.168.1.10.54322 |
送信元 IP とポート(末尾がポート) |
> |
通信方向(左 → 右) |
93.184.216.34.443 |
宛先 IP とポート(443 = HTTPS) |
Flags [S] |
TCP フラグ(後述) |
length 0 |
ペイロード長 |
TCP フラグの読み方
| 表記 | フラグ | 意味 |
|---|---|---|
S |
SYN | 接続開始要求 |
S. |
SYN/ACK | 接続要求への応答 |
. |
ACK | 確認応答のみ |
P |
PSH | データ送出(push) |
F |
FIN | 接続終了 |
R |
RST | 接続の強制リセット |
3ウェイハンドシェイクが成立していれば [S] → [S.] → [.] が並ぶ。[S] を送って [R](RST)が返る、あるいは何も返らない場合は、ポートが閉じている / 経路で遮断されている可能性が高い。
見たい通信だけに絞るには?(BPFフィルタ)
結論: コマンド末尾に BPF 式を書くと対象を絞れる。
host/port/src/dstとand/or/notの組み合わせがほぼすべて。
tcpdump の引数末尾に書く条件式を BPF(Berkeley Packet Filter)という。代表的なものだけ覚えれば実務は回る。
# 特定ホストとの通信だけ $ sudo tcpdump -i any -nn host 93.184.216.34 # 特定ポートだけ(HTTPS) $ sudo tcpdump -i any -nn port 443 # 送信元 / 宛先を限定 $ sudo tcpdump -i any -nn src 192.168.1.10 $ sudo tcpdump -i any -nn dst port 53 # プロトコルを限定 $ sudo tcpdump -i any -nn udp port 53
条件を組み合わせる
# host A かつ port 443 $ sudo tcpdump -i any -nn host 192.168.1.10 and port 443 # 22番(SSH)以外を見たい $ sudo tcpdump -i any -nn not port 22 # DNS か HTTPS $ sudo tcpdump -i any -nn 'port 53 or port 443'
and / or / not を含む式や括弧を使う場合は、シェルの解釈を避けるため 式全体をシングルクォート で囲む(例: 'tcp port 80 and host 10.0.0.1')。
よく使う語彙: host / net 192.168.1.0/24 / port / portrange 8000-8100 / src / dst / tcp / udp / icmp / arp。
中身(ペイロード)まで見るには?
結論:
-Aで ASCII、-Xで16進+ASCII を表示。平文の HTTP ヘッダや DNS クエリの確認に有効。詳細度は-v/-vvで調整する。
ヘッダだけでなくパケットの中身を確認したいときに使う。
# ASCII でペイロード表示(HTTPヘッダ等の確認に) $ sudo tcpdump -i any -nn -A port 80 # 16進数 + ASCII(バイナリ解析向け) $ sudo tcpdump -i any -nn -X port 80 # 詳細度を上げる(TTL・オプション等) $ sudo tcpdump -i any -nn -vv host 192.168.1.10
HTTPS(443)はペイロードが暗号化されているため -A / -X で中身は読めない(TLS のハンドシェイクや SNI の一部は見える)。平文が見えるのは HTTP・DNS など暗号化されていない通信。
古い情報で -s 0(スナップ長を無制限に)が必要とされることがあるが、近年の tcpdump は既定のスナップ長が十分大きく(262144 バイト)、通常は指定不要。
キャプチャを保存して後で解析するには?
結論:
-w file.pcapでバイナリ保存、-r file.pcapで読み戻す。保存した pcap は Wireshark でそのまま開けるので、取得はサーバ・解析は手元という分業ができる。
保存と読み戻し
# pcap 形式で保存(画面には出さず書き出す) $ sudo tcpdump -i any -nn -w capture.pcap # 保存したファイルを読む(読むだけなら sudo 不要) $ tcpdump -nn -r capture.pcap # 読み込み時にもフィルタを後がけできる $ tcpdump -nn -r capture.pcap port 443
取得はサーバ、解析は手元
- サーバで
sudo tcpdump -i any -nn -w /tmp/cap.pcap port 443 -c 1000 - 手元へ転送(
scp user@server:/tmp/cap.pcap .) - Wireshark で
cap.pcapを開く
GUI のフィルタ・追跡機能で深く追えるので、込み入った解析はこの型が速い。
ファイルを回して溜めすぎない
長時間キャプチャはディスクを圧迫する。サイズや時間でローテーションできる。
# 100MB ごとにファイルを分割、最大10ファイルで循環 $ sudo tcpdump -i any -nn -w cap_%Y%m%d_%H%M%S.pcap -C 100 -W 10
-C 100:1ファイル約100MBで切り替え-W 10:保持ファイル数の上限(超えると古いものから上書き)
切り分けの実例:接続できない
結論: 「SYN を送って応答が無い / RST が返る」かを見れば、到達性とポート開放を一気に切り分けられる。
ある相手の443番に繋がらないときの確認。
$ sudo tcpdump -i any -nn host 93.184.216.34 and port 443
判断の目安:
[S]を送って[S.]が返る → 到達・ポート開放はOK(問題はアプリ層)[S]を送って[R](RST)が返る → 相手まで届いているがポートが閉じている[S]を送るが何も返らない → 経路の途中(FW・経路設定)で落ちている可能性- 自分発の
[S]すら出ない → ローカルの経路・名前解決・アプリ側を疑う
ping / traceroute での到達性確認と併用すると切り分けが速い。詳細は関連記事を参照。
よく使うオプション早見表
結論:
-i/-nn/-c/-w/-r/-A/-vの7つを押さえれば日常のトラブルシュートは十分カバーできる。
| オプション | 役割 |
|---|---|
-i IF |
キャプチャするインターフェイス(any 可) |
-nn |
ホスト名・ポート名を解決しない |
-c N |
N 件で停止 |
-w FILE |
pcap 形式で保存 |
-r FILE |
pcap を読み込む |
-A |
ペイロードを ASCII 表示 |
-X |
16進数 + ASCII 表示 |
-v/-vv |
詳細度を上げる |
-e |
リンク層(MAC アドレス)も表示 |
-D |
利用可能なインターフェイス一覧 |
コピペ用:安全テンプレ
# まず眺める sudo tcpdump -i any -nn -c 50 # 対象を絞る sudo tcpdump -i any -nn host 192.168.1.10 and port 443 # 保存して後で解析 sudo tcpdump -i any -nn -w /tmp/cap.pcap port 443 -c 1000 tcpdump -nn -r /tmp/cap.pcap