Chromium Edge の net-export で QUIC、HTTP/3 の通信をキャプチャする

### この記事でやること
Chromium ベースの Microsoft Edge の net-export という機能でネットワークログをキャプチャし、専用のビューアーの netlog-viewer で確認するところをご紹介します。なお、QUIC や HTTP/3、 net-export のパラメータ等の詳細には触れません。

※ 本投稿では通信のキャプチャと言いつつ、あくまで Chromium 側で出力可能な NET_EXPORT の NetLog によるログを取得し閲覧する形となるので、いわゆるOSの標準コマンドのnetshによる取得やパケットキャプチャドライバ等によるパケットキャプチャとは仕組みも異なり、取得できるレイヤーや粒度も異なりますのでご注意ください。

## 背景
今年 2021 年に新しいトランスポートプロトコルとして QUIC が IETF にて標準化されました。([RFC 9000](https://www.rfc-editor.org/rfc/rfc9000.html))

ちなみに、ざっくりですが当初の Google QUIC はアプリケーションプロトコルも含めてひとまとめにしたもので、その後 HTTP over QUIC としても議論され、最終的にアプリケーションプロトコルの部分と切り離されて、今回標準化されたトランスポートプロトコルの QUIC と現在標準化を議論中のアプリケーションプロトコルの HTTP/3 でそれぞれ分離されたわけです。

今回は QUIC をトランスポートプロトコルとして利用する HTTP/3 のキャプチャを Chromium Edge 標準で搭載の net-export のログ機能を利用し、確認していこうと思います。そもそも Chromium の機能なので Google Chrome でも同様の方法で勿論可能です。ちなみに、今回は HTTP/3 のキャプチャと書いてますが、Google QUIC もキャプチャ可能です。

## 今回の検証
- Windows 10 21H1 の Chromium ベースの New Microsoft Edge を利用
- https://www.google.co.jp/ にアクセスして検証します

## 事前準備 : キャッシュ削除
ブラウザの Inprivate モードで検証してもいいですが、通常のモードで開く場合には念の為キャッシュを削除しておきましょう。以下の手順で削除可能です。

edge://settings/privacy を開き、[時間の範囲] は [すべての期間] を選択し、[閲覧データをクリア] 内の [クリアするデータの選択]  のボタンを押し、[Cookie] と [キャッシュ] の欄にチェックを入れ、[今すぐクリア] を押します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/150728/7e4221ff-8698-9bc6-11f3-047a4e9eef63.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/150728/a3fcb541-62b8-b1ae-21d1-f4f00c0a479f.png)


## 1. キャプチャ -> Viewer で開く
具体的な手順をここに書いていきたいところですが、既に画像付きで [net-export の使い方 (Japan Developer Support Internet Team Blog)](https://jpdsi.github.io/blog/internet-explorer-microsoft-edge/how-to-use-net-export/) に書いてあるため、こちらは省略します。

この Blog の "ログの取得方法" にあるように [edge://net-export/](edge://net-export/) (Chrome の場合は [chrome://net-export/](chrome://net-export/)) を開き、net-export の Network Log を取得開始・https://www.google.co.jp/ (Google の検索サイト) にアクセス再現・取得終了まで行います。

取得後、保存された JSON ファイルを [netlog-viewer - https://netlog-viewer.appspot.com/](https://netlog-viewer.appspot.com/) で開きます。


## 2. netlog-viewer : Alt-Svc タブ
まず最初に netlog-viewer の左パネルの [Alt-Svc タブ](https://netlog-viewer.appspot.com/#alt-svc) から見ていきましょう。

HTTP/3 で通信するためにはサーバー側が HTTP/3 に対応しているかを知る必要がありますが、これは Alt-Svc レスポンスヘッダ ([RFC 7838](https://datatracker.ietf.org/doc/html/rfc7838/)) にて確認が可能です。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/150728/46aa21d6-bc09-6156-5925-66587b55870a.png)

また、[Alt-Svc (MDN Web)](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Alt-Svc/) にあるように ma にて max-age を指定することでこの期間まで確認を省略できます。その確認したマッピングの情報がここで見れるわけです。

一般的には HTTP/3 の QUIC では通常 UDP の 443 ポートを利用する事が多いようなのですが、特に仕様でポート番号が決まってはいないため、h3=":443"; や h3-29=":443"; のように、Alt-Svc レスポンスヘッダで指定がされています。こちらのポート番号もこの Alt-Svc タブで、サーバー側のどのポート番号にマッピングされたかを確認することが可能です。Chromium はどのサイトが QUIC をサポートしているかをこのヘッダーを基に記憶しておくことで、Alt-Svc による事前確認のオーバーヘッドを緩和しています。

#### 参考 : Alt-Svc ヘッダによる事前確認について

例えば、HTTP3 対応がされている nginx のデモサイトの https://quic.nginx.org/ にアクセスしてみます。
そうすると、最初の方のリソース読み込みのアクセスは以下のように HTTP/2 のプロトコルでアクセスされています。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/150728/d689fa9d-5c66-d91d-85e9-5e83cff7f8ff.png)

そして応答ヘッダーの中に alt-svc ヘッダーがあります。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/150728/26dc192b-9a36-d243-f71b-73ad17a4c11d.png)

一部、同サイト内でも後続では HTTP/3 のアクセスがあります。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/150728/c29c1958-7483-a448-f9ca-4113f4c16cab.png)

そして、デモサイトの https://quic.nginx.org/ に DevTools でキャッシュを無効化した上で再度アクセスしてみます。そうすると、先ほどは HTTP/2 のアクセスだったリクエストが HTTP/3 でのアクセスに変わっています。これは上述したブラウザ側で事前の Alt-svc ヘッダーの内容を記憶しており、max-age 以内であったために最初から HTTP/3 アクセスを行う事が可能であったためです。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/150728/f34ed972-d811-255d-1491-106d3bcae4ad.png)


## 3. netlog-viewer : QUIC タブ
次に netlog-viewer の左パネルの [QUIC タブ](https://netlog-viewer.appspot.com/#quic) を開きます。
上部では Supported Versions などの QUIC に関する情報が閲覧できます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/150728/c9657d00-a883-d582-3bbd-3a061a9092c4.png)


今回はキャプチャを確認したいため、下部の QUIC sessions を利用します。
例えば、Version の部分が h3-Q050 の場合は前述の Google QUIC を示し、draft29 となっているのは h3-29 と呼ばれる草案 29 版ベースの HTTP/3 を指します。他にも Peer address や Connection ID が確認できます。

View live QUIC sessions のリンクをクリックすると、表示されている各 QUIC のネットワークログが見れますが、今回は、そこではなく、表の中の 1 つの Connection ID のリンクを試しに開いてみてください。
具体的には 1 つの www.google.co.jp:443 の Connection ID のリンクをクリックしてみます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/150728/c5845fa0-cac8-de98-7547-d808db72faa9.png)


## 4. netlog-viewer : 上記 Connection ID で絞った Events タブ
そうすると、[Events タブ](https://netlog-viewer.appspot.com/#events) に上記クリックした Connection ID でフィルターした状態で遷移します。

具体的には、以下のように type:QUIC_SESSION の選択した Connection ID の QUIC セッションに関する詳細なネットワーク ログが右側で確認できるはずです。スクロールして眺めてみてください。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/150728/91472493-e29b-b45f-1fc5-addfa7e527ff.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/150728/df076a58-aee6-86a1-22dc-c295006bc2b7.png)

例えば、HTTP3_HEADERS_SENT イベントや HTTP3_HEADERS_DECODED イベントで各リクエストやデコード後のレスポンスヘッダーも確認可能です。また上部のフィルター "type:QUIC_SESSION <Connection ID>" を解除すれば、他の様々なイベントも確認でき、UDP_SOCKET、QUIC_STREAM_FACTORY_JOB、HTTP_STREAM_JOB、HTTP_STREAM_JOB_CONTROLLER、URL_REQUEST など様々なソースタイプがあります。ぜひ色々なソースをポチポチしてみてください。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/150728/f297566c-3126-01f6-c1bc-8855805d7707.png)

なお、今回特に深追いしませんが、例えばソースやイベントの状況によっては os_error や net_error も簡易的なエラーコードだけではありますが確認が可能です。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/150728/dbbe1653-f02d-9c8c-5791-4319a36aa5ba.png)

ちなみに、左側に表示されている各ログのソースタイプの一覧は Chromium リポジトリ内の [net_log_source_type_list.h](https://source.chromium.org/chromium/chromium/src/+/main:net/log/net_log_source_type_list.h)、右側に表示されている各イベントタイプの一覧は [net_log_event_type_list.h](https://source.chromium.org/chromium/chromium/src/+/main:net/log/net_log_event_type_list.h) で見れます。

## 5. netlog-viewer 以外でも実は見れる net-export の NetLog
① edge://net-export や chrome://net-export の NetLog は実は Fiddler Classic でも拡張の機能をダウンロードすることで見ることが可能です。

[Fiddler でも実は見れる edge://net-export の NetLog](https://qiita.com/nt-7/items/c897e9460ef43af6ed14#%E5%8F%82%E8%80%83--fiddler-%E3%81%A7%E3%82%82%E5%AE%9F%E3%81%AF%E8%A6%8B%E3%82%8C%E3%82%8B-edgenet-export-%E3%81%AE-netlog)

② また、NetLog は qlog のフォーマットに対応しているため QUIC や HTTP/3 の qlog の可視化ツールである [qvis](https://qvis.quictools.info/#/files) でも確認することが可能です。

1. qvis のサイト https://qvis.quictools.info/#/files を開きます。
2. net-export で取得しておいた NetLog の json を Option 2 の Upload file 欄から Import することで確認可能です。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/150728/9326ed5f-d148-e2dc-36f0-eede2b9b5332.png)


## その他の方法の紹介
### A. 開発者ツールのネットワークタブ
他にキャプチャする方法として、Edge や Chrome の DevTools (開発者ツール) の Network パネルによる確認があります。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/150728/2e85af0c-0bb1-eb08-f33d-2518b1201f03.png)

### B. SSLKEYLOGFILE を用いた Wireshark での閲覧
さらに他にも、SSLKEYLOGFILE の環境変数と [Wireshark](https://www.wireshark.org/download.html) を用いた方法があります。

SSLKEYLOGFILE の環境変数を事前にキャプチャ前に指定して、Microsoft Edge や Google Chrome の通信をキャプチャ後に、出力したキーを含むファイルを用いて Wireshark で復号する方法です。TLS 1.3 を前提とした QUIC 関連の復号はサーバーの秘密鍵だけあっても復号できないので取得する Edge クラインアント側で出力した SSLKEYLOGFILE を利用してパケットを復号し確認します。

なお、事前準備から復号までの具体的な手順は [Wireshark による New Microsoft Edge のトレース取得方法 (Japan Developer Support Internet Team Blog)](https://jpdsi.github.io/blog/internet-explorer-microsoft-edge/New-Edge-Wireshark/) にあるので、ご興味があればぜひそちらの方法でもお試しください。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/150728/3eaedc28-fdb5-11ed-e912-37a14bc5234e.png)

## ご参考
冒頭に述べたように特に今回は QUIC や HTTP/3 の詳細等には全く触れてません。もし興味があれば様々な方が書いてくださっている良記事や講演等をご参照ください。一部かもしれませんがご参考までにいくつか載せておきます。

https://www.youtube.com/watch?v=2nefATBHs1o
https://github.com/flano-yuki/http3-note
https://gihyo.jp/magazine/wdpress/archive/2021/vol123
https://eng-blog.iij.ad.jp/archives/10039