ツイッターで、pcap2qlogというpcapをqlogに変換するツールを教えていただきました。
今回は、s2n-quic と pcap2qlog を組み合わせて、qlogを生成してみたので紹介します。
pcap2qlog をインストールする
pcap2qlogのREADME.md の手順に従いインストールします。
まずリポジトリをクローンします。
$ git clone https://github.com/quiclog/pcap2qlog
$ cd pcap2qlog
次に、レポジトリの中で以下のコマンドを実行します。
$ npm install npm notice created a lockfile as package-lock.json. You should commit this file. npm WARN qlog-pcap@1.0.0 No repository field. added 5 packages from 38 contributors and audited 5 packages in 3.749s found 0 vulnerabilities $ npx tsc
こうすると、以下のコマンドでpcapをqlogに変換するツールが実行できるようになります。
$ node out/main.js No input file or list of files specified, use --input or --list
s2n-quicでkeylogファイルを出力する
pcap ファイルは暗号化されています。それを復号するためにkeylogファイルを書きだす必要があります。
「key_log」という名前のAPIが無いかを検索すると、クライアントとサーバーそれぞれにkeylogを出力するためのAPIがあることが分かります。
s2n_quic::provider::tls::default::client::Builder::with_key_logging s2n_quic::provider::tls::default::server::Builder::with_key_logging
githubのソースを検索すると、テストコード で使っているのを見つけました。
let tls = s2n_quic::provider::tls::default::Server::builder() .with_certificate(certificate, private_key)? .with_application_protocols( self.opts.application_protocols.iter().map(String::as_bytes), )? .with_key_logging()? .build()?;
このテストコードは、echoのexampleとは、サーバーのインスタンスの生成方法が異なっています。
let mut server = Server::builder() .with_tls((CERT_PEM, KEY_PEM))? .with_io("127.0.0.1:4433")? .start()?;
with_tlsのAPI を見ると、s2n_quic::provider::tls::default::Server::builder
を使って生成したtlsのインスタンスを渡せばよさそうなことが分かります。
なので、echoのexampleの宣言を以下のように変更しました。
let tls = s2n_quic::provider::tls::default::Server::builder() .with_key_logging()? .with_certificate(CERT_PEM, KEY_PEM)? .build()?; let mut server = Server::builder() .with_tls(tls)? .with_io("127.0.0.1:4433")? .start()?;
echoを実行し、pcapとkeylogファイルを取得する
ターミナルを分けて、パケットをキャプチャするためのtshark、echo サーバー、echo クライアントをそれぞれ実行します
まずtshark を実行して、test.pcapというファイルにpcapを保存します。tsharkは、echo クライアント、echo サーバーの実行を終えたら終了します。
tshark -i lo -w test.pcap
次にecho serverを実行します。
keylog.rs を見ると、環境変数 SSLKEYLOGFILE
を設定していると、keylogファイルを出力しそうなことが分かります。
なので、実行時に環境変数を設定して実行するようにします。
$ SSLKEYLOGFILE=./keylog.txt ./target/release/quic_echo_server
最後にecho clientを実行します。今回は、「abcdefg」、「hijklmn」と2つのメッセージを送っています。
$ ./target/release/quic_echo_client abcdefg abcdefg hijklmn hijklmn ^C
echo server を終了させて、keylogファイルが生成されていることを確認します。
$ cat keylog.txt SERVER_HANDSHAKE_TRAFFIC_SECRET XXXX... CLIENT_HANDSHAKE_TRAFFIC_SECRET XXXX.... SERVER_TRAFFIC_SECRET_0 XXXX.... CLIENT_TRAFFIC_SECRET_0 XXXX....
pcapファイル、keylogファイル、tsharkのパスを指定して、pcap2qlogを実行します。
$ node out/main.js --input=./test.pcap --secrets=../s2n-quic/examples/echo/keylog.txt --tshark=/usr/bin/tshark --output=. /path_to_dir/pcap2qlog/cache/4168580c0e24469893c5a5b5f21553b58e4d09ef.qlog
生成されたqlogファイルを見ると、正しく生成されていることが分かります。
{ "qlog_version": "draft-02-wip", "description": "", "traces": [ { "title": "Connection 1", "vantage_point": { "name": "pcap", "type": "network", "flow": "client" }, "configuration": { "time_offset": "0", "time_units": "ms", "original_uris": [ "./test.pcap" ] }, "common_fields": { "group_id": "7175fb807a7e1d4e", "protocol_type": "QUIC", "reference_time": "1647345682.7767463" }, "event_fields": [ "relative_time", "category", "event", "data" ], (以下略)
長いので、全文は、gist に置いておきました。
qvisで可視化すると、ちゃんと可視化できていることが分かります。
まとめ
s2n-quicでpcap2qlogを使って、qlogファイルを生成してみました。
pcapから生成できるのはすごいですね。。。
ツイッターで、s2n_quic::provider::event::Subscriber
を使うという方法を紹介いただいたので、それを使ってqlogを生成する方法も試してみたいと思います。