March 24, 2011

tshark (WiresharkのCLI版) の使い方






tsharkWiresharkのCLI(コマンドライン)版と言えるもので、GUIのないサーバ上やターミナルからtcpdumpと同じ利便性で使える、パケットキャプチャです。tsharkによるSummaryもWiresharkど同等の内容で確認できるので、tcpdumpよりtsharkの方が好まれる人も多いのでは。

GUIではWiresharkが最もメジャーなパケットキャプチャで、使用されている方も多いかと思います。かたやCLIではtcpdumpを使う方が多いのではないでしょうか。この場合、tcpdumpの代わりにtsharkを使うとCLIでもWiresharkと同様の確認が行えるのでよいかもしれせん。

tsharkはWiresharkのパッケージに含まれて提供されていますので、Wiresharkがインストール済みであれば既に実行可能かと思います。
WindowsやLinuxでは下記Pathにあると思います。
Windows: C:\Program Files\Wireshark\tshark.exe
Linux: /usr/bin/tshark

もし無ければ、Linuxであれば個別にインストールも可能です。サーバ向けにインストールを行なっている環境だと、個別インストールが必要かと思います。Ubuntuであれば下記のように。
$ sudo apt-get install tshark



Windowsであれば基本的にWiresharkを使える環境にありますので、これ以降の使い方についてはLinux(Ubuntu)ベースにしています。
また、tsharkの使い方はWindowsのコマンドプロンプトで使う場合にも基本的には同じです。tsharkのバージョンは1.2.7を想定しています。

後述する -z を工夫してLinuxシェル上で扱うことで、ケースによっては非常に強力なツールになるかもしれません。


tsharkはroot権限で実行しなければならない



パケットキャプチャを行うときには、該当インターフェースをプロミスキャスモードで動作させなければなりません。それにはroot権限が必要になるので注意しましょう。

非root権限で実行すると以下のようなエラーになります。以降の -D オプションもききません。
$ tshark
tshark: There are no interfaces on which a capture can be done



tsharkでインターフェースの指定



-D オプションで使用可能なインターフェースとそのIndexを確認することが出来ます。まずはこれを実行しましょう。

$ sudo tshark -D
1. eth0
2. any (Pseudo-device that captures on all interfaces)
3. lo


-i オプションでパケットキャプチャを行うインターフェースを指定します。指定しなければ一番Indexの若いインターフェースになります。下記の例では全てeth0インターフェースでキャプチャを開始します。

$ sudo tshark
$ sudo tshark -i 1
$ sudo tshark -i eth0



-f オプションでキャプチャフィルタの指定が出来ます。tcpdumpやWiresharkと同じくlibpcapフォーマットのフィルタ構文を使用します。クォーテーションでくくって指定してください。詳しいフィルタの構文についてはググってください。

$ sudo tshark -i eth0 -f 'port 80 and host 10.0.0.1'


なお、-R オプションはディプレイフィルタなので、標準出力に対してのフィルタオプションです。キャプチャファイルを保存しない一時的な実行であれば、標準出力への出力内容は同じなります。-f オプションの方がマッチしないパケットをバッファリングしない分、システムに優しい気もしますが。


tsharkでキャプチャファイルの保存と読み込み



-w で指定したPATHにキャプチャファイルを保存します。-r で指定して読み込むことが出来ます。また、Wiresharkで直接読み込むことができますので、サーバ上でtsharkで保存したファイルを、共有ディレクトリを通じてクライアントPCのWiresharkで確認する方法をよくとります。

$ sudo tshark -i eth0 -f 'port 80' -w /mnt/share/test.cap



tsharkで詳細表示



-V を追加で指定すると、Wiresharkで見慣れた内容が各パケットエントリーごとで確認できます。ただ、内容量が多いのでパケット数が少ない場合に限られると思います。

$ sudo tshark -i eth0 -f 'icmp' -V



tsharkで名前解決を無効にする



IPアドレスやPort番号を、FQDNやサービス名に変換表示させたくない場合もあるかと思います。その時には -n オプションを付与しましょう。
$ sudo tshark -i eth0 -n



-z オプション



-z をキーに、tsharkの動作を強力にカスタマイズ出来ます。-z に続けて様々なオプションでそれらを指定します。


-z オプションでInfo Columnのカスタマイズ



man tsharkより抜粋
-z proto,colinfo,filter,field

Append all field values for the packet to the Info column of the one-line summary output. This feature can be used to append arbitrary fields to the Info column in addition to the normal content of that column. field is the display-filter name of a field which value should be placed in the Info column. filter is a filter string that controls for which packets the field value will be presented in the info column. field will only be presented in the Info column for the packets which match filter.

NOTE: In order for TShark to be able to extract the field value from the packet, field MUST be part of the filter string. If not, TShark will not be able to extract its value.


Info Columnとは、tshark実行時に標準出力に出力される、各パケット毎のSummary情報部分です。この出力内容をカスタマイズすることが出来ます。
注意すべき点は、この場合の -z オプションはディプレイフィルタではないので、このfilterにマッチしなくてもInfo columnに表示しないだけです。マッチするものだけを表示させたい場合は、-R オプションでのディスプレイフィルタを併用する必要があります。
下記にいくつか例を挙げます。

# TCP Window SizeをInfo Columnに追加表示します。
$ sudo tshark \
-z "proto,colinfo,tcp.window_size,tcp.window.size" \
-r test.cap

107 0.375142 124.83.141.28 -> 10.0.0.2 TCP http > 52571 [ACK] Seq=387 Ack=1155 Win=65535 Len=0 tcp.window_size == 65535


-z オプションは複数指定して、Info Column上で連結することが出来ます。この例ではディスプレイフィルタでHTTP Request Methodが含まれているものだけをフィルタしています。
$ sudo tshark \
-z "proto,colinfo,http.request.uri,http.request.uri" \
-z "proto,colinfo,tcp.window_size,tcp.window_size" \
-r http.cap -R "http.request.method"

79 1.693395 10.0.0.2 -> 124.83.183.212 HTTP GET /oi?t=j&s=ytop_ams_rmdl_utf8&i=toppage HTTP/1.1 tcp.window_size == 65536 http.request.uri == "/oi?t=j&s=ytop_ams_rmdl_utf8&i=toppage"


-R オプションも利用して"http.content_type"の指定があるレスポンスを抽出し、"http.content_encoding"をInfo Columnに表示します。
$ sudo tshark \
-z "proto,colinfo,http.content_encoding,http.content_encoding" \
-R "http.content_type" \
-r http.cap

51 0.113339 124.83.235.204 -> 10.130.141.230 HTTP HTTP/1.1 200 OK (text/html) http.content_encoding == "gzip"
66 0.166352 118.151.253.60 -> 10.130.141.230 HTTP HTTP/1.1 200 OK (JPEG JFIF image)
78 0.180127 202.93.69.243 -> 10.130.141.230 HTTP HTTP/1.1 200 OK (JPEG JFIF image)
89 0.201872 124.83.223.251 -> 10.130.141.230 HTTP HTTP/1.1 200 OK (GIF89a)
93 0.227038 114.111.103.164 -> 10.130.141.230 HTTP HTTP/1.1 200 OK (application/x-javascript) http.content_encoding == "gzip"
104 0.356011 124.83.141.28 -> 10.130.141.230 HTTP HTTP/1.0 200 OK (GIF89a)


例えば、DNSのCNAMEレコードが返ってきた数を計測します。
$ sudo tshark \
-z "proto,colinfo,dns.resp.type,dns.resp.type" \
-r dns.cap | egrep CNAME | wc -l

2



-z オプションでプロトコル統計をとる



man tsharkより抜粋
-z io,phs[,filter]

Create Protocol Hierarchy Statistics listing both number of packets and bytes. If no filter is specified the statistics will be calculated for all packets. If a filters is specified statistics will be only calculated for those packets that match the filter.

This option can be used multiple times on the command line.


単純に以下のように実行してみてください。Ctrl+Cで終了させるとプロトコル種別ごとの統計が取れます。
$ sudo tshark -i any -z io,phs
(省略)
=====================================
Protocol Hierarchy Statistics
Filter: frame

frame frames:29 bytes:4624
sll frames:29 bytes:4624
ip frames:18 bytes:3960
tcp frames:18 bytes:3960
ssh frames:10 bytes:3464
arp frames:11 bytes:664
=====================================



-z オプションでトラフィック統計をとる



man tsharkより抜粋
-z io,stat,interval[,filter][,filter][,filter]...

Collect packet/bytes statistics for the capture in intervals of interval seconds. Intervals can be specified either as whole or fractional seconds. Interval can be specified in ms resolution. If Interval is 0, the statistics will be calculated over all packets.

If no filter is specified the statistics will be calculated for all packets. If one or more filters are specified statistics will be calculated for all filters and presented with one column of statistics for each filter.

This option can be used multiple times on the command line.


これも単純に実行してCtrl+Cで終了することで、その効果を確認することが出来ます。intervalごとのトラフィック統計を取れます。
$ sudo tshark -i any -z io,stat,1
(省略)
=================================
IO Statistics
Interval: 1.000 secs
Column #0:
| Column #0
Time |frames| bytes
000.000-001.000 2 124
001.000-002.000 2 346
002.000-003.000 4 788
003.000-004.000 7 860
004.000-005.000 2 618
005.000-006.000 2 346
006.000-007.000 3 408
007.000-008.000 4 742
008.000-009.000 4 566
009.000-010.000 5 76
=================================



まとめ



基本的な使い方はほぼtcpdumpと同じで、実際は同じpcapライブラリを使用しているので、内部的にも同じように動作する部分が多いです。Wiresharkの仕様にあわせてサーバ上でのパケットキャプチャを取得したい場合は、tcpdumpよりtsharkを使用する方がベターかもしれません。

特に、 -R オプションや -z オプションを使用することで、tsharkは強力にあなたをサポートできるでしょう。

他にもいくつかWiresharkに組み込まれている技術をtsharkでも利用できますので、興味があればman tsharkなどから勉強すると良いと思います。