tcpdumpを用いたパケットキャプチャの方法を調べていたのでそのときのメモ。
基本的な使い方
tcpdumpはrootユーザもしくはsudoを付けて実行する。実行中は、キャプチャしたパケットが標準出力に表示される。終了するときはCtrl+cでプロセスを停止させる。
以下は、GoogleのパブリックDNS(8.8.8.8)にpingを打ったときのパケットキャプチャ。行きと返りのパケットが表示されていることがわかる。
$ sudo tcpdump 23:20:40.518757 IP 192.168.1.1 > google-public-dns-a.google.com: ICMP echo request, id 33301, seq 5, length 64 23:20:40.611513 IP google-public-dns-a.google.com > 192.168.1.1: ICMP echo reply, id 33301, seq 5, length 64
キャプチャ条件の指定
tcpdumpはキャプチャするパケットの条件を指定することが可能。以下よく使いそうなもの。
192.168.1.1 が送信元または宛先のIPであり、ポート80 が送信元または宛先のポートであるパケット。
$ sudo tcpdump host 192.168.1.1 and port 80
パケットのプロトコルがICMPであり、宛先ネットワークアドレスが 192.168.1.0/24 以外のパケット。
$ sudo tcpdump icpm and not dest net 192.168.1.0/24
送信元IPが 192.168.1.1 もしくは 192.168.1.2 であるパケット。
$ sudo tcpdump src host 192.168.1.1 or src host 192.168.1.2
キャプチャ内容をファイルに出力
-w オプションを付ける事で、キャプチャ内容をファイルに出力することができる。
以下のコマンドを実行すると、現在のディレクトリに test.pcap というディレクトリができる。
$ sudo tcpdump -w test.pcap
生成されたファイルは生データなので、 more や less では読めない。WireSharkなどのソフトか、 tcpdump の -r で内容を確認できる。ファイルを読むだけならroot権限はいらない。
$ tcpdump -r test.pcap
キャプチャ内容をファイルに出力できないとき
ここでハマった。tcpdumpを実行するマシンのSELinuxが有効になっていると “Permission denied” が表示されファイルにキャプチャ内容を書き出せない場合がある。なのでSELinuxを無効にする。
参考:SELinuxを停止/無効化する
出力ファイルのローテーション
キャプチャ内容をファイルに出力する場合、ファイルサイズがあっという間に増加してしまう。そのため、ファイルサイズもしくは時間でファイルをローテーションさせる。
ファイルサイズでローテーションする場合。
-C オプションで一定の容量でローテーションするよう指定する。単位はMB。
-Z オプションでローテーション時の書き込み権限を指定する。root もしくは sudo できるユーザを指定。
以下の例では、100MBごとにファイルのローテーションを行う。ローテーション後のファイル名は test.pcap test.pcap1 test.pcap2 …とファイル名の末尾に数字が付与される。
$ sudo tcpdump -C 100 -Z root -w test.pcap
時間でローテーションする場合。
-G オプションで一定の時間でローテーションするように指定する。単位は秒。strftime形式でファイル名に時間を入れないと、ローテーション後に元のファイルが上書きされるので注意。
以下の例では、1時間ごとにファイルのローテーションを行う。2014/12/01 10:00に最初のコマンド実行を行ったとすると、ファイル名は test_20141201_100000.pcap test_20141201_110000.pcap test_20141201_120000.pcap …となる。
$ sudo tcpdump -G 3600 -Z root -w test_%Y%m%d_%H%M%S.pcap
ローテーション後にコマンドを実行させる場合。
-z オプションで、ローテーション後のファイルにコマンドを使用できる。
以下の例では、ローテーション後のファイルを自動的に圧縮している。
$ sudo tcpdump -G 3600 -Z root -w test_%Y%m%d_%H%M%S.pcap -z gzip
バックグラウンドで実行
実際にパケットキャプチャの運用をする場合、コマンド実行ユーザがログアウトした後もプロセスが動くようバックグラウンドでtcpdumpを実行する必要がある。
コマンド実行時は末尾に & を付けてバックグラウンドで実行する。
$ sudo tcpdump -G 3600 -Z root -w test_%Y%m%d_%H%M%S.pcap -z gzip &
プロセスを終了させるときは、psでPIDを調べてkillする。
$ ps -ef | grep -v grep | grep tcpdump 0 71139 71006 0 12:21AM ttys002 0:00.02 sudo tcpdump $ sudo kill 71139
3vgpem
6m3e02