curl + wolfSSLでECHを試してみよう

TLS 1.3では、ハンドシェイクメッセージの多くが暗号化されるようになり、通信内容の秘匿性が大幅に向上しました。しかし、ClientHelloおよびServerHelloメッセージは平文で送信されるため、サーバの識別情報や設定に関する一部の情報は依然として外部から観察可能です。

特に問題となるのが、Client Helloに含まれるServer Name Indication (SNI)拡張です。SNIは、同一IPアドレスを使用して複数のサーバーが運用されている場合に、クライアントが接続先ホストを明示することでサーバーが適切な証明書を選択できるようにする仕組みです。しかし、SNI情報は暗号化を開始する前に送信されます。つまり、ネットワーク上で第三者によって観察され、ユーザーの接続先ホスト名を盗み見られてしまうというプライバシー上の懸念があります。

これを解決するのが、TLS 1.3の拡張機能であるEncrypted Client Hello (ECH)です。ECHを使用することで、このClient Helloメッセージを暗号化できるようになります。
ECHを有効にすると、Client Helloメッセージの中にもう1つの「暗号化されたClient Helloメッセージ」が埋め込まれます。このとき、内側の暗号化されたClient Helloには真の情報が、外側のClient Helloにはダミーの情報がそれぞれ記されます。
この仕組みにより、たとえネットワーク上でClient Helloが観察されたとしても、ユーザーの接続先が第三者に漏れることはありません。

ただし、本稿翻訳時点ではIETFによる標準化プロセスが続いており、対応しているサーバやクライアントは未だ限定的です。

curlwolfSSL は、ECHに対応しています。

wolfSSL のインストール

まず、wolfssl ライブラリを ECH サポートを有効にしてビルドする必要があります。wolfSSL リリースをダウンロードし、次のようにしてインストールします。

$ ./configure --enable-ech --enable-curl
$ make
$ sudo make install

curl のインストール

次に、curl を wolfSSL サポートを有効にしてビルドする必要があります。curl リリースをダウンロードし、次のようにします。

$ ./configure --enable-ech --with-wolfssl=/usr/local
$ make
$ sudo make install

もしwolfSSLのインストール先がデフォルトの /usr/local でなければ、1行目のオプションを変更してください。

ECH の有効化

curl では、コマンドライン引数 --ech を使用してECHの機能を制御できます。具体的には、次のようにします。

  • --ech false:ECHを使用しない (デフォルト)
  • --ech true:ECHを使用しようと試みるが、対向サーバーが対応していない場合は使用しない
  • --ech hard:ECHの使用を強制し、対向サーバーが対応していない場合には処理を中止する

合わせて、DNSの正引きリクエスト/レスポンスパケットから接続先サーバの情報が第三者に漏れないよう、DNS-over-HTTPSを使用すべきです。curlでは、--doh-url オプションを付加することで利用できます。

使用例

$ curl --ech hard --doh-url https://one.one.one.one/dns-query https://defo.ie/ech-check.php

この例では --ech hard を使用しており、ECH が使用できない場合は curl が失敗します。

取得したペイロードの抜粋を以下に示します。

<p>
SSL_ECH_OUTER_SNI: cover.defo.ie <br />
SSL_ECH_INNER_SNI: defo.ie <br />
SSL_ECH_STATUS: success <img src="greentick-small.png" alt="good" /> <br />
</p>

Wireshark でトラフィックをキャプチャすると、以下のようになります。

このキャプチャから、

  • 外側の Client Hello メッセージでは暗号化されていない公開サーバー名(この場合「cover.defo.ie」)を使用していること
  • 到達しようとしている実際のサーバー名を含む、内側のClient Hello は暗号化されていること

が確認できます。

一方で、ECHを使用せずに実行してキャプチャすると次のようになります。

ここでは、Client Hello 全体が暗号化されておらず、SNI サーバー名が「defo.ie」として記録されていることが観察できます。

ご質問がございましたら、ぜひ info@wolfssl.jp までお問い合わせください。

原文:https://www.wolfssl.com/using-ech-with-curl-and-wolfssl