PCを使ううえでインターネットをはじめとするネットワーク機能は欠かせません。ネットワーク上ではさまざまなプロトコルやサービスに応じたパケットやフレームを機器間でやりとりしています。そこで今回はそんなネットワークのトラフィックの中身を見るために定番の、
Ubuntuなら常にインストールされているtcpdump
「tcpdump」
とりあえず実際に実行してみましょう。
$ sudo tcpdump -c 10
おそらくいろんなホストとの通信メッセージが表示されるはずです。
出力の先頭フィールドは時刻です。その後ろについては、
01:41:00.281097 ARP, Request who-has 192.168.10.3 tell 192.168.10.10, length 28
01:41:00.312383 ARP, Reply 192.168.10.3 is-at b8:27:eb:12:30:70, length 460
上記だと192.
IPパケットであれば
01:39:00.666424 IP 192.168.10.4.ssh > 192.168.10.10.54012:
Flags [P.], seq 692251127:692251519, ack 2792381807, win 1810,
options [nop,nop,TS val 932541213 ecr 44643234], length 392
01:39:00.666458 IP 192.168.10.10.54012 > 192.168.10.4.ssh:
Flags [.], ack 392, win 1436,
options [nop,nop,TS val 44643486 ecr 932541213], length 0
上記は192.
フィルタリング機能
tcpdumpは特にオプションを指定していない場合、
「-i」
$ sudo tcpdump -i eth0
「-P」
$ sudo tcpdump -P in
なおこの
オプションでは基本的なルールしか設定できませんが、
特定のホストに関連するパケットだけを表示したい場合はhostフィルタを使用します。また、
ホスト名emaの通信だけを表示 $ sudo tcpdump host ema ホスト名emaと、miiもしくはriiとの通信を表示 $ sudo tcpdump host ema and \( mii or rii \) ホスト名emaの通信のうち、taroに関連するものだけを除外 $ sudo tcpdump host ema and not taro IPアドレスでの指定も可能 $ sudo tcpdump host 192.168.0.1
特定のポートの通信だけを表示する場合は、
zukaホストでポート番号5060に関連する通信だけを表示 $ sudo tcpdump host zuka and port 5060 「ftpもしくはftp-dataのポート」が宛先になっている通信だけ表示 $ sudo tcpdump dst port ftp or ftp-data sshポートの通信のうちTCPパケットのみ表示 $ sudo tcpdump tcp port ssh oiホストから送られるIPv4のブロードキャストパケットのみ表示 $ sudo tcpdump ip broadcast and src host oi
その他にもいろいろなルールを指定できます。詳しいことはpcap-filterのマニュアルを参照してください。
出力のカスタマイズ
tcpdumpは特に指定しなければ、
しかし実際にtcpdumpを使用する場合は、
「-x」
下記は80番ポートの通信を監視しつつ、
$ sudo tcpdump -i wlan0 -X -c 5 port 80 tcpdump: verbose output suppressed, use -v or -vv for full protocol decode listening on wlan0, link-type EN10MB (Ethernet), capture size 262144 bytes 02:20:26.638452 IP 192.168.10.10.59296 > gihyo.jp.http: Flags [S], ... 02:20:26.658487 IP gihyo.jp.http > 192.168.10.10.59296: Flags [S.], ... 02:20:26.658544 IP 192.168.10.10.59296 > gihyo.jp.http: Flags [.], ... 02:20:26.658697 IP 192.168.10.10.59296 > gihyo.jp.http: Flags [P.], 0x0000: 4500 0299 f66d 4000 4006 22ac c0a8 0a0a E....m@.@."..... 0x0010: 31d4 22bf e7a0 0050 a593 4639 fb5c 6ec2 1."....P..F9.\n. 0x0020: 8018 00e5 5959 0000 0101 080a 02b2 b058 ....YY.........X 0x0030: 1c35 4b9b 4745 5420 2f20 4854 5450 2f31 .5K.GET./.HTTP/1 0x0040: 2e31 0d0a 486f 7374 3a20 6769 6879 6f2e .1..Host:.gihyo. 0x0050: 6a70 0d0a 5573 6572 2d41 6765 6e74 3a20 jp..User-Agent:. 0x0060: 4d6f 7a69 6c6c 612f 352e 3020 2858 3131 Mozilla/5.0.(X11 0x0070: 3b20 5562 756e 7475 3b20 4c69 6e75 7820 ;.Ubuntu;.Linux. 0x0080: 7838 365f 3634 3b20 7276 3a33 362e 3029 x86_64;.rv:36.0)
他にも
「-e」
ファイルへの保存とファイルからの再生
tcpdumpはネットワークトラフィックの様子をほぼリアルタイムで表示しますが、
そんなときに便利なのが指定したファイルに保存する
$ sudo tcpdump -i eth0 -w yano.pcap
tcpdumpはlibpcap形式のバイナリデータとしてパケットの内容を保存します。
$ sudo tcpdump -r yano.pcap port 80
上記の
ちなみにUbuntuの場合、
pcapファイルが大きくなりすぎないように、
tcpdumpは個々のパケットで65535バイトを超えるデータは切り捨てています。このサイズは
GUIによるアナライザーWireshark
「Wireshark
」

ところでネットワークトラフィックをキャプチャするには管理者権限が必要です。tcpdumpの場合はsudo付きで起動しましたが、
- pkexecを使って管理者権限で起動する
- wiresharkグループに属してdumpcapを利用する
- tcpdumpやdumpcapで出力したpcapファイルを読み込む
1.はWiresharkを管理者権限で起動する方法です。polkitの設定が必要なうえ、
2.はインストール時の質問にYesと答えたときに行われる設定です。インストール時にNoと答えた場合でも、
$ sudo dpkg-reconfigure wireshark-common
wiresharkグループが作成されますので、
$ sudo adduser $USER wireshark
追加後は一度ログインしなおしてください。さらにdumpcapコマンドもインストールしておきます。
$ sudo apt-get install pcaputils
これで一般ユーザーで起動したWiresharkでも、
3.はWiresharkを解析のみに利用し、
WiresharkのCUI版TShark
WiresharkのCUI版が
tsharkのキャプチャ機能はtcpdumpのそれと大した違いはありません。tsharkで便利なのは、
たとえばtsharkでpcapファイルを読み込むと次のように表示されます。
$ tshark -r rinko.pcap
1 0.000000 192.168.10.10 -> 153.121.51.184 TCP 74 60411→80 [SYN] Seq=0 Win=29200 Len=0 MSS=1460 SACK_PERM=1 TSval=47313761 TSecr=0 WS=128
2 0.010867 153.121.51.184 -> 192.168.10.10 TCP 74 80→60411 [SYN, ACK] Seq=0 Ack=1 Win=14480 Len=0 MSS=1414 SACK_PERM=1 TSval=2539409277 TSecr=47313761 WS=64
3 0.010925 192.168.10.10 -> 153.121.51.184 TCP 66 60411→80 [ACK] Seq=1 Ack=1 Win=29312 Len=0 TSval=47313764 TSecr=2539409277
4 0.011019 192.168.10.10 -> 153.121.51.184 HTTP 763 GET / HTTP/1.1
5 0.022089 153.121.51.184 -> 192.168.10.10 TCP 66 80→60411 [ACK] Seq=1 Ack=698 Win=15936 Len=0 TSval=2539409288 TSecr=47313764
このうち4番目のフレームの詳細を表示するには次のようにframe.
$ tshark -r rinko.pcap -V -Y 'frame.number==4' Frame 4: 763 bytes on wire (6104 bits), 763 bytes captured (6104 bits) Encapsulation type: Ethernet (1) ... Hypertext Transfer Protocol GET / HTTP/1.1\r\n [Expert Info (Chat/Sequence): GET / HTTP/1.1\r\n] [GET / HTTP/1.1\r\n] [Severity level: Chat] [Group: Sequence]
パケットデータ部分を表示する場合は、
$ tshark -r rinko.pcap -x -Y 'frame.number==4' 0000 a4 12 42 3e f8 3c 64 80 99 70 2c a4 08 00 45 00 ..B>.<d..p,...E. 0010 02 ed 26 74 40 00 40 06 79 b3 c0 a8 0a 0a 99 79 ..&t@.@.y......y 0020 33 b8 eb fb 00 50 e7 d0 d5 14 a0 7d 80 2f 80 18 3....P.....}./.. 0030 00 e5 ab d5 00 00 01 01 08 0a 02 d1 f3 64 97 5c .............d.\ 0040 4f 7d 47 45 54 20 2f 20 48 54 54 50 2f 31 2e 31 O}GET / HTTP/1.1 0050 0d 0a 48 6f 73 74 3a 20 6d 75 73 61 6e 69 2e 6a ..Host: musani.j 0060 70 0d 0a 55 73 65 72 2d 41 67 65 6e 74 3a 20 4d p..User-Agent: M 0070 6f 7a 69 6c 6c 61 2f 35 2e 30 20 28 58 31 31 3b ozilla/5.0 (X11; 0080 20 55 62 75 6e 74 75 3b 20 4c 69 6e 75 78 20 78 Ubuntu; Linux x 0090 38 36 5f 36 34 3b 20 72 76 3a 33 36 2e 30 29 20 86_64; rv:36.0)
他にもtsharkであれば
プログラミング言語でも
今回紹介したtcpdump/
libpcapを直接使うにはC言語を使う必要がありますが、