Satoshi Tajima

下の図は、とあるサーバのネットワークトラフィックのモニタリングのグラフです。
具体的な数値はマスクしてありますが、数週間かけてじわじわとトラフィック量が増加しています。
今回はtsharkを用いてこの通信の内容を調査し、トラフィック量増加の原因を特定した話です。

traffic.png

tsharkとは

tsharkは、おそらくこの記事を読んでいる多くの方がご存知であろう、WiresharkのCUI版のツールです。 RHEL系のOSであれば、wiresharkのパッケージをインストールすることで利用可能になります。
今回の記事の内容は、wireshark-1.8.10-17.el6.x86_64 からインストールされる、TShark 1.8.10 を利用して作成しています。

CUIベースでのパケットキャプチャツールとしては、tcpdumpがとても有名なツールだと思います。
パケットをキャプチャし通信の内容を表示することができるという観点では同じようなツールなのですが、tsharkは通信の内容をHuman-Readableにデコードしたり、一定期間の通信を集計をして統計情報を表示できたりと、便利な機能が多く実装されています。

tsharkの基本的な使い方は、manを見るか、既に多くまとめられている他のサイトを見ることをおすすめします。

調査

tsharkの便利な機能の1つに、-z オプションを使った統計情報の表示があります。
今回はその -z オプションで表示できる統計情報をいくつか用いて調査を行います。

まずは手始めに、この通信のTCPとUDPの割合を確認してみます。
※尚、入力したコマンドや出力の内容は、IPアドレスや各種数値等、便宜的に手で書き換えている部分があります。

$ tshark -a duration:60 -f 'dst host 172.17.XXX.XXX' -q -z io,stat,10,tcp,udp
Capturing on eth0
16 packets dropped
2666 packets captured

===================================================================
| IO Statistics                                                   |
|                                                                 |
| Interval size: 10 secs                                          |
| Col 1: Frames and bytes                                         |
|     2: tcp                                                      |
|     3: udp                                                      |
|-----------------------------------------------------------------|
|          |1                 |2                 |3               |
| Interval | Frames |  Bytes  | Frames |  Bytes  | Frames | Bytes |
|-----------------------------------------------------------------|
|  0 <> 10 |    164 |   41351 |    162 |   40863 |      2 |   488 |
| 10 <> 20 |   1177 | 6283124 |   1165 | 6280295 |     12 |  2829 |
| 20 <> 30 |    871 | 4516942 |    863 | 4514656 |      8 |  2286 |
| 30 <> 40 |    204 |   43122 |    200 |   42138 |      4 |   984 |
| 40 <> 50 |    137 |   21731 |    135 |   21462 |      2 |   269 |
| 50 <> 58 |    113 |   28049 |    110 |   27351 |      2 |   638 |
===================================================================

コマンドのオプションを解説します。

  • -a duration:60: tsharkの停止条件を指定しています。duration:6060秒後に停止 を意味しています。
  • -f 'dst host 172.17.XXX.XXX': キャプチャするパケットのフィルタを記載します。inboundのトラフィックについて調査したいので自ホストが送信先になっているパケットを対象とします。
  • -q: キャプチャしたパケットを、1件ずつ出力するのをやめます。今回は統計情報だけ見れればよいので有効にしておきます。
  • -z io,stat,10,tcp,udp: -z は統計情報を出力するためのオプションです。 io,stat,interval[,filter][,filter][,filter]...interval の間隔の間に、filter にマッチする通信がどれくらいの パケット数/Byte数 だったかを集計してくれるオプションです。 tcp, udp は見て分かる通りそれぞれ TCPの通信とUDPの通信を表しています。

出力の内容はそれほど難しくないと思います。表中の 2 がTCPでの通信、3 がUDPでの通信を表しています。1 はキャプチャしたパケット全体の量です。

この結果から、通信の大半はTCPだということがわかりました。ではこのTCPの通信は、どこのホストとのどんな通信でしょうか。それは次のコマンドで確認します。

$ tshark -n -a duration:60 -f 'dst host 172.17.XXX.XXX' -q -z conv,tcp
Capturing on eth0
47 packets dropped
1623 packets captured
================================================================================
TCP Conversations
Filter:<No Filter>
                                               |       <-      | |       ->      | |     Total     |   Rel. Start   |   Duration   |
                                               | Frames  Bytes | | Frames  Bytes | | Frames  Bytes |                |              |
172.17.X.XX:47688    <-> 52.XXX.XX.XX:80          713   5288887       0         0     713   5288887     8.323630499        10.5606
172.17.X.XX:47760    <-> 52.XXX.XX.XX:80          425   3349593       0         0     425   3349593    13.359284739         6.5439
172.17.X.XX:47814    <-> 50.XX.XXX.XX:443          12      7029       0         0      12      7029    11.545835487         0.7044
172.17.X.XX:44320    <-> 50.XX.XXX.XXX:443         12      7018       0         0      12      7018    11.061043611         0.7214
.. snip ..
172.17.X.XX:38302    <-> 210.XXX.XX.XXX:443         4       279       0         0       4       279     2.884381083         0.0025
172.17.X.XX:39084    <-> 54.XXX.XXX.XXX:443         2       167       0         0       2       167    17.913879040         0.0001
210.XXX.XX.XXX:59861 <-> 172.17.X.XX:22             0         0       2       132       2       132     2.435391340        10.0354
210.XXX.XX.XXX:14136 <-> 172.17.X.XX:22             0         0       1       106       1       106    19.941849383         0.0000
================================================================================

今回新たに使ったコマンドのオプションを解説します。

  • -n: ホスト名やポート名の名前解決を無効にします。
  • -z conv,tcp: ホストとTCPのポートのペア毎に、通信のパケット数/Byte数を出力します。

あるホストのTCP80番ポートに対するリクエストの応答が、通信の大半を占めていることがわかりました。次のコマンドで、このhttpの通信の内容を統計的に見てみます。

$ tshark -a duration:60 -q -z http_req,tree
Capturing on eth0
304 packets dropped
1795 packets captured

===================================================================
HTTP/Requests                                                  value             rate          percent
-------------------------------------------------------------------
HTTP Requests by HTTP Host                                         58       0.006287
  169.254.169.254                                                   38       0.004119          65.52%
   /latest/meta-data/iam/security-credentials/                       19       0.002059          50.00%
   /latest/meta-data/iam/security-credentials/XXX                    19       0.002059          50.00%
  XXX.s3.amazonaws.com                                              18       0.001951          31.03%
   /?prefix=XXXX                                                      1       0.000108           5.56%
   /?marker=XXXX&prefix=XXX/                                          1       0.000108           5.56%
   .. snip ..
   /?marker=XXXX&prefix=XXX/                                          1       0.000108           5.56%
   /XXX                                                               1       0.000108           5.56%
  .. snip ..
===================================================================

今回新たに使ったコマンドのオプションを解説します。

  • -z http_req,tree: キャプチャしたパケットのうち、HTTPの通信を集計して、ホストとパス毎にグルーピングして統計情報を表示します。

Amazon S3との通信であることがわかりました。このあたりまでわかれば、あとはどの処理が通信を行っているのか心当たりがつくのではないでしょうか。初見の環境などで、まったく検討もつかない場合はssコマンドやnetstatコマンドを組み合わせてプロセスを特定しましょう。

今回のケースではあるS3バケットに対して定期的な s3 sync を行っているのですが、そのS3バケットのオブジェクト数が徐々に増えていたため、その増加に応じてファイルリスト取得時の通信量も増えていたということがわかりました。(S3との通信がhttpになってしまっているのは意図していなかったのでそれは後日修正しました….)

まとめ

以前はこのような調査を

  1. tcpdumpでpcapファイルを作成
  2. GUI環境に転送してWiresharkで確認

といったステップで行っていたのですが、tstarkを使うことでより簡単に実施することができるようになりました。

実際には今回のようにきれいに原因を特定できず、もう少し泥臭い調査をしなければ行けないケースもあるかと思いますが、-z のオプションには他にもたくさんの種類があるので、調査したい内容に合わせてより都合のいいものを選ぶとよいと思います。

以上、tsharkを用いたネットワークトラフィックの内訳の調査でした。