關於 DNS 泄露及其相關誤解的説明

儘量澄清 DNS 泄露的常見誤解,解析系統代理與 TUN 透明代理模式下泄露的成因,並給出透過最佳化分流規則和 fake-ip 模式徹底規避泄露的實用方案。

點進這篇文章的人想必基本都對 DNS 泄露這一概念有所耳聞了,其中也不乏談 DNS 泄露色變者,由於評論區和 Issue 裏提出相關問題的人已經有數位,鄙人這次寫一篇説明,儘可能將這個問題講清楚,澄清一些大家對這個概念可能的誤解,也為各位編寫自己的代理配置提供一個蔘考。

這個概念已經被一些 VPN 廠商和一大堆 YouTuber 講爛了,基本的意思是:當你在代理時,電腦卻透過本地網絡向本地 DNS 請求你正在訪問的網址,使得運營商可以依據你的 DNS 請求記錄得知你的瀏覽記錄。

搞清楚需求

首先需要想明白的是,我們煞費苦心地防止 DNS 泄露究竟是為了什麼——大家的第一反應可能都是:「那還用説!肯定是為了不讓審查者看到我們透過代理訪問了哪些網站啊!」

其實這個説法並不完全準確,具體還得看情況。不妨想一想:讓審查者知道你在刷抖音、聊微信會有什麼實質性的危害嗎?恐怕沒有。但如果讓審查者發現你在訪問維基百科、瀏覽 X(推特)或者其他帶有明確政治傾向的敏感內容,那問題就有點大了。防止 DNS 泄露的目的,從來不是為了讓你在所謂的「DNS 泄露測試」網站上拿到一個全綠的滿分,也不是為了隱藏你使用國內常用服務的事實,而是為了不讓審查者知道你在訪問那些被封禁、被視為敏感的網站和服務。

對於生活在牆內的我們來説,區分什麼是敏感內容其實非常簡單:直接蔘考 GFWList1 即可——能讓 GFW 專門將其重點關照的,自然就是敏感內容。

那些 DNS 泄露測試的網站,測試用的隨機域名甚至連 GFWList 的邊都沾不上,本身就毫無敏感性可言。對於一些經過最佳化的正常代理配置來説,這類域名連看都不想多看一眼,通常會直接被略過並扔給最後的兜底規則(比如 MATCH, DIRECT)去處理,這個過程自然而然地觸發了本地 DNS 解析。於是,測試網站便如獲至寶般地亮起紅燈,警告你「存在 DNS 泄露」。但明白機制的我們自然清楚,很多時候這種所謂的泄露完全是無關痛癢的,只要配置得當,你真正需要保護的敏感訪問記錄,早就匹配到前面的分流規則被安全地送進加密隧道了。

更有甚者,諸如 Surfshark、ExpressVPN 這類海外商業 VPN 廠商,以及一眾跟着恰飯的無良 YouTuber,成天拿這種毫無實際意義的測試結果製造隱私焦慮。可笑的是,這些傳統的商業 VPN 客户端往往連最基礎的域名分流規則功能都不具備,全靠粗暴的一把梭將所有網絡請求強行塞進虛擬網絡卡。而更諷刺的是,即便是這種簡單粗暴的全域性代理,他們過去還曾因為自身客户端軟件的缺陷,真真切切地導致過 DNS 泄露問題。所以,與其聽信這些販賣焦慮的恰飯營銷,不如自己弄懂代理軟件的運作原理。

出現泄露的環節

其實現在主流的代理軟件都比較成熟,配置得當完全不需要擔心 DNS 泄露的問題。問題出就出在很多配置根本就不得當。接下來我將會簡要地解釋代理軟件在系統代理模式和透明代理(虛擬網絡卡)模式下可能出現 DNS 泄露的環節。

代理軟件本身

在使用系統代理的情況下(假設代理地址是socks5://127.0.0.1:78902)用瀏覽器訪問https://www.example.com,會經歷如下的請求過程:

  • 第一步:瀏覽器會把網絡請求打包傳送給socks5://127.0.0.1:7890
  • 第二步:代理軟件收到請求後根據配置的分流規則匹配節點
  • 第三步:代理軟件根據匹配結果向節點轉發整個網絡請求

在整個發起請求的過程中,瀏覽器將網絡請求打包交給代理,不會向本地 DNS 發出請求,這一環節不會產生 DNS 泄露;代理軟件將網絡請求轉發給伺服器,整個過程加密,也不會產生 DNS 泄露;真正產生 DNS 泄露的環節,是根據分流規則匹配的過程。

向本地 DNS 發起域名查詢這件事情本身並不一定是壞事,但配置不當的分流規則會讓代理軟件在拿到域名後過早地向本地 DNS 發起查詢,導致泄露不應泄露的隱私資訊。假設在極端情況下,蓋世太保從運營商調取所有人的 DNS 查詢記錄,凡是查詢過域名包含 GFW 封鎖列表中的專案者都拉出去槍斃,在這種情況下,為了保全自身,我們需要恰當地配置分流規則。

以使用廣泛的 Mihomo 核心為例,在作為客户端開啓系統代理模式、使用 Chrome 進行到前文所述的第二步時,核心已知的資訊有:

  • 主機3example.com
  • 目標埠:443
  • 網絡協議:TCP
  • 發起請求的程序的名稱和具體路徑:C:\Application\chrome.exe
  • 入站 IP:127.0.0.1
  • 入站名稱:DEFAULT-MIXED
  • 入站埠:隨機的高位埠

核心不會進行多餘的 DNS 請求,根據已知的資訊,核心可以在不發起 DNS 解析的情況下,匹配所有基於域名、埠、程序名稱以及網絡協議匹配的路由規則:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
rules:
  # 基於域名的匹配規則
  - DOMAIN,ad.com,REJECT
  - DOMAIN-SUFFIX,google.com,auto
  - DOMAIN-KEYWORD,google,auto
  - DOMAIN-WILDCARD,*.google.com,auto
  - DOMAIN-REGEX,^abc.*com,PROXY
  - GEOSITE,youtube,PROXY
  # 基於埠的匹配規則
  - DST-PORT,80,DIRECT
  - SRC-PORT,7777,DIRECT
  # 基於程序名稱的匹配規則
  - PROCESS-PATH,/usr/bin/wget,PROXY
  - PROCESS-PATH,C:\Application\chrome.exe,PROXY
  - PROCESS-NAME,curl,PROXY
  - PROCESS-NAME,chrome.exe,PROXY
  # 基於網絡協議的匹配規則
  - NETWORK,UDP,REJECT
  # 不依賴任何資訊的匹配規則
  - MATCH,DIRECT

因此,上述這些種類的規則不會產生 DNS 泄露,因為核心匹配它們的時候根本沒必要發起 DNS 解析。

對於剩下種類的規則,需要在第二步獲知目標 IP 資訊才能讓匹配進行下去:

1
2
3
4
5
rules:
  - GEOIP,cn,DIRECT
  - IP-CIDR,127.0.0.0/8,DIRECT
  - IP-SUFFIX,8.8.8.8/24,PROXY
  - IP-ASN,13335,DIRECT

在預設情況下,為了確保匹配的準確性,進行到第二步時,核心不知道目標 IP,只知道目標主機地址www.example.com,此時核心不得不對www.example.com的 IP 地址進行查詢,這也就造成了 DNS 泄露。如果在規則的末尾加上no-resolve4,則匹配到基於 IP 的規則時會直接跳過,這就使得no-resolve很適合用來分流 Telegram 等軟件的裸 IP 請求。

透明代理的問題(TUN 模式5

透明代理顧名思義即被代理的系統/軟件感知不到自己被代理了的代理方式。這種方式非常省事,TUN 模式一開,所有軟件通通都能用,無須繁瑣的逐一配置不遵循系統代理的軟件。代價就是這種省事本身——目標系統/軟件都不知道自己被代理了,他們在正常網絡上該有的行為都會照常進行,其中自然也包括 DNS 解析,可是目標系統/軟件並不知道自己被代理了,他們想要和遠端建立連線,總得要先拿到一個 IP 才行吧。為了解決這個問題,以 Mihomo 為例,有兩種 DNS 劫持模式,redir-hostfake-ip

redir-host 模式:

fake-ip 模式:

其中redir-host比較老實,既然目標系統/軟件發起了 DNS 查詢,那就老老實實透過上游 DNS 去查,把查詢到的真實的 IP 返回給目標系統/軟件。由於這種模式下系統必定會發生一次真實的 DNS 解析請求定址過程,存在着先天的結構性缺陷,不可避免地會造成 DNS 泄露。原來的 Clash 核心在後續的版本更新中乾脆直接砍掉了 redir-host 模式。

不過,繼承了 Clash Meta 核心的 Mihomo 核心選擇了將其保留下來,並且加入了sniffer6對其進行增強。在redir-host模式下,sniffer依靠嗅探資料包中的特徵(比如從 TLS 的 SNI 欄位7)嘗試將被解析成裸 IP 的流量恢復成連線域名,再用這個域名走一遍分流規則的匹配,補齊了redir-host模式在分流上的諸多短板。但需要特別注意:sniffer 解決的是分流準確性的問題,並不能消除 DNS 泄露本身——DNS 查詢請求在 sniffer 介入之前就已經發出去了,運營商該記錄的早就記錄了。

但這裏需要提醒:如果你在透明代理環境下仍然堅持使用redir-host模式,就必須在配置一套無污染的 DNS,具體的例子可以蔘考我的另一篇文章,否則你的 DNS 訪問記錄依然會泄露。

相對而言,fake-ip模式則採用了截然不同的解決思路,不僅完美規避了透明代理環境下的 DNS 泄露問題,甚至還能順帶提升瀏覽器的網頁響應速度。

如何規避 DNS 泄露

最佳化餵給代理軟件的分流規則

還是以 Mihomo 核心為例,規則的匹配是從上到下順序進行的,核心每收到一個請求都會按順序從上到下一條一條地匹配,直到匹配到目標規則為止。這也就意味着如果一個域名已經被第一條規則匹配,之後的第二、第三、乃至第一千萬條規則的匹配流程都不會觸發。

基於這一點,我們編寫規則時應當要遵循「域名規則在前,IP規則在後」的總原則,即使是針對某個特定服務的規則集,也要為其中的 IP 規則加入no-resolve標記,一個典型的例子如下:

1
2
3
4
5
6
7
DOMAIN-SUFFIX,e-hentai.org
DOMAIN-SUFFIX,ehgt.org
DOMAIN-SUFFIX,ehwiki.org
DOMAIN-SUFFIX,exhentai.org
DOMAIN-SUFFIX,hath.network
DOMAIN-SUFFIX,hentaiverse.org
IP-CIDR,178.175.128.0/21,no-resolve

當使用 GeoSite 和 GeoIP 數據庫時,也應當為靠前的 IP 規則新增no-resolve標記。

1
2
3
4
5
6
rules:
  - GEOSITE,telegram,Telegram
  - GEOIP,telegram,Telegram,no-resolve
  - GEOSITE,gfw,Proxy
  - GEOIP,cn,DIRECT
  - Match,Proxy

就以上面的配置規則為例,當我們的裝置發起不同型別的網絡請求時,Mihomo 核心會按照自上而下的順序進行規則匹配。具體流程可以透過下面的圖表來梳理:

從上述流程圖中我們可以清晰地看到規則順序和 no-resolve 屬性的作用。當我們訪問 Telegram 服務時,由於命中了靠前的 GEOSITE 或帶有 no-resolveGEOIP 規則,請求被直接路由至代理,完全避免了在這一環節產生 DNS 解析。

同理,當我們訪問其他任何在 GFW 列表上的網站時,會在匹配到 GEOIP,cn,DIRECT 這條不得不觸發本地 DNS 解析的規則之前,就率先匹配到了 GEOSITE,gfw,Proxy 規則。此時代理軟件直接將請求轉發至節點,後續基於 IP 的規則因為不再執行,相關的 DNS 解析請求也就被成功避免,杜絕了因為 DNS 請求導致敏感瀏覽記錄泄露的可能性,審查者再也不會知道你在訪問敏感的網站和服務了。

用 Fake-IP 規避透明代理問題

相比最佳化分流規則,fake-ip 模式則從根源上解決了透明代理下的 DNS 泄露問題,不僅完美規避了泄露風險,甚至還能順帶提升瀏覽器的網頁響應速度。

原理非常巧妙:當目標軟件發起 DNS 查詢時,代理軟件並不會傻乎乎地去本地或遠端上游查詢真實 IP,而是直接在本地瞬間返回一個假的內網保留 IP(例如198.18.0.28)。目標軟件拿到這個假 IP 後信以為真,緊接着就會拿着這個假 IP 嘗試建立連線。

而在代理軟件這裏,它只需要攔截所有發往自己簽發過的這些假 IP 的請求即可。由於代理軟件內部維護了一張詳細的「假 IP 對應真實域名」的對映表,所以即便目標軟件發來的是往假 IP 傳送的包,代理軟件依然心知肚明你其實想訪問的是什麼域名。於是,代理軟件直接提取出原始域名,將網絡請求順着加密代理隧道發往遠端節點去處理。

在整個fake-ip模式的精妙配合下,你的裝置對外不僅沒有泄露隱私的 DNS 請求,甚至可以説針對這些由代理軟件接管的流量根本就沒有向外部發起過常規的 DNS 查詢,審查者自然無從得知你要訪問何處。同時由於免去了本地苦等 DNS 真實響應的時間,還能順帶大幅度降低網頁訪問的首位元組載入延遲(TTFB9),一石二鳥。

太長不想讀(小結)

DNS 泄露本身並不可怕,可怕的是不明就裏地被焦慮營銷牽着鼻子走。理解了機制之後,應對思路其實很清晰:

  • 系統代理模式:遵循「域名規則在前,IP 規則在後」的原則,為所有 IP 類規則加上 no-resolve,敏感域名在觸發 DNS 解析之前就已經被分流走了。
  • TUN 透明代理模式:優先選用 fake-ip,從根源上杜絕 DNS 查詢外泄,同時還能獲得更低的 TTFB。如果堅持使用 redir-host,必須搭配無污染的上游 DNS,且要清楚 sniffer 只能改善分流準確性,無法阻止 DNS 請求本身的泄露。
  • 不要迷信泄露測試網站:測試用的隨機域名根本不在 GFW 封鎖列表內,觸發本地解析是正常且無害的行為,綠燈與否不是衡量配置質量的標準。

  1. 被中國大陸防火長城(Great Firewall, GFW)封鎖的域名列表。 ↩︎

  2. SOCKS5 是一種網絡代理協議(RFC 1928),工作在會話層,支援 TCP 和 UDP 轉發,且允許客户端將域名直接傳遞給代理伺服器解析,而非在本地解析後再連線——這正是它在防止 DNS 泄露方面優於普通 HTTP 代理(非 CONNECT 隧道模式)的關鍵特性。 ↩︎

  3. 可以理解為域名。 ↩︎

  4. no-resolve 是附加在 IP 類規則末尾的標記,作用是告訴核心:當流量的目標是域名而非 IP 時,跳過此規則,不要為了匹配它而主動發起 DNS 解析。但如果流量本身就是直接連線 IP(如 Telegram 客户端直連伺服器 IP),則該規則仍然會正常蔘與匹配。 ↩︎

  5. 也就是我們所説的虛擬網絡卡模式 ↩︎

  6. 流量嗅探(Sniffer)是指代理軟件透過檢查資料包的協議特徵來還原目標域名的技術。例如,HTTPS 連線在握手階段會以明文傳送目標域名(即 SNI),HTTP 請求頭中也包含 Host 欄位,代理軟件可以從這些特徵中提取出真實的目標域名。 ↩︎

  7. Server Name Indication,TLS 協議的擴充套件欄位。由於同一 IP 上可能託管多個 HTTPS 站點,客户端在 TLS 握手的 ClientHello 階段需要以明文告知伺服器自己要訪問哪個域名,以便伺服器返回正確的證書。這也是為什麼即使使用了 HTTPS,中間人仍然能看到你訪問的域名(但看不到具體路徑和內容)。 ↩︎

  8. Mihomo 預設使用 198.18.0.0/15 地址段分配假 IP。該地址段由 IANA 在 RFC 2544 中保留,專門用於網絡裝置基準測試,不會出現在正常的網際網絡路由表中,因此不會與任何真實的公網地址衝突。整個 /15 段可提供約 131,072 個地址供對映使用。 ↩︎

  9. Time To First Byte,即從客户端發出請求到收到伺服器響應第一個位元組所經過的時間。在傳統模式下,瀏覽器需要先等待 DNS 解析完成(通常耗時 20-120ms)才能發起 TCP 連線;而 fake-ip 模式下 DNS 響應幾乎是瞬時的(<1ms),因此能顯著縮短整體的頁面載入時間。 ↩︎

採用 CC BY-NC-SA 4.0 協議進行許可
上次改過於 2026 年 5 月 18 日 12:16 +0800