まず、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
を送信します。