在這篇 Tweet 看到有趣的 Paper How Great is the Great Firewall? Measuring China’s DNS Censorship,透過在美國及中國的實驗找出 censored domains,進而實作出可以有效避免 GFW DNS poisoning 的方式。
GFW 如何運作?
GFW 是 on-path injector,並且不會丟棄或修改由 resolver 或是 authoritative name server 的回覆。因此只有在路徑上會經過 GFW 時才會觀察到此行為,例如日本客戶端透過中國 resolver 查詢 www.google.com
。
GFW 會偽造不合理的 IPv4/IPv6 地址,並且因為 GFW 離客戶端更近,客戶端通常會更快地收到來自 GFW 的回覆並採用。舉例來說:
// 中國聯通的 DNS resolver
// 解析 Google 網站回傳的 IP 地址卻指向 Microsoft 的網站
$ dig www.google.com @202.102.224.68 +short
173.244.217.42
Paper 裡面定義了 GFW overblocking 的行為,例如 torproject.org
是 censored domain,但 mentorproject.org
卻也一併被污染。
如何知道一個域名可能被污染?
比較 client – resolver – authoritative name server 路徑經過與不經過 GFW 的回覆,例如:
// suspicious
$ dig mentorproject.org @202.102.224.68 +short
203.161.230.171
// looks fine
$ dig mentorproject.org @1.1.1.1 +short
23.236.62.147
$ dig mentorproject.org @8.8.8.8 +short
23.236.62.147
$ dig mentorproject.org @168.95.1.1 +short
23.236.62.147
但因為 public DNS resolvers 可能紀錄已經被污染了,所以更保險的作法是直接去問 authoritative name server。
所以,如何預防?
因為 GFW 不會丟棄或修改由 resolver 或是 authoritative name server 的回覆,我們只要讓客戶端等待足夠長的時間,確保所有的回覆都收到再採用即可。
例如 Paper 裡面提到在他們中國的機器上,收到第一個 DNS 回覆後(因為這邊是 delta time),只要再等上 364ms,就可以 99% 確保收到第二個真實的回覆。
這邊一個小細節是 GFW 的偽造回覆雖然通常較快,但在美國的測試有時會發現 GFW 的回覆反而比較慢(hold-on time 為負),推測與 UDP 傳輸特性有關。Paper 裡面有提出其他方式來避免誤判。
實驗時間
中國聯通跟 Cloudflare resolver 給了不同的答案:
$ dig mentorproject.org @202.102.224.68 +short
64.33.88.161
$ dig mentorproject.org @1.1.1.1 +short
23.236.62.147
第三行可以看到 resolver 202.102.224.68 這邊確實給了第兩個回覆 XD
$ sudo tshark -i any -f 'port 53' -n
// 中國聯通
1 0.000000000 172.31.37.101 -> 202.102.224.68 DNS 90 Standard query 0x89c6 A mentorproject.org
2 0.154465529 202.102.224.68 -> 172.31.37.101 DNS 95 Standard query response 0x89c6 A 64.33.88.161
3 0.154511590 202.102.224.68 -> 172.31.37.101 DNS 95 Standard query response 0x89c6 A 203.161.230.171
// Cloudflare
4 12.710885026 172.31.37.101 -> 1.1.1.1 DNS 90 Standard query 0x9e3d A mentorproject.org
5 12.886210394 1.1.1.1 -> 172.31.37.101 DNS 106 Standard query response 0x9e3d A 23.236.62.147