はじめに
TIGの棚井龍之介です。
夏の自由研究ブログ連載2021の第1投稿として、Wiresharkで実際に流れるパケットを観察し、通信プロトコルの動きを見てみました。
本記事の目標
コンピュータはネットワークを通じて他のコンピュータと通信しています。
みなさんが利用する業務用PCも、いっときも目が離せないiPhoneも、Apple Watchでさえも、ネットワークを通じてデータのやり取りをしています。PCとスマートウォッチというように明らかに見た感じが異なるデバイスであっても、どちらもWi-Fiを設定すればインターネットと通信できるのは、共通のルールのもとネットワークを介して通信しているからです。この共通ルールのことを通信プロトコルと呼びます。
本記事では、基本的な通信プロトコルの中身を見ていくことにより
- 通信プロトコルのやり取りがイメージできる
- IPアドレス、MACアドレスの利用場面がわかる
- ネットワーク分野への誘いになる
ことを目標としています。
TCP/IPモデル
インターネットの多くは、TCP/IPプロトコルによって通信しています。
Twitterで投稿するとき、YouTubeを見るときも、その裏側ではコンピュータがTCP/IPに沿った通信を行っています。この通信は「利用者が意識しないで済む」ことを念頭に設計されています。そのため、TCP/IPで何らかの問題が生じた場合、利用者の認知は「ネットにつながらない」です。
あるコンピュータ(PC)から別のコンピュータ(Server)に通信するとき、以下のようなやりとりが発生しています。
人間が会話するのと同様に
- PC:「明日の東京の天気は?」
- Server:「晴れです」
とやり取りしているだけです。
この通信にて、TCP/IPは裏側で以下のようなことをやっています。
PC→Server
PC←Server
通信したいデータに対して、カプセル化を繰り返しながら情報を追加していき、符号化してデータを送る。受け手側ではその逆の順序で情報を外していき、最終的に送信元のデータを取得する。各層には独自の役割があり、それぞれがうまく機能することでコンピュータ同士は通信しています。よくある「ネットにつながない」現象は、これらの層のどこかで問題が生じている、ということになります。
コンピュータ同士がやり取りするデータはネットワークを介しているため、ネットワーク自体を覗き見ることで、「やり取りしているデータ自体」を見ることができます。このデータを見る作業をパケットキャプチャといいます。
Wiresharkでパケットキャプチャ
パケットキャプチャのために、OSS(Open Source Software)のWiresharkを使います。
パケットキャプチャツールは、キャプチャ実行端末のNIC(Network Interface Card)を通信傍受することで、端末の送受信する通信データを取得するものです。
Wiresharkを起動するとキャプチャするNICの選択画面が表示されるので、インタフェース表示を無線にして「Wi-Fi」を選択すれば、無線で送受信されるパケットが見れます。
パケットを見る機会などほとんどないので、しばらく見続けてみましょう。
TCP
や192.168.1.1
など、なんとなく見覚えのある情報もあれば、正体不明のIPも見つかると思います。Wiresharkで続々と表示されるレコードは、全てPCで送受信しているデータです。実際に見てみると、想像していたよりも沢山のやり取りをしていませんか?
それでは、WiresharkでTCP/IPでの代表的な3つの通信プロトコルを見ていきます。
- データリンク層
- ARP
- ネットワーク層
- ICMP
- トランスポート層
- TCP
アプリケーション層の内容はWiresharkのみでは扱いきれない場面が多いため、本記事では取り扱っていません。
データリンク層
IPアドレスとMacアドレスの対応表を作成するARP
の通信を見ていきます。ARPはブロードキャスト通信の「ARP Request」とユニキャスト通信「ARP Reply」により実現されます。
Wiresharkは表示レコードを制限できるので、表示条件をarp
にしてしばらく待つとルータからのARP通信をキャッチできます。
今回キャッチした内容は以下です。
- Source
- MAC: Buffalo_(UAA)
- IP: 192.168.11.1
- Destination
- MAC: 00:00:00_00:00:00
- IP: 192.168.11.7
- ARP Request
- Info
- Who has 192.168.11.7? Tell 192.168.11.1
- Source
- MAC: Apple_(UAA)
- IP: 192.168.11.7
- Destination
- MAC: Buffalo_(UAA)
- IP: 192.168.11.1
- ARP Reply
- Info
- 192.168.11.7 is at Apple_(UAA)
Infoをみると、ルータとPCが会話していることが分かります。
- ルータ: 192.168.11.7を持っている方、Macアドレスを私に教えてください。
- PC: 私が192.168.11.7です。MacアドレスはApple_(UAA)です。
ARPはIPアドレスとMacアドレスの対応表を作成するプロトコルなので、上記会話にて「ルータのARPテーブルに、192.168.11.7に紐づくMacアドレスはApple_(UAA)」と登録されたようです。
ネットワーク層
トラブルシュートでお馴染みのpingを見ていきます。pingはICMP
プロトコルを用いたネットワーク監視の王道ツールです。ICMPは「Echo Request」と「Echo Reply」により会話します。
ネットワークの障害切り分けでは、pingに対してEcho Replyが
- 返ってくる: ネットワーク層より上の層(トランスポート層、アプリケーション層)に問題あり
- 返ってこない: ネットワーク層より下の層(データリンク層、物理層)に問題あり
と疎通問題を切り分けられます。
作業PC(192.168.11.7)から、ルータ(192.168.11.1)に向けて、pingを打ってみます。
$ ping -t 5 192.168.11.1 |
このとき、Wiresharkでは5つの通信全てをキャッチしています。icmp
で表示を絞り込むと…
各通信ごとに「Echo (ping) Request」と「Echo (ping) Reply」を送り合っていることが分かります。
Echo (ping) Request
Echo (ping) Reply
ネットワーク疎通確認のとき、ping単体だと通信がイメージできないならば、裏でWiresharkを起動すると理解が進むかもしれません。その場合、デフォルトのWiresharkはNICを通過する全パケットを取得&表示してしまうため、メモリ負荷を下げるために「キャプチャフィルタ」や「表示フィルタ」の利用がオススメです。
トランスポート層
トランスポート層はTCP(Transmission Control Protocol)とUDP(User Datagram Protocol)の2つがメインです。今回はTCP
側での、通信の開始と終了を見ていきます。
TCPは通信の信頼性を保証するため、その開始と終了タイミングで特徴的なデータのやり取りを実施しています。
- 開始
- 3ウェイハンドシェイク
- 相互に通信を開始する
- 通信内容
1. SYN
2. SYN + ACK
3. ACK
- 3ウェイハンドシェイク
- 終了
- コネクションの切断
- 各自で通信を終了する
- 通信内容
1. FIN + ACK
2. ACK
3. FIN + ACK
4. ACK
- コネクションの切断
Wiresharkには、TCP通信の開始からコネクションの終了までをグルーピングしてくれるStreamID
という識別子があります。これ利用して、あるTCP通信が始まってから終わるまでの流れを見ていきます。
開始・終了
開始のSYN+ACKと、終了のFIN+ACKがキャッチできました。
本ブログ執筆まで、「コネクション切断」の通信は「FIN→ACK→FIN→ACK」パターンだと理解していたのですが、Wireshackでのキャプチャで「FIN/ACK→ACK→FIN/ACK→ACK」と表示されて、自分の理解が間違っていたことに気づきました。
ネットで検索したところ、日本語で分かりやすい記事が見つかったので、URLを添付します。
FIN -> FIN/ACK -> ACK という TCP の幻想
要するに、TCP通信が開始された(3ウェイハンドシェイクが完了してESTABLISHED状態になった)相手との通信では、基本的にACK
を付与しなければならない、ということです。コネクション終了時はFIN
ではなく、FIN/ACK
が正解です。
ネットワークは教科書的な理解よりも「実際の運用で、ちゃんと疎通させられる知識」の方が重要です。Wiresharkでリアルなパケットを見て「知識と実挙動の対応を確認する」ことの重要性を改めて実感しました。
パケットの詳細を確認すると、行列のような形で SYN・ACK・FIN が表現されていることが分かります。
SYN
SYN・ACK
FIN・ACK
ACK
Wiresharkでパケットをしばらく監視していると、通信失敗やリトライ時の挙動が見れるので、「Wiresharkを眺める→新しい情報を見つける→ネットで調べる」を繰り返せば、色々な生きた知識が身についていきます。
おわりに
Wiresharkを利用して、代表的なネットワーク通信プロトコルの「ARP, ICMP, TCP」の中身を見てきました。
各種通信プロトコルを「知識としては知っている」で終わらせずに、パケットキャプチャツールでインターセプトして「実際にどのように通信しているかイメージできる」まで体得すれば、ネットワーク系の問題が発生したときに、より正確に問題の切り分けができると思います。
アプリケーションと異なり、ネットワークは「見えない」が勉強の壁になりがちです。今回ご紹介した「Wiresharkでの可視化」を導入することで、ネットワーク分野への参入障壁が下がればいいなと思います。