まず、GFW がどのように私たちのトラフィックをブロックしているのかを理解する必要があります#
-
IP ブラックホール:現在は解決策がなく、一部のサービスに対してのみブラックホール(Google 系:Google、Twitter、YouTube など)
-
DNS 汚染:ドメイン名に対して偽の IP を返す。hosts ファイルを使用してドメイン名に対応する IP を強制指定するか、暗号化された DNS(DoH、DNS 署名など)を使用する
-
HTTP ハイジャック:トラフィックが暗号化されていないため、GFW は天然の中間者として直接改ざんすることができます(例:404 ページへのリダイレクト、詐欺防止ページへのハイジャックなど)。HTTPS 接続を使用することで回避できますが、SNI ブロックに遭遇する可能性があります
-
SNI ブロック:クライアントとサーバーが暗号化接続を確立する前に、クライアントは
Client Hello
メッセージを送信しますが、このメッセージは平文であり、一般的にserver_name
を含んでいます。GFW は、どのウェブサイトにアクセスしようとしているかを知ることができ、ホワイトリストにないドメイン名(例:discord.com)をブロックします。server_name
は実際には拡張機能であり、必ず送信する必要はないため、SNI ブロックを回避するために送信しないことも可能です
では、GFW が異なるウェブサイトに対してどのようにブロックしているかを分析してみましょう#
WireShark を使用してパケットキャプチャを行います
-
まず
www.baidu.com
にアクセスしてみます。これは GFW にブロックされていないドメイン名です-
まず ping を試みます
-
IP を取得:
2408:873d:22:18ac:0:ff:b021:1393
-
Hosts を使用して強制的にバインド
-
WireShark でパケットキャプチャを行うと、クライアントが送信した
Client Hello
にServer Name
フィールドが明確に表示され、正常にServer Hello
を受信し、その後両者が通信を開始します
-
ブラウザを確認すると、ウェブサイトに正常にアクセスできます
-
-
次に
discord.com
にアクセスしてみましょう-
まず ping を試みると、ドメイン名と解決された IP の両方が通じないことがわかります
-
この時、
itdog.cn
を使用して v4 ping を試み、解決されたドメイン名に対して順次 ping を行います
-
最初の IP が通じることがわかります
-
Hosts を強制的にバインドし、パケットキャプチャを試みます
-
- 強制 Hosts バインド後、クライアントが
Client Hello
を送信すると、GFW はServer Name
フィールドを検出し、クライアントにRST
メッセージを送信します。これはクライアント接続のリセットを要求するものです。クライアント側ではERR_CONNECTION_RESET
が表示され、接続がリセットされたことを示します。ユーザーはウェブページにアクセスできません。
続いて、空の Server Name
メッセージを送信してみます#
成功しました。WireShark では Server Name
フィールドが見つかりませんでした
切り札、tcpioneer#
それは TCP パケットを魔改造することで GFW が検出できないようにし、WireShark でも Client Hello
メッセージをキャプチャできませんが、接続を確立することができ、サーバーが Server Hello
を送信します