首先,我們要知道 GFW 是如何封鎖我們的流量的#
-
IP 黑洞:目前無解,但僅對部分服務黑洞,如谷歌系(谷歌、推特、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
字段,然後 GFW 向客戶端發送一個RST
報文,即要求重置客戶端連接。在客戶端側,則會收到ERR_CONNECTION_RESET
即:連接已重置。用戶無法訪問網頁。
繼續,嘗試發送空 Server Name
報文#
成功訪問。在 WireShark 中並未發現 Server Name
字段
殺手鐧,tcpioneer#
它通過魔改 TCP 數據包使得 GFW 無法檢測,並且 WireShark 也無法抓取到Client Hello
報文,但是仍然能建立連接,即服務端發送Server Hello