本稿では tcpdump コマンドを使ったパケットキャプチャについて概要を説明します。
1. はじめに
1.1. 確認した環境
本稿に記載した内容は下記の環境で検証しています。バージョンにより動作が異なる可能正があるので十分に注意してください。
$ cat /etc/centos-release
CentOS Linux release 7.9.2009 (Core)
$ tcpdump --version
tcpdump version 4.9.2
libpcap version 1.5.3
OpenSSL 1.0.2k-fips 26 Jan 2017
1.2. tcpdump コマンドのインストール
tcpdump コマンドがインストールされいない場合は yum install コマンドでインストールしましょう。
$ sudo yum install tcpdump
1.3. tcpdump コマンドのインストール
まずは ifconfig コマンドでパケットを受信するインターフェースを確認しましょう。下記の例で ens33 というのがインターフェース名です。ちなみに lo はローカルループバックです。
$ ifconfig
ens33: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500
inet 192.168.47.141 netmask 255.255.255.0 broadcast 192.168.47.255
inet6 fe80::ed8a:d999:984f:1382 prefixlen 64 scopeid 0x20<link>
ether 00:0c:29:54:37:54 txqueuelen 1000 (Ethernet)
RX packets 141574 bytes 28006414 (26.7 MiB)
RX errors 0 dropped 0 overruns 0 frame 0
TX packets 55907 bytes 25972855 (24.7 MiB)
TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0
lo: flags=73<UP,LOOPBACK,RUNNING> mtu 65536
inet 127.0.0.1 netmask 255.0.0.0
inet6 ::1 prefixlen 128 scopeid 0x10<host>
loop txqueuelen 1000 (Local Loopback)
RX packets 69 bytes 5949 (5.8 KiB)
RX errors 0 dropped 0 overruns 0 frame 0
TX packets 69 bytes 5949 (5.8 KiB)
TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0
1.4. tcpdump コマンドの実行に必要な権限
tcpdump コマンドを実行するには root 権限が必要です。root ユーザーにスイッチするか sudo コマンドをつけて tcpdump コマンドを実行しましょう。
2. 基本操作
2.1. パケットキャプチャの開始
-i オプションでパケットをキャプチャするインターフェースを指定します。下記の例では ens33 を指定していますが、お使いの環境に合わせて指定してください。
# tcpdump -i ens33
tcpdump: verbose output suppressed, use -v or -vv for full protocol decode
listening on ens33, link-type EN10MB (Ethernet), capture size 262144 bytes
00:06:57.429918 IP sent7dns.ssh > 192.168.47.1.56359: Flags [P.], seq 100393141:100393337, ack 2862901129, win 251, length 196
00:06:57.429987 IP 192.168.47.1.56359 > sent7dns.ssh: Flags [.], ack 196, win 4100, length 0
00:06:57.430349 IP sent7dns.53867 > dns.google.domain: 32628+ PTR? 1.47.168.192.in-addr.arpa. (43)
00:06:57.434441 IP dns.google.domain > sent7dns.53867: 32628 NXDomain 0/0/0 (43)
<以下、略>
2.2. パケットキャプチャの停止
通信を絞っていないので、大量のパケットがキャプチャされると思います。止めるときは Ctrl キー + C キーを押してください。
3. tcpdump コマンドのプションを理解する
tcpdump コマンドの主なオプションは下記になります。
No | オプション | 説明 |
---|---|---|
1 | -i | パケットキャプチャをするネットワークインターフェースを指定。ネットワークインターフェース は ifconfig コマンドなどで確認できます。any を指定するとすべてのネットワークインターフェースが対象となります。 例)-i eth0 、-i any |
2 | -p | プロミスキャスモードにしない。 ※プロミスキャスモードとは自分宛ではないパケットもキャプチャするモードのこと。 |
3 | -c | キャプチャするパケット数を指定します。指定した数のパケットをキャプチャしたら、パケットキャプチャを停止します。※小文字です 例) -c 1000 |
4 | -w | ログをファイルに書き込みます。書き込んだログはWiresharkで読み込むことができます。※小文字です 例)-w /tmp/tcdump.pcap |
5 | -s | ログをファイルに書き込む際の1パケットの大きさです。ファイルのサイズではありません。大抵の場合は 最大サイズを指定しておけば問題ありません。0 を指定すると最大サイズとなります。※小文字です 例) -s 0 |
6 | -C | ログファイルの最大サイズをメガバイト単位で指定します。指定したサイズに到達したらログのローテーションが行われます。※大文字です 例) -C 100 |
7 | -G | 指定した時間パケットキャプチャを実施します。単位は秒です。1時間取得したい場合は 3600秒のように指定します。 例) -G 3600 |
8 | -W | ローテーションするファイルの数を指定します。サイズ指定の場合と時間指定の場合で動作が異なります。詳しくは実行例を参照ください。※大文字です 例) -W 3 |
No | 項目 | 説明 |
---|---|---|
1 | 送信元IP | パケットの送信元IPアドレスでフィルタします。 例)src host 192.168.10.10 |
2 | 宛先IP | パケットの宛先IPアドレスでフィルタします。 例)dst host 192.168.10.10 |
3 | 宛先ポート番号 | パケットを受信するポート番号でフィルタします。 例)dst port 22 |
4 | 送信元ポート番号 | パケット送信元のポート番号でフィルタします。 例)src port 3720 |
5 | プロトコル | icmp、tcp、udp のうちどれかを指定可能です。 |
4. tcpdump コマンドの実行例
4.1. 送信元IPでフィルタする
送信元IPでフィルタをするには src host <IPアドレス> のように指定します。
実行例
# tcpdump -i ens33 src host 192.168.47.1
tcpdump: verbose output suppressed, use -v or -vv for full protocol decode
listening on ens33, link-type EN10MB (Ethernet), capture size 262144 bytes
23:46:28.058522 IP 192.168.47.1.59500 > sent7dns.ssh: Flags [.], ack 2878916557, win 4097, length 0
23:46:28.116391 IP 192.168.47.1.59500 > sent7dns.ssh: Flags [.], ack 149, win 4096, length 0
23:46:28.163733 IP 192.168.47.1.59500 > sent7dns.ssh: Flags [.], ack 281, win 4096, length 0
23:46:28.210974 IP 192.168.47.1.59500 > sent7dns.ssh: Flags [.], ack 413, win 4095, length 0
23:46:28.259307 IP 192.168.47.1.59500 > sent7dns.ssh: Flags [.], ack 545, win 4095, length 0
<以下、略>
4.2. 宛先ポート番号でフィルタする
宛先のポート番号でフィルタする場合は dst port <ポート番号> のように指定します。
実行例
# tcpdump -i ens33 dst port 22
tcpdump: verbose output suppressed, use -v or -vv for full protocol decode
listening on ens33, link-type EN10MB (Ethernet), capture size 262144 bytes
23:51:47.589282 IP 192.168.47.1.59500 > sent7dns.ssh: Flags [.], ack 2878923225, win 4095, length 0
23:51:47.653086 IP 192.168.47.1.59500 > sent7dns.ssh: Flags [.], ack 149, win 4094, length 0
23:51:47.700118 IP 192.168.47.1.59500 > sent7dns.ssh: Flags [.], ack 281, win 4100, length 0
<以下、略>
4.3. 送信元IPと宛先ポート番号でフィルタする
複数の条件を指定する場合は and でつなぎます。下記の例では送信元IPアドレスが 192.168.47.1 で、かつ、宛先ポート番号が 22 の通信でフィルタしています。
実行例
# tcpdump -i ens33 src host 192.168.47.1 and dst port 22
tcpdump: verbose output suppressed, use -v or -vv for full protocol decode
listening on ens33, link-type EN10MB (Ethernet), capture size 262144 bytes
23:53:03.727418 IP 192.168.47.1.59500 > sent7dns.ssh: Flags [.], ack 2878927657, win 4096, length 0
23:53:03.790521 IP 192.168.47.1.59500 > sent7dns.ssh: Flags [.], ack 149, win 4096, length 0
23:53:03.839008 IP 192.168.47.1.59500 > sent7dns.ssh: Flags [.], ack 281, win 4095, length 0
<以下、略>
4.4. 通信プロトコルでフィルタする
通信プロトコルは icmp、tcp、udp を指定することができます。下記は送信元が 192.168.47.1、プロトコルを icmp に絞った例です。
実行例 1
# tcpdump -i ens33 src host 192.168.47.1 and icmp
tcpdump: verbose output suppressed, use -v or -vv for full protocol decode
listening on ens33, link-type EN10MB (Ethernet), capture size 262144 bytes
14:01:28.494387 IP 192.168.47.1 > sent7dns: ICMP echo request, id 1, seq 35763, length 40
14:01:29.506317 IP 192.168.47.1 > sent7dns: ICMP echo request, id 1, seq 35764, length 40
14:01:30.521014 IP 192.168.47.1 > sent7dns: ICMP echo request, id 1, seq 35765, length 40
<以下、略>
ping は icmp を使ったプログラムです。icmp にはポート番号という概念がありません。
※参考: ping にポート番号はありません
下記は送信元が 192.168.47.1、プロトコルを udp に絞った例です。
実行例 2
# tcpdump -i ens33 src host 192.168.47.1 and udp
tcpdump: verbose output suppressed, use -v or -vv for full protocol decode
listening on ens33, link-type EN10MB (Ethernet), capture size 262144 bytes
14:13:12.450176 IP 192.168.47.1.60279 > 192.168.47.255.52217: UDP, length 32
14:13:12.450204 IP 192.168.47.1.60279 > 192.168.47.255.52217: UDP, length 32
14:13:40.027506 IP 192.168.47.1.57542 > 239.255.255.250.ssdp: UDP, length 175
14:13:41.038226 IP 192.168.47.1.57542 > 239.255.255.250.ssdp: UDP, length 175
14:13:42.034592 IP 192.168.47.1.57542 > 239.255.255.250.ssdp: UDP, length 175
14:13:43.047038 IP 192.168.47.1.57542 > 239.255.255.250.ssdp: UDP, length 175
<以下、略>
4.5. ログファイルに書き込む
Wiresharkで解析したい場合はログファイルに書き込みます。ログファイルのパスは -w オプションの後に指定します。下記の例では送信元IPと宛先ポートで絞ったパケットキャプチャを /tmp/tcpdump.pcap に書き込んでいます。
※ログファイルに書き込む際はオプション -s 0 を指定し、1パケットの最大サイズを無制限にしておくことをおすすめします。
実行例
# tcpdump -i ens33 src host 192.168.47.1 and dst port 22 -s 0 -w /tmp/tcpdump.pcap
tcpdump: listening on ens33, link-type EN10MB (Ethernet), capture size 262144 bytes
4.6. 指定した時間が経過したらログを上書きする
-G オプションを指定することで指定した時間パケットキャプチャを取得したらログを上書きすることができます。※時間が経過したらログファイルの中身はすべてクリアされます。
実行例
# tcpdump -i ens33 src host 192.168.47.1 and dst port 22 -s 0 -w /tmp/tcpdump.pcap -G 60
tcpdump: listening on ens33, link-type EN10MB (Ethernet), capture size 262144 bytes
この時のファイルサイズを観察すると1分経過後、ファイルサイズが0になっているのがわかります。
$ ls -l tcpdump.pcap
$
-rw-r--r--. 1 tcpdump tcpdump 4096 Nov 5 10:31 tcpdump.pcap
$ ls -l tcpdump.pcap
-rw-r--r--. 1 tcpdump tcpdump 16384 Nov 5 10:31 tcpdump.pcap
$
$ ls -l tcpdump.pcap
-rw-r--r--. 1 tcpdump tcpdump 0 Nov 5 10:32 tcpdump.pcap
$
$ ls -l tcpdump.pcap
-rw-r--r--. 1 tcpdump tcpdump 1254 Nov 5 10:32 tcpdump.pcap
4.7. 指定した時間が経過したらログを停止する (単一ファイル)
-w オプションでローテーション回数を指定できますが、1を指定することで時間が経過したらローテーションせずに、ログの出力を停止することができます。
下記の例では60秒経過したらパケットのキャプチャが停止します。
実行例
# tcpdump -i ens33 src host 192.168.47.1 and dst port 22 -s 0 -w /tmp/tcpdump.pcap -G 60 -W1
tcpdump: listening on ens33, link-type EN10MB (Ethernet), capture size 262144 bytes
Maximum file limit reached: 1
252 packets captured
252 packets received by filter
0 packets dropped by kernel
cron に登録することで任意の時刻から任意の時間だけパケットをキャプチャすることができます。
4.8. 指定した時間が経過したらキャプチャを停止する (複数ファイル)
-W (大文字) オプションでローテーション回数を2以上に指定することで、指定した時間毎にファイルを分割できます。ファイルが大きいとコピーやファイルの読み込みなどの処理をしずらくなるので、分割することをおすすめします。
ファイル名に -%F-% などの時刻フォーマットを指定しないと同じファイルに上書きしてしまいますのでご注意ください。
下記の例では60秒間隔でローテーションを実施し、3ファイルできたらキャプチャを停止します。つまり3分間パケットをキャプチャします。
実行例
# tcpdump -i ens33 src host 192.168.47.1 and dst port 22 -s 0 -w /tmp/tcpdump_%F-%T.pcap -G 60 -W3
tcpdump: listening on ens33, link-type EN10MB (Ethernet), capture size 262144 bytes
Maximum file limit reached: 3
513 packets captured
513 packets received by filter
0 packets dropped by kernel
ログファイルは下記のようになります。
# ls -la tcpdump*
-rw-r--r--. 1 tcpdump tcpdump 9708 Nov 5 11:16 tcpdump_2022-11-05-11:15:06.pcap
-rw-r--r--. 1 tcpdump tcpdump 34244 Nov 5 11:17 tcpdump_2022-11-05-11:16:06.pcap
-rw-r--r--. 1 tcpdump tcpdump 4508 Nov 5 11:18 tcpdump_2022-11-05-11:17:09.pcap
4.9. ログが指定したサイズに達したしたらローテションする
ファイルサイズを指定する -C (大文字) オプションとファイル数を指定する -W オプションの組み合わせで、ログファイルのローテーションをすることができます。ファイル数が指定したサイズに到達すると新しいログファイルが作成されます。最後のログファイルがサイズの上限に到達すると最初のファイルにログを上書きしていきます。
時間指定の場合とはことなり指定したファイル数に到達してもログの記録は停止されず、循環的に上書きされます。
実行例
# tcpdump -i ens33 src host 192.168.47.1 and dst port 22 -s 0 -w /tmp/tcpdump.pcap -C1 -W3
tcpdump: listening on ens33, link-type EN10MB (Ethernet), capture size 262144 bytes
上記を実行すると下記のような動きになります。
① 実行すると番号が不可されたファイルが作成されます。
#ls -l tcpdump*
-rw-r--r--. 1 tcpdump tcpdump 522K Nov 5 11:57 tcpdump.pcap0
② ファイルサイズが上限に達すると新しいファイルが作成されます。
#ls -l tcpdump*
-rw-r--r--. 1 tcpdump tcpdump 977K Nov 5 11:58 tcpdump.pcap0
-rw-r--r--. 1 tcpdump tcpdump 977K Nov 5 11:59 tcpdump.pcap1
-rw-r--r--. 1 tcpdump tcpdump 632K Nov 5 12:00 tcpdump.pcap2
③ 指定したファイル数に到達すると最初のファイルに上書きされます。
下記の例では tcpdump.pcap0 のサイズが小さくなっているのがわかります。
#ls -l tcpdump*
-rw-r--r--. 1 tcpdump tcpdump 80K Nov 5 12:01 tcpdump.pcap0
-rw-r--r--. 1 tcpdump tcpdump 977K Nov 5 11:59 tcpdump.pcap1
-rw-r--r--. 1 tcpdump tcpdump 977K Nov 5 12:01 tcpdump.pcap2
以上。
コメント