Cloudflareが本日サポートを発表した、暗号化SNIは、拡張版TLS 1.3プロトコルであり、ISP、カフェ店主、ファイアウォールなどのパス上のオブザーバーが、TLS Server Name Indication(SNI)拡張子を傍受し、これを利用してユーザーの訪問先のWebサイトを特定することを防止し、インターネットユーザーのプライバシーを向上させます。

暗号化されたSNIと、すでにCloudflareから無料で提供している他のインターネットセキュリティ機能を用いることで、インターネット上のコンテンツ検閲やユーザーの追跡をより困難にします。以下で、その仕組みを説明します。

なぜサーバー名?

TLS Server Name Indication(SNI)拡張仕様は、2003年に最初に標準化された、初回のTLSハンドシェイク中にクライアントが希望する接続先を指定することを要求する仕様で、サーバーが複数のTLSが有効にされたWebサイトを同一IPアドレス一式でホストすることを可能にしたものです。SNIなしでは、サーバーは、たとえばどの証明書がクライアントに提供されるのか、またはどの設定が接続に適用されるのかを認識できません。

クライアントは、接続先のサイトのホスト名を含むSNI拡張機能をClientHelloメッセージに追加します。そしてTLSハンドシェイク中にサーバーにClientHelloを送信します。残念ながら、この時点でクライアントとサーバーは暗号鍵を共有していないため、ClientHelloメッセージは暗号化されずに送信されます。

暗号化されていないSNIを使用したTLS 1.3

つまり、パス上のオブザーバー(ISP、カフェの店主、ファイアウォールなど)は、プレーンテキストのClientHelloメッセージを傍受して、クライアントが接続しようとしているWebサイトを特定することが可能です。したがってオブザーバーはユーザーのアクセス先のサイトを追跡できます。

ですが、SNI暗号化を使用すれば、残りのClientHelloがプレーンテキストで送信されても、クライアントはSNIを暗号化します。

暗号化されたSNIを使用したTLS 1.3

では、どうして以前は暗号化できなかった元のSNIを今は暗号化できるのでしょうか?クライアントとサーバーがネゴシエーションしていない時点で、暗号鍵はどこから来るのでしょうか?

ニワトリが卵より先でなければならないなら、ニワトリはどこにいるべきか?

多くのインターネット機能と同様に、答えはシンプルに「DNS」です。

サーバーは、接続する前にクライアントがフェッチできる既知のDNSレコードに公開鍵を公開します(A、AAAA、およびその他のレコードの場合と同様)。次にクライアントは、ClientHello内のSNI拡張機能を「暗号化したSNI」の拡張機能と置き換えますが、これはオリジナルのSNI拡張機能と違いはないのですが、下で説明するサーバーの公開鍵を使用して派生させた対称鍵暗号化を使用して暗号化されています。サーバーは秘密鍵を持ち、対称鍵を派生させることができるので、拡張機能を復号化して、接続を終了(またはバックエンドサーバーに転送)することができます。クライアントとこれに接続されているサーバーのみが暗号鍵を派生させることができるため、サードパーティーは暗号化されたSNIを復号化してアクセスすることはできません。

これはTLSバージョン1.3以降の拡張機能であり、それ以前のバージョンのプロトコルでは機能しないことに注意が必要です。その理由は非常に単純です。TLS 1.3により実現される変更の1つは(問題がないわけではありませんが)、サーバーがTLSハンドシェイクの暗号化された部分に対して送信した証明書メッセージを移動することです(1.3より前のバージョンではプレーンテキストで送信)。プロトコルに対するこの基本的な変更なしでは、攻撃者は依然として、単純にネットワーク上に送信されたプレーンテキストの証明書を観察することで、サーバーのIDを特定することができます。

このベースにある暗号機には、Diffie-Hellman鍵交換アルゴリズムが使用されており、クライアントとサーバーは信頼性のないチャネルを介して共通の暗号鍵を生成することができます。したがって、暗号化されたSNI暗号鍵は、サーバーの公開鍵(実際は半静的なDiffie-Hellman共有鍵の公開された部分)とクライアント自身がその場で生成しClientHelloがサーバーに送信された後に即座に廃棄される一時的なDiffie-Hellman共有鍵の秘密部分を使用して、クライアント側で計算されます。さらに追加のデータ(ClientHelloメッセージの一部としてクライアントから送信される暗号化パラメータの一部など)まで暗号化プロセスには混在しています。

クライアントのESNI拡張機能には、実際の暗号化されたSNIビットだけでなく、クライアントの公開共有鍵と暗号化に使用した暗号スイート、およびサーバーのESNI DNSレコードのダイジェストも含まれます。一方、サーバーは自身の秘密共有鍵とクライアントの共有鍵の公開部分を使用して暗号鍵を生成し、拡張機能を復号化します。

これは過剰に複雑なプロセスに見えるかもしれませんが、これによって暗号鍵はそれ用に生成された特定のTLSセッションに暗号化により関連付けられ、複数の接続において再利用できなくなります。これにより、攻撃者が暗号化された拡張機能を単純に傍受して別セッションでサーバーに再生することで、ユーザーが接続しようとしているWebサイトのIDがマスク解除されるという攻撃(これは「カットアンドペースト」攻撃と呼ばれます)を防止します。

しかし、サーバーの秘密鍵が侵害されると、このサーバーで生成されたすべてのESNI対称鍵が危険にさらされる(オブザーバーが以前に収集した暗号化データを復号化できる)ため、Cloudflare自身のSNI暗号化実装はサーバーの鍵を毎時間ローテーションして、forward secrecy(前方秘匿性)を強化していますが、その前の数時間分の鍵の追跡を維持して、DNSのキャッシュおよびレプリケーション遅延を可能にすることで、わずかに古い鍵を持つクライアントも問題なくESNIを利用できるようにしています(ただし最終的にはすべての鍵を破棄して忘れ去ります)。

しかし、DNSで、大丈夫なのか。

賢明な読者の皆様は、単にDNS(デフォルトで暗号化されない)を使用するだけでは、暗号化されたSNIのアイデア全体が完全に無意味になることに気付かれたかもしれません。パス上のオブザーバーは、暗号化されたSNIの利用有無に関わらず、クライアント自身が送信したプレーンテキストのDNSクエリを単純に傍受することで、クライアントがどのWebサイトに接続しようとしているか、判断することができます。

しかし、DNS over TLS(DoT)やDNS over HTTPS(DoH)などのDNS機能や、これらの機能をユーザーに提供するパブリックDNSリゾルバ(Cloudflare独自の1.1.1.1など)を導入したことで、DNSクエリを暗号化して検閲やトラッカーからの読み取りから保護できるようになっています。

ただし、DoT/DoH DNSリゾルバからの応答はある程度信頼できますが(リゾルバに悪意があっても)、依然として悪意ある攻撃者は、権限を持つDNSサーバーとの通信を傍受し悪意あるデータを注入することによって、リゾルバのキャッシュに偽の情報を持たせる可能性があります。ただし、権限を持つサーバーとリゾルバの両方がDNSSEC[1]をサポートしていなければです。ちなみに、Cloudflareの権威DNSサーバーは、リゾルバに戻されたレスポンスに署名でき、リゾルバ1.1.1.1がこれを検証することができます。

IPアドレスはどうなりますか?

DNSクエリとTLS SNI拡張機能の両方をパス上の攻撃者から保護できるようになりましたが、依然として、ただ、ユーザーのデバイスから出発したトラフィック上にある宛先IPアドレスを調べるだけで、ユーザーがアクセスしているWebサイトを特定できる可能性があります。多くのCloudflareのドメインで同一のアドレスを共有しているため、Cloudflareのお客様の一部は一定レベルまで保護されていますが、これでは十分ではなく、エンドユーザーをより確実に保護するには、もう少し作業が必要です。今後も、このテーマについての、Cloudflareからの更新情報にご期待ください。

どこでサインアップできますか?

暗号化されたSNIは、ネームサーバーを使用するすべてのCloudflareゾーンで無料で有効になっていますので、CloudflareのWebサイトでの操作は不要です。ブラウザ側では、Firefoxが今週、暗号化されたSNIのサポートをFirefox Nightlyで開始する可能性があるとのことです(SNIの暗号化仕様は開発中のため、まだ安定していないことにご注意ください)。

encryptedsni.comにアクセスすると、現在のブラウジングの安全性を確認できます。セキュリティで保護されたDNSを使用していますか?リゾルバはDNSSEC署名を検証していますか?お使いのブラウザはTLS 1.3をサポートしていますか?お使いのブラウザはSNIを暗号化していますか?すべての質問に対する答えが「はい」であれば、あなたのブラウジングは覗き見から保護されていますので、安心してください。

結論

暗号化されたSNIは、TLS 1.3、DNSSEC、DoT/DoHとの組合せにより、インターネット上での監視と検閲を許している数少ない残りの穴の1つをふさぎます。監視ゼロのインターネットを達成するには、さらに多くの作業が必要ですが、私たちは(ゆっくりと)そこに近づいています。

[1]:DNSSECは、DNSリゾルバとTLDサーバーとの間のBGPルートのハイジャックによって無効にされるおそれがあることに言及することが重要です。当社は先週、RPKIに関する取り組みについて発表しましたが、DNSリゾルバとTLDにもRPKIを実装した場合、このタイプのハイジャックの実行はさらに難しくなります。

ブログ新着通知に登録すると、バースデーウィークに行われる発表に関する日々の更新メールが届きます。