Wireshark
ネットワークを流れるパケットを取り込み、プロトコルの階層ごとにフィールドを解読して表示するオープンソースのプロトコルアナライザ(パケット解析ツール)である。取り込んだ後のデータから条件に合うものだけを表示する表示フィルタや、TCPの一連のやり取りを再構成する機能を持つ。
イマシルちゃんの解説
ネットワークの調子が悪いとき、機器の設定を眺めるだけでは原因が分からないことがあるんだ。
そんなときに使うのが、流れるパケットを取り込んで中身を見せてくれるWiresharkというツールだよ。
取り込んだデータはイーサネットやIP、TCPといった層ごとに分解されて、宛先や番号を一つずつ読めるようになるの。
何万個ものパケットから条件に合うものだけを選んだり、一つの会話を最初から最後までつなげて見たりもできるんだ。
「同じデータを何度も送り直している」「応答が返ってこない」といった事実を目で確かめられるから、推測ではなく証拠で原因を絞り込めるんだよ。
この解説はわかりやすかったですか?
より深い解説
位置付けと名前
Wiresharkは、取り込んだパケットの内容を詳しく表示するネットワークパケットアナライザである。障害の切り分け、セキュリティ調査、プロトコルの開発や学習に使われる。Windows・macOS・Linuxなどで動作し、ライセンスはGNU GPL version 2である。
1997年にGerald Combsが「Ethereal」という名前で開発を始め、2006年に現在のWiresharkへ改称した。古い資料にEtherealとあれば同じ系統のツールを指す。経緯と機能の全体像はWireshark User's Guideの第1章にまとめられている。
Wiresharkは通信を受動的に観測するだけで、パケットを書き換えたり送出したりはしない。また侵入検知システム(IDS)でもない。不審な通信を自動で検出して警告する仕組みが必要なら、IDSやIPSを別に用意する。Wiresharkは人が通信を読み、原因を判断するための道具である。
取り込みから表示までの流れ
画面上ではパケットが一覧表示されるだけに見えるが、内部ではいくつかの段階を経ている。
- 取り込み専用のプログラムであるdumpcapが、ネットワークインタフェースに届いたフレームを受け取る。Unix系OSではlibpcap、WindowsではNpcapというキャプチャ用ライブラリを使う。
- キャプチャフィルタを指定していれば、条件に合わないパケットをこの段階で捨てる。
- 取り込んだパケットに受信時刻を付けてファイルへ記録する。保存形式はバージョン1.8からpcapngが既定になり、従来のpcap形式も読み書きできる。
- ディセクタと呼ばれるプロトコルごとの解読処理が、イーサネットのタイプ、IPのプロトコル番号、TCPやUDPのポート番号などを手掛かりに、次に解読すべきプロトコルを決めて順に分解する。
- 表示フィルタで絞り込んだ結果を、パケット一覧・詳細ツリー・バイト列の三つのペインに表示する。
4の手順から分かるとおり、上位のプロトコルは主にポート番号で判定する。標準と異なるポートでHTTPを動かしていると、HTTPとして解読されないことがある。この場合は「Decode As」で解読方法を指定する。pcapng形式の採用はWireshark 1.8.0のリリース告知で確認できる。
どこで取り込むかで見えるものが決まる
Wiresharkで見えるのは、取り込んだインタフェースに実際に届いたパケットだけである。スイッチは宛先MACアドレスを学習したフレームを該当するポートにしか転送しない。そのため調査用PCを空きポートにつないでも、他の端末同士のユニキャスト通信は見えない。
自分宛て以外のフレームもNICに受け取らせるプロミスキャスモードを有効にしても、スイッチが転送してこないフレームは届かない。他の端末の通信を見るには、スイッチのポートミラーリングで対象ポートの通信をコピーするか、回線にネットワークタップを挿入する。あるいは通信する端末やサーバ自身で取り込む。
| 取り込む場所 | 見えるもの | 注意点 |
|---|---|---|
| 通信する端末自身 | その端末が送受信するパケット | 送信側では、オフロード機能のため回線上と異なる大きさや未計算のチェックサムが見えることがある |
| ミラーポート | 指定したポートやVLANのコピー | ミラー先の帯域を超えると取りこぼす。エラーフレームはコピーされないことがある |
| ネットワークタップ | 回線上の信号の複製 | 機器の挿入時に回線が一時的に切れる場合がある |
| 無線LAN | 通常は自分の通信だけ | 他の端末の802.11フレームを見るにはモニターモードと対応するNICが必要になる |
送信ホストでの取り込みに関する注意は特に誤解を招きやすい。チェックサムの計算や大きなデータの分割をNICへ任せるオフロード機能が有効だと、Wiresharkは計算前・分割前のデータを見ることになる。「チェックサムが誤っている」「MTUより大きいパケットが出ている」と表示されても、回線上では正常な場合がある。
無線LANでWPA2などの暗号化を使っている場合、モニターモードで取り込んでも中身は暗号化されたままである。復号するには事前共有鍵などの鍵情報と、その端末の4ウェイハンドシェイクを取り込んでいる必要がある。
二種類のフィルタ
Wiresharkには役割の異なる二種類のフィルタがある。どちらも「絞り込む」機能だが、働く時点と書き方がまったく違う。
| 観点 | キャプチャフィルタ | 表示フィルタ |
|---|---|---|
| 働く時点 | 取り込む前 | 取り込んだ後 |
| 書き方 | libpcapのフィルタ言語(tcpdumpと共通) | Wireshark独自のフィールド名と演算子 |
| 例 | tcp port 443 and host 192.0.2.10 | tcp.port == 443 && ip.addr == 192.0.2.10 |
| 条件に合わないパケット | 記録されず、後から取り戻せない | 表示されないだけで、条件を変えれば再び見える |
キャプチャフィルタは取り込む量とディスクの使用量を減らせるが、絞り込みすぎると原因となるパケットまで捨ててしまう。障害調査では、取り込みは広めにして表示フィルタで絞るのが基本である。構文はキャプチャフィルタの説明のとおりlibpcapの言語で書く。
表示フィルタ(ディスプレイフィルタ)は、詳細ツリーに出るフィールド名をそのまま条件に使える。次はよく使う例である。
ip.addr == 192.0.2.10
tcp.flags.syn == 1 && tcp.flags.ack == 0
dns
http.request
tcp.analysis.retransmission
tcp.window_size == 0 && tcp.flags.reset != 1
!(ip.addr == 192.0.2.10)
ip.addr は送信元と宛先のどちらかに一致すれば真になる。そのため、ある端末を除外したいときは !(ip.addr == 192.0.2.10) のように全体を否定して書く。ip.addr != 192.0.2.10 は版によって解釈が変わってきた書き方であり、意図と違う結果になりやすい。この注意は表示フィルタのWikiでも説明されている。
解析を助ける主な機能
| 機能 | 内容 | 使いどころ |
|---|---|---|
| Follow TCP Stream | 一つのTCPコネクションのデータを順番どおりにつなげて表示する | HTTPやSMTPなど平文のやり取りを会話として読む |
| Expert Information | 再送、重複ACK、ゼロウィンドウなど注意すべき事象を一覧にする | 大量のパケットから異常の候補を探す |
| Conversations/Endpoints | 通信相手の組や端末ごとの量を集計する | 帯域を使っている通信の特定 |
| I/O Graphs | 時間あたりのパケット数やバイト数をグラフにする | 通信量の急増や停止の時刻を調べる |
| 名前解決 | アドレスをホスト名などに置き換えて表示する | 読みやすくなる反面、解決のためにDNS問合せが発生しうる |
TLSで暗号化された通信は、そのままではアプリケーションのデータを読めない。ブラウザなどが出力するセッション鍵のログファイルを読み込ませると、Wiresharkで復号して表示できる。鍵を持たない第三者が通信路で取り込んだだけでは内容を読めないことが、暗号化の意味でもある。
時刻の表示は、取り込み開始からの経過時間のほか、直前に表示したパケットからの差分にも切り替えられる。要求と応答の間隔を測るときは差分表示が便利である。
TCPのやり取りを読む例
次は独自に作った取り込み例である。クライアント192.0.2.10のポート50,000から、サーバ198.51.100.20のTCPポート443へ接続した。Wiresharkは既定でシーケンス番号を相対値で表示するので、最初のSYNのシーケンス番号は0と表示される。
| 時刻(秒) | 向き | 内容 |
|---|---|---|
| 0.000 | クライアント → サーバ | SYN |
| 0.042 | サーバ → クライアント | SYN/ACK |
| 0.043 | クライアント → サーバ | ACK |
| 0.050 | クライアント → サーバ | データ(Seq=1、長さ1,460) |
| 0.350 | クライアント → サーバ | 同じデータ(Seq=1、長さ1,460) |
SYNからSYN/ACKまでの間隔から、クライアントから見た往復遅延(RTT)はおよそ42msと読み取れる。0.350秒の行は同じシーケンス番号のデータを送り直しているので、Wiresharkは再送として印を付ける。最初のデータか、それに対するACKが途中で失われた可能性がある。
RTTが分かると、ウィンドウサイズによる上限も見積もれる。ウィンドウスケールを使わず、受信ウィンドウが65,535バイトのままなら、1往復で送れるのは最大65,535バイトである。
65,535バイト × 8 = 524,280ビット
524,280ビット ÷ 0.042秒 ≒ 12,482,857bit/s ≒ 約12.5Mbit/s
回線が1Gbit/sあっても、この条件では1本のTCPコネクションの約12.5Mbit/sが上限の目安になる。回線速度ではなくウィンドウとRTTが性能を決めていることを、取り込んだ値から説明できる。
パケットの並びからは、次のように原因の候補を絞り込める。
| 観測した状態 | 考えられる原因 |
|---|---|
| SYNを繰り返し送るが応答がない | 経路の途中で破棄されている。宛先へのルーティングやファイアウォールの破棄を疑う |
| SYNの直後にRSTが返る | 宛先ポートで待ち受けていない。または途中の機器が拒否を通知している |
| 再送や重複ACKが多い | 経路上でのパケット損失。回線の品質や輻輳を調べる |
| 受信側がゼロウィンドウを通知する | 受信側のアプリケーションがデータを読み出せていない |
| ARP要求を繰り返し応答がない | 同じセグメントに相手がいない、またはデータリンク層の接続に問題がある |
同じ系統のコマンドラインツール
Wiresharkの配布物には、画面を持たない道具も含まれる。
| ツール | 画面 | 主な用途 |
|---|---|---|
| Wireshark | GUI | 取り込みと対話的な詳細解析 |
| TShark | コマンドライン | Wiresharkと同じ解読処理と表示フィルタを端末上で使う |
| dumpcap | コマンドライン | 取り込みとファイル保存だけを行う |
| tcpdump | コマンドライン | 別プロジェクトのキャプチャツール。libpcapを使い、pcap形式で保存できる |
画面のないサーバではtcpdumpやTSharkで取り込んでファイルに保存し、手元のWiresharkで開いて解析する使い方が多い。ファイル形式が共通なので、取り込む道具と解析する道具を分けられる。
運用上の注意
パケットの取り込みには、通常OSの管理者権限が必要である。Wiresharkは取り込みをdumpcapに任せることで、多数のディセクタを含むGUI本体を管理者権限で動かさずに済むようにしている。
取り込んだデータには、平文のパスワード、個人情報、業務データが含まれうる。組織の許可を得た範囲でだけ取り込み、保存したファイルは機密情報として管理する。必要以上に長く保存しない。
長時間の取り込みでは、ファイルサイズや時間でファイルを切り替えるリングバッファを使う。複数地点で同時に取り込んで比べる場合は、各機器の時刻をNTPで合わせておかないと、どちらが先に起きたかを判断できない。
午後での問われ方
- 「スイッチに解析用PCをつないだが目的の通信が見えない理由」と、その対策としてのミラーポートの設定対象を問う。
- パケットの取り込み結果を示し、SYNへの応答の有無、RST、再送などから障害の原因箇所を答えさせる。
- クライアント側とサーバ側など二地点の取り込みを比べ、パケットがどの区間で失われたかを特定させる。
- 時刻の差からRTTを求め、ウィンドウサイズとの関係でスループットの上限を計算させる。
- 暗号化された通信を解析する際に、どの地点で何があれば内容を確認できるかを説明させる。