はじめに
こんにちは!新卒入社4年目の加藤です。
皆さんはサーバーの設定をした際に通信の疎通が取れなくて困ったことはありませんか?
そんなときには通信の中身を見てみるとなにかわかるかもしれません。
今回はそんなパケットキャプチャについて簡単にご説明します。
パケットキャプチャとは?
その名の通り、ネットワークを流れるパケットをキャプチャすることです。
パケットの中には、宛先のIPアドレスやポート番号、送受信されるデータ自体も含まれるため、そのネットワーク上でどんなデータが流れているか、どんな問題が発生しているのかを切り分けることができます。
方法はいくつかありますが、今回はPC上で直接取得してみましょう。
パケットキャプチャの簡単な始め方
では実際にパケットをキャプチャしてみましょう!
…の前に、パケットをキャプチャするには専用のツールが必要です。
とは言っても、簡単にインストールができる他、OSに標準で用意されていることも多いです。
多く利用されるキャプチャツールをまずはご紹介します。
Wireshark
Wireshark(ワイヤーシャーク)は、オープンソースのパケットキャプチャツールです。
Windows / macOS / Linuxなど幅広いOSに対応しており、インストールするだけでGUI上からキャプチャを行うことができます。
そのため、誰でも簡単にパケットキャプチャを行うことができるため、基本的にWiresharkを利用することをおすすめします。
tcpdump
tcpdump(ティーシーピーダンプ)は主にLinuxで利用されるキャプチャツールです。
OS標準で付属していて、コマンドを利用することでキャプチャすることができます。
Linuxを利用していて、サーバー環境であるという理由などからWiresharkをインストールしづらい場合や、GUIが利用できないLinux環境の場合はこちらを使うのがおすすめです。
1 2 |
% tcpdump -w dump.pcapng src host 192.168.1.1 and port 80 # 192.168.1.1を発信元とする80番ポートの通信のみをキャプチャ |
PktMon
PktMon(Packet Monitor/パケットモニター)はWindows 10やWindows Server 2019以降で利用できるキャプチャツールです。
OS標準で付属していて、コマンドを利用することでキャプチャすることができます。
Windowsを利用していて、サーバー環境であるという理由などからWiresharkをインストールしづらい場合や、Server CoreなどGUIが利用できない環境の場合はこちらを使うのがおすすめです。
https://learn.microsoft.com/ja-jp/windows-server/networking/technologies/pktmon/pktmon
1 2 3 4 5 |
C:\\Windows\\System32> pktmon filter add -i 192.168.1.1 -p 80 # 192.168.1.1との80番ポートのパケットのみ C:\\Windows\\System32> pktmon start --capture --pkt-size 0 # サイズが0以上のパケットをキャプチャ開始 C:\\Windows\\System32> pktmon stop # キャプチャ終了(PktMon.etlというファイルができる) C:\\Windows\\System32> pktmon etl2pcap PktMon.etl # キャプチャファイルをWiresharkで見られる形式に変換 |
実際にパケットキャプチャしてみよう
今回はWiresharkを利用してHTTPのパケットをキャプチャしてみましょう。
簡易的に、Microsoft Azure上にNGINXを起動したVMを用意して、検証してみます。
HTTPの通信
ではまずはシンプルにHTTPのパケットをキャプチャしてみましょう。
PCからのキャプチャ結果がこちらです。
( 192.168.100.2
がPCで、 20.89.88.240
がVMです)
本当は通信がたくさんあるのですが、「 ip.addr==20.89.88.240
」と入力し、VMとの通信のみ表示するように絞っています。
まず最初に、PCとVMが通信を始めるためにコネクションを確立しようとしています。
- PC → VMにSYNを送る(No. 25)
- VM → PCにSYN/ACKを返す(No. 26)
- PC → VMにさらにACKを返す(No. 27)
これによってPCとVMの間で通信の準備が整いました。
次に通信の準備ができたので、実際にHTTPの通信をしています。
- PC → VMにHTTP GETを送る(No. 28)
- VM → PCにHTTP 200 OKを返す(No. 30)
なお、それぞれの間に通信が届いたことを表すACKをお互いに返しています。(No. 29/31).
これで通信は終わりですので、最後にコネクションを切断しています。
- PC → VMにFINを送る(No. 32)
- VM → PCにFIN/ACKを返す(No. 33)
- PC → VMにさらにACKを返す(No. 34)
通信を遮断してみよう
では次に通信を遮断した状態で見てみましょう。
今回はVM上のLinuxに入っているiptablesで、HTTPで利用されている80番ポートをREJECTする設定を入れて検証してみます。
PCからのキャプチャ結果がこちらです。
なにやら赤文字で「 TCP Retransmission
」とたくさん書かれています。
これは、最初にコネクションを確立するために送ったPC → VMへのSYNパケット(No. 5)に対して、VM→PCに返ってくるはずのACKが一定時間内に返ってこなかったため、PCがVMにパケットを再送している状態です。
今回はiptablesを遮断したためとわかっていますが、原因がわからない状態でこの結果だと、
- 経路上のネットワーク
- VMに設定しているネットワーク
- VMに設定しているNetwork Security Group
- iptablesなどのVMのファイアウォール
- VM上のWebサーバ
のどこに問題があるか、更にそれぞれPC → VM / VM → PCのどちらの方向の通信に問題があるかがわかりません。
では、VM上ではどうなっているのでしょうか。
VMはLinuxで起動しているため、SSH接続してtcpdumpコマンドで取得してみました。
その結果がこちらです。
( 10.0.0.4
がVMで、PCのグローバルIPアドレスは伏せています)
どうやら、PC → VMの通信はきちんとVMまで到達しているようですね。
(No. 36 / 38 / 40 / 75 / 77/ 79 / 81 / 157)
つまり、PC → VM方向は問題がなさそうです。
そして、こちらでは緑色の文字で「 Port Unreachable
」とたくさん書かれてたパケットが送られています。
ICMPとはインターネットの通信における情報の通知などに利用されるプロトコルです。
(ちなみに、pingはこのICMPを利用しています。 )
今回は「 Port Unreachable
」のため、ポートに到達できなかったことを表しています。
つまり
- VM上のWebサーバ
- iptablesなどのVMのファイアウォール
に問題がありそう、ということがわかります。
(iptablesは設定によってICMPを返さなかったり、別のタイプを返すことも可能です)
また、VM → PCにICMPを返しているにも関わらずPCでは受け取れていないことから、その方向の経路上でICMPがブロックされている可能性もありそうです。
このように、ブラウザからアクセスするだけですと読み込み中のままに見えますが、パケットをキャプチャしてみるとここまで原因や問題点を絞り込むことができます。
最後に
ネットワークの中身は目に見ることが難しいため敬遠されがちですが、パケットキャプチャを行うことでどこに問題が発生しているのかがわかるようになります。
また、ネットワークがどのようなルールで通信されているかを知れば知るほど、パケットキャプチャも面白くなります。
これを機にぜひ試してみてください。