摘要#
インターネット技術の急速な発展に伴い、情報伝達の速度と範囲が大幅に向上しました。ソーシャルメディア、ブログ、動画プラットフォームなどの新しいメディアは、個人や団体が意見や情報を簡単に共有できるようにしています。このような情報の自由な流通は、公共の参加、社会運動、民主化の進展を促進しました。しかし、ネットワークのオープン性は情報管理の課題ももたらしました。多くの国や地域の政府は、国家安全保障、社会の安定、政治的管理を維持するために、徐々にネットワークコンテンツの検閲を強化しています。この検閲制度は、特定のウェブサイトのブロック、ソーシャルメディアコンテンツの監視、言論の制限として現れます。
本稿では、2 つの一般的なブロック技術の原理を説明し、検出の考え方を提供します:DNS キャッシュポイズニングとSNI ブロッキング。さらに、これら 2 つのブロック方式の影響を受けているかどうかをより簡単に検出するための PoC(概念実証)ツールも提供します。提供される方法は広範なテストを受けていないため、これらの検閲技術を使用している国や地域では有効である可能性がありますが、他の国や地域では正常に機能しない可能性があります。
本稿では、ブロック技術を回避する方法や、他の未提及のブロックおよび検閲手段については議論しません。DNS キャッシュポイズニングに関する議論は、UDP ベースの DNS プロトコルに限定され、TCP ベースの DNS は実験してみてください。
本稿の検出方法は、実験者が追加のサーバーを展開する必要がない原理検出の方法です。
名詞説明#
ドメイン名(Domain Name): ドメイン名は、インターネット上の特定の場所やリソースを識別するための覚えやすい文字列です。ドメイン名の存在は、IP アドレスが覚えにくい問題を解決するためのものです。例えば:www.fubao.dev はドメイン名です。
DNS(Domain Name System):ドメイン名システム。ターゲットドメインへのアクセスは最終的に IP を使用します。このシステムは電話帳に相当し、名前から電話番号を調べることができ、ドメイン名システムを通じてドメイン名から IP アドレスを調べることができます。例えば、www.fubao.dev に対応する IP アドレスは 34.41.105.151 です。
SNI(Server Name Indication):サーバー名指示(SNI)は TLS プロトコルの拡張です。ハンドシェイクプロセスが始まると、クライアントは接続するサーバーにターゲットホスト名を通知します。これにより、サーバーは同じ IP アドレスと TCP ポート上で複数の証明書を提示でき、同じ IP アドレスで複数の安全(HTTPS)サイトや他の TLS ベースのサービスを提供できるようになります。すべてのサイトが同じ証明書を使用する必要はありません。
簡単に言えば、1 つの IP アドレスに複数のドメイン名を展開できます。HTTPS でアクセスする際、証明書の合法性を確認する必要がある場合、クライアントは SNI を通じてサーバーにどのドメインの証明書を提供すべきかを通知し、ハンドシェイクプロセスがスムーズに進むようにします。サーバーは HTTP 層の Host 情報にのみ関心を持つかもしれませんが、互換性のために通常はハンドシェイク時に SNI 情報を送信します。
SNI 情報は 2 種類に分けられます:1 つは平文の SNI 情報で、最も一般的で互換性が高い方法です。もう 1 つは暗号化された SNI(ESNI)ですが、本稿では ESNI については議論しません。
DPI(Deep Packet Inspection):深層パケット検査技術は、ネットワークデータパケットフィルタリング技術であり、検出ポイントを通過するデータパケットの内容を分析することを目的としています。これにはデータ部分や可能なヘッダーが含まれます。この技術は、規格に準拠しないプロトコル、ウイルス、スパム、侵入行為を識別するために使用されます。事前に設定された基準に基づいて、DPI はデータパケットが通過を許可されるか、他の目的地にルーティングされるかを決定できます。さらに、DPI はネットワークトラフィックの統計データを収集し、監視やターゲット広告配信に使用されます。例えば、いくつかの DPI システムでは、SNI 情報や DNS クエリのターゲット情報が収集および注目される情報です。
通常、ネットワークブロック技術において、DPI システムは具体的なブロックアクションを実行できるサービスと相互作用する必要があります。大規模な DPI システムとその実行ユニットは、正常なネットワークに影響を与えないように、通常はミラーリングトラフィックとバイパス展開の方法を採用し、特定のパケットを注入することで通信を阻止します。このようなシステムは一般にパケットインジェクターと呼ばれます。
DNS 汚染:DPI がブロックドメインへのクエリを検出した後、パケットインジェクターを介して DNS 応答を強制的に返します。DPI デバイスはクエリ元に近いため、注入されたパケットが最初に到達します。特定の高度な DPI およびアクションシステムでは、正しい応答パケットが後続で到達するのを破棄することもあります。
SNI ブロッキング:DPI がターゲットドメインへの HTTPS リクエストにブロックすべきドメインの SNI 情報が含まれていることを検出した場合、TCP RST パケットを注入してリクエスト元とターゲットの接続を切断します。一部の専門的な DPI システムでは、この RST ブロックパケットはほとんど双方向であり、クライアントに対してはサーバーが接続を切断したことを通知し、サーバーに対してはクライアントが接続を切断したことを通知します。これにより、RST パケットを単純に破棄してブロックを回避する手段が無効になります。
検閲の残留:一部の DPI システムでは、アプリケーション層や他の層に基づくブロックロジックが連動する可能性があります。例えば、特定の IP と SNI を使用してターゲットサイトにアクセスした場合、次回この IP に接続すると、ハンドシェイクパケットが破棄される可能性があります。通常、このようなパケットを破棄するシステムはバイパス展開されていません。検閲の残留は、いくつかの DPI システムの動作方式を研究するための便利さを提供しますが、いくつかの不便ももたらします。本稿では言及しますが、大規模な議論は行いません。
渔:DPI とパケットインジェクターの一般的な弱点#
大規模データシナリオにおける DPI とパケットインジェクションシステムにとって、スループットと処理能力は重要な指標です。コストと効果のバランスを取るために、DPI システムとパケットインジェクターは通常、以下の欠陥を持っています:
-
ターゲットプロトコルスタックの実装は通常軽量で、完全なプロトコルスタックの最小限の利用可能なサブセットであり、通常は RFC 実装を完全には満たしません。これはコストの考慮からです。例えば、TCP 用の DPI システムは TCP パケットのチェックサム値が合法であるかどうかを検証しません;
-
DPI とパケットインジェクターはバイパス展開されているため、彼らを通過するパケットしか見ることができず、収集される情報は不完全です。例えば、DPI システムはターゲットまでのホップ数を知ることができず、簡単に欺かれます。例えば、DPI とパケットインジェクターを通過できる TTL 値のパケットを送信すると、DPI とパケットインジェクターも動作を開始します。多くの DPI とパケットインジェクターはターゲットまでのホップ数を仮定しますが、この仮定は巧妙に構成された TTL 値のパケットをカバーすることはできません。
-
DPI は TCP などのストリーミングプロトコルのデータストリームを再構成することができますが、待機時間の制限があります。
-
その他
DNS 汚染の識別#
通常、DNS 汚染の識別方法は正しい結果と比較することですが、この方法は一般性がありません。ECS や CDN 技術の存在により、DNS サーバーはリクエスト元に最も近いサーバーの IP 情報を返すことがあり、最適なアクセス体験を保証します。ターゲットサービスは異なる地域や国で異なるプロバイダーのサービスを使用することがあるため、この検出方法は大量の偽陽性を引き起こす可能性があります。
DPI システムの一般的な弱点を考慮すると、DPI システムはリクエストが合法であるかどうかに関心を持たないため、次のような不正な DNS クエリを構築できます。このクエリリクエストでは、DNS サーバーに対して、クエリリクエストにクエリ結果が含まれていることを通知します。
正常な DNS クエリは以下の図のようになります:
私たちが構築した不正なクエリは、図で囲まれた部分を変更しました:
不正なクエリが強制応答されなかった場合(つまり、汚染されていない場合)、私たちが見る結果は DNS サーバーのエラーメッセージです:
不正なクエリが強制応答された場合(つまり、DNS が汚染された場合)、私たちが見る応答は正常な応答結果です:
PoC: dns_pollution.py
使用例:
SNI ブロッキングの検出#
SNI ブロッキングの検出では、DNS 汚染の影響を排除する必要があります。DPI システムが通常使用する情報は限られているため、確実にアクセスできる出境 IP アドレスを使用して、SNI を含むリクエストを送信し、RST パケットを受信するかどうかを確認します。HTTPS ハンドシェイクを完全に完了する必要はありません。
PoC:sni_block.py
使用例:
まとめ#
以上の考え方に基づいて、検出方法には多くのバリエーションがあります。皆さんが楽しんでいただけることを願っています。