【Linux】tcpdumpによるパケット解析

tcpdumpは指定したネットワークインタフェース上を通過するパケットを目に見える形で表示してくれて、どんなパケットが来ているか(来ていないのか)を確認できるツールです。


下記の例ではeth0を通過するicmpパケットを拾っています。このコマンドを実行している状態で、別ターミナルでpingを実行します。

コマンド

tcpdump -ni eth0 icmp

実行結果

tcpdump: verbose output suppressed, use -v or -vv for full protocol decode listening on eth0, link-type EN10MB (Ethernet), capture size 262144 bytes 12:22:38.809758 IP 192.168.1.101 > 8.8.8.8: ICMP echo request, id 26913, seq 1, length 64 12:22:38.816623 IP 8.8.8.8 > 192.168.1.101: ICMP echo reply, id 26913, seq 1, length 64 12:22:39.810785 IP 192.168.1.101 > 8.8.8.8: ICMP echo request, id 26913, seq 2, length 64 12:22:39.817819 IP 8.8.8.8 > 192.168.1.101: ICMP echo reply, id 26913, seq 2, length 64 12:22:40.812053 IP 192.168.1.101 > 8.8.8.8: ICMP echo request, id 26913, seq 3, length 64 12:22:40.819771 IP 8.8.8.8 > 192.168.1.101: ICMP echo reply, id 26913, seq 3, length 64 12:22:41.814175 IP 192.168.1.101 > 8.8.8.8: ICMP echo request, id 26913, seq 4, length 64 12:22:41.823410 IP 8.8.8.8 > 192.168.1.101: ICMP echo reply, id 26913, seq 4, length 64

黄色が自分から8.8.8.8へ送信したping request、緑が8.8.8.8からのping reply。ping実行すると行きと帰りで2セット出力されます。上記は4回pingを実行した結果となります。
※8.8.8.8はGoogleのDNSサーバで、インターネット経由でping応答を返してくれるのです(記事投稿時点では)。覚えやすいIPアドレスのため、サーバがインターネットに出れるかどうかの調査でよく使わせて頂いております。

引数 意味
n ホスト名をIPアドレスに変換させないで結果を表示させる。
i パケットキャプチャを行うインタフェースを指定する。インタフェースが複数ある場合は指定しましょう。確か指定しないと一番若いインタフェース(大体eth0)になったかと思います。
icmp キャプチャするプロトコルを指定します。tcpやudp等も指定可能。

ちなみに相手からの応答がない場合は以下のようになります。相手からのping replyがありません。

実行結果

tcpdump: verbose output suppressed, use -v or -vv for full protocol decode listening on eth0, link-type EN10MB (Ethernet), capture size 262144 bytes 12:39:04.982117 IP 192.168.1.101 > 192.168.2.1: ICMP echo request, id 27209, seq 1, length 64 12:39:05.981727 IP 192.168.1.101 > 192.168.2.1: ICMP echo request, id 27209, seq 2, length 64 12:39:06.981840 IP 192.168.1.101 > 192.168.2.1: ICMP echo request, id 27209, seq 3, length 64 12:39:07.981527 IP 192.168.1.101 > 192.168.2.1: ICMP echo request, id 27209, seq 4, length 64


次はポートを指定してパケットを取得します。この例ではFTP通信で利用する20番、21番ポートが関連するパケットを取得しています。こちらもping同様、コマンドを実行した状態で別途FTP通信を発生させます。

コマンド

tcpdump -nni eth0 port 20 or port 21

実行結果

tcpdump: verbose output suppressed, use -v or -vv for full protocol decode listening on eth0, link-type EN10MB (Ethernet), capture size 262144 bytes 19:36:41.972720 IP 192.168.1.100.63501 > 192.168.1.101.21: Flags [S], seq 3908844646, win 8192, options [mss 1460,nop,wscale 0,nop,nop,sackOK], length 0 19:36:41.972756 IP 192.168.1.101.21 > 192.168.1.100.63501: Flags [S.], seq 2821952715, ack 3908844647, win 29200, options [mss 1460,nop,nop,sackOK,nop,wscale 7], length 0 19:36:41.973075 IP 192.168.1.100.63501 > 192.168.1.101.21: Flags [.], ack 1, win 8192, length 0 19:36:41.974361 IP 192.168.1.101.21 > 192.168.1.100.63501: Flags [P.], seq 1:21, ack 1, win 229, length 20: FTP: 220 (vsFTPd 3.0.2) 19:36:41.982247 IP 192.168.1.100.63501 > 192.168.1.101.21: Flags [P.], seq 1:15, ack 21, win 8172, length 14: FTP: OPTS UTF8 ON 19:36:41.982302 IP 192.168.1.101.21 > 192.168.1.100.63501: Flags [.], ack 15, win 229, length 0 19:36:41.982384 IP 192.168.1.101.21 > 192.168.1.100.63501: Flags [P.], seq 21:47, ack 15, win 229, length 26: FTP: 200 Always in UTF8 mode. 19:36:42.022859 IP 192.168.1.100.63501 > 192.168.1.101.21: Flags [.], ack 47, win 8146, length 0

黄色の部分は有名な3ウェイハンドシェイクかと思われます。緑字部分は[FTP]の文字列も見えますし、アプリケーション層のパケットのやり取りですね。ちなみにポート番号はIPアドレスの後、[.]に続く数字で表示されています。

続いてFTPログイン後にアクセス先のサーバ上でlsを叩いてみます。(ファイル一覧を取得する。)

実行結果

20:00:23.982151 IP 192.168.1.100.63810 > 192.168.1.101.21: Flags [P.], seq 77:104, ack 218, win 7975, length 27: FTP: PORT 192,168,1,100,249,68 20:00:23.982316 IP 192.168.1.101.21 > 192.168.1.100.63810: Flags [P.], seq 218:269, ack 104, win 229, length 51: FTP: 200 PORT command successful. Consider using PASV. 20:00:23.989049 IP 192.168.1.100.63810 > 192.168.1.101.21: Flags [P.], seq 104:110, ack 269, win 7924, length 6: FTP: NLST 20:00:23.989259 IP 192.168.1.101.20 > 192.168.1.100.63812: Flags [S], seq 734891644, win 29200, options [mss 1460,sackOK,TS val 500462092 ecr 0,nop,wscale 7], length 0 20:00:23.989489 IP 192.168.1.100.63812 > 192.168.1.101.20: Flags [S.], seq 201576010, ack 734891645, win 65535, options [mss 1460,nop,wscale 8,nop,nop,sackOK], length 0 20:00:23.989528 IP 192.168.1.101.20 > 192.168.1.100.63812: Flags [.], ack 1, win 229, length 0 20:00:23.989570 IP 192.168.1.101.21 > 192.168.1.100.63810: Flags [P.], seq 269:308, ack 110, win 229, length 39: FTP: 150 Here comes the directory listing. 20:00:23.989595 IP 192.168.1.101.20 > 192.168.1.100.63812: Flags [P.], seq 1:11, ack 1, win 229, length 10 20:00:23.989606 IP 192.168.1.101.20 > 192.168.1.100.63812: Flags [F.], seq 11, ack 1, win 229, length 0 20:00:23.989708 IP 192.168.1.100.63812 > 192.168.1.101.20: Flags [.], ack 12, win 8212, length 0 20:00:23.989781 IP 192.168.1.101.21 > 192.168.1.100.63810: Flags [P.], seq 308:332, ack 110, win 229, length 24: FTP: 226 Directory send OK. 20:00:23.989880 IP 192.168.1.100.63810 > 192.168.1.101.21: Flags [.], ack 332, win 7861, length 0 20:00:23.995457 IP 192.168.1.100.63812 > 192.168.1.101.20: Flags [F.], seq 1, ack 12, win 8212, length 0 20:00:23.995519 IP 192.168.1.101.20 > 192.168.1.100.63812: Flags [.], ack 2, win 229, length 0

注目してほしいのは黄色から緑に変わったところで、利用しているポート番号が変化しています。 FTPでは制御系の命令は21番を使い、データ転送系は20番を使うんですね。今回はファイルリストを取得しただけですが、その動作も20番が使われます。(ファイルリストのダウンロードとなるため。)

FTPでサーバにログインはできるのだけど、データが転送ができない、といった事象がたまにあります。考えらえる原因として、データ転送ポートの20番をFWで許可していないってのがほとんど。この辺のこともtcpdumpを使えば見えてきます。

このように、tcpdumpを使えばサーバ-クライアント間の通信がよーく見えてきます。クライアントからサーバへ通信を行っているのに、サーバ側のtcpdumpの結果にパケットが乗ってこなければ、経路上のどこかでパケットが破棄されていることが分かりますし、 サーバ上でパケットは確認できるけども、アプリケーションが正常に動作していなければ、サーバ側に問題があると考えられます。問題発生時の切り分け手段として、是非使ってみてください。