DNS 洩漏是什麼:代理開著,查詢卻走了本機
網域解析是上網的第一步:瀏覽器拿到網域後,要先把網域翻譯成 IP 位址,這一步由 DNS 完成。所謂 DNS 洩漏,就是代理已經顯示「已連線」,但解析請求仍然從你的真實網路直接發出,落在電信業者或路由器的 DNS 伺服器上。後果有兩層:一是隱私,你造訪過哪些網域、什麼時間造訪,本機網路提供方看得一清二楚;二是可用性,本機 DNS 回傳被污染的結果時,瀏覽器會拿到錯誤 IP,典型症狀就是「Clash 顯示已連線,網頁卻打不開,或打開的是錯的內容」。
開了代理為什麼還會漏?常見原因有四個:
- 系統代理模式只接管瀏覽器等應用程式的網頁請求,不會改動系統 DNS 設定,網卡上由電信業者自動下發的 DNS 照常運作。
- Clash 的內建 DNS 沒有啟用,或者啟用了但監聽位址沒有涵蓋系統實際使用的解析通道。
- 瀏覽器自帶「安全 DNS」(DoH)功能,繞過系統解析器直連 DoH 伺服器,檢測結果也會因此失真。
- IPv6 連線沒被接管,AAAA 查詢順著 IPv6 的 DNS 伺服器溜走——只改 IPv4 的 DNS 堵不住這條路。
第一步:先檢測,確認有沒有漏
修復之前先取證。按下面的順序做一遍,確認洩漏是否存在、漏在哪條連線上。
- 開啟 Clash 用戶端,確認代理已連線,記下目前模式(規則、全域或直連)。
- 暫時關閉瀏覽器的安全 DNS:Chrome 在「設定 → 隱私權和安全性 → 安全性 → 使用安全 DNS」裡關閉;Edge 路徑相同;Firefox 在「設定 → 網路設定」裡取消「啟用 HTTPS 上的 DNS」。不關的話,檢測反映的是瀏覽器 DoH 的走向,而不是系統連線。
- 打開任意一個公開的 DNS 洩漏檢測頁(如 dnsleaktest、ipleak、browserleaks 的 DNS 檢測),先跑標準測試,再跑擴充測試。
- 對照結果判斷:清單裡出現你所在地區的電信業者 DNS 節點(如中華電信、台灣大哥大、遠傳等),說明存在洩漏;只出現 Cloudflare、Google 等公共 DNS 或代理出口機房的解析器,說明沒有洩漏。
- 系統代理模式和 TUN 模式各測一次。兩種模式的接管範圍不同,結果經常不一樣。
檢測前先清一次系統 DNS 快取,避免舊快取把結果帶偏。Windows 用管理員權限執行 ipconfig /flushdns;macOS 執行 sudo dscacheutil -flushcache,再執行 sudo killall -HUP mDNSResponder。
一個容易誤判的點:如果你的 nameserver 裡設定了公共 DNS(如 Google 8.8.8.8),檢測站可能顯示對應的節點。這代表查詢從真實網路直達該服務商,嚴格來說真實 IP 暴露給了這家 DNS 服務商,但不算電信業者層面的洩漏。要不要追究這一層,取決於你要「常規分流」還是「嚴格防洩漏」,下文兩套寫法都會給出。
修復一:把 nameserver 寫對
Clash 的 DNS 行為由設定檔裡的 dns 段落控制。先逐欄位看清楚,再動手改。
enable:內建 DNS 總開關,防洩漏必須為true。listen:監聽位址與埠號,寫0.0.0.0:53表示接管發到本機 53 埠的查詢。enhanced-mode:fake-ip或redir-host。fake-ip 回傳 198.18.0.1/16 段的虛擬位址,Clash 接管連線時在內部反查網域,解析全程不出 Clash,是防洩漏最徹底的模式;redir-host 則由用戶端先解析出真實 IP 再發起連線。nameserver:預設上游,負責直連網域的解析。建議用帶 IP 的 DoH 位址,如https://223.5.5.5/dns-query、https://119.29.29.29/dns-query。fallback:命中境外網域時使用的上游,通常填https://1.1.1.1/dns-query、https://8.8.8.8/dns-query,查詢經代理發出。default-nameserver:用來解析上面那些 DoH 伺服器自身網域的「引導 DNS」,填純 IP(如 223.5.5.5、119.29.29.29),避免「解析 DNS 伺服器的網域本身又需要 DNS」的死循環。proxy-server-nameserver(mihomo):解析節點伺服器網域專用,填可信的 DoH,防止節點網域被污染導致連不上節點。
常規分流的一套完整範例:
dns:
enable: true
listen: 0.0.0.0:53
enhanced-mode: fake-ip
fake-ip-range: 198.18.0.1/16
default-nameserver:
- 223.5.5.5
- 119.29.29.29
nameserver:
- https://223.5.5.5/dns-query
- https://119.29.29.29/dns-query
fallback:
- https://1.1.1.1/dns-query
- https://8.8.8.8/dns-query
proxy-server-nameserver:
- https://223.5.5.5/dns-query
嚴格防洩漏的寫法是去掉 nameserver 裡境內的上游,全部走 fallback 經代理解析,代價是本地站點首次解析略慢。折衷方案是用 nameserver-policy 按網域分流:
nameserver-policy:
"geosite:cn":
- https://223.5.5.5/dns-query
"geosite:geolocation-!cn":
- https://1.1.1.1/dns-query
訂閱檔通常自帶 dns 段落,直接改訂閱會在下次更新時被覆蓋。建議做法:先備份原設定,再用用戶端的設定覆寫功能(Clash Verge Rev 的「全域擴充設定」、Clash Nyanpasu 的 Merge 等)注入 dns 段落,這樣更新訂閱後設定仍然生效。
修復二:讓查詢真的走到 Clash(劫持監聽)
設定寫得再對,系統不把查詢送給 Clash 也是白搭。三種接管方式,按省心程度排序。
方式一:TUN 模式(推薦)
mihomo(Clash Meta)核心的 TUN 模式會建一張虛擬網卡,接管整台裝置全部流量,包括 UDP 53 的 DNS 查詢;dns-hijack 會把發往任意位址 53 埠的查詢劫持進內建 DNS。Clash Verge Rev、Clash Nyanpasu、FlClash 等用戶端在設定裡可一鍵開啟,開啟後系統 DNS 填什麼都不再重要。
tun:
enable: true
stack: mixed
dns-hijack:
- any:53
- tcp://any:53
auto-route: true
auto-detect-interface: true
方式二:手動改系統 DNS
把網卡的 IPv4 DNS 改為 127.0.0.1,IPv6 DNS 改為 ::1(或直接停用 IPv6),配合 dns.listen 監聽 53 埠。注意 Windows 的網際網路連線共享、部分虛擬機的網卡服務會佔用 53 埠,導致 Clash 啟動時報錯。這時要麼找出佔用方並停掉,要麼直接改用 TUN 模式——不要硬改監聽埠,Windows 的網卡 DNS 設定不支援指定 53 以外的埠。
方式三:只靠系統代理 + redir-host
這是接管最弱的一種:只有走代理的應用程式流量被接管,系統裡其他行程的 DNS 查詢仍走原路。如果暫時不能開 TUN,至少確認瀏覽器 DoH 已關閉,並接受「只管得住瀏覽器」的邊界。
修復三:規則兜底與複檢清單
最後一層是規則。DNS 設定決定「怎麼解析」,規則決定「漏網的查詢流量往哪走」。
- 確認規則末尾的
MATCH指向代理策略群組而不是 DIRECT,未命中任何規則的流量(包括應用程式自帶的 DoH 請求)才不會直連出去。 - 不要給 53 埠加 DIRECT 規則;TUN 模式下 dns-hijack 已經接管,多餘規則只會添亂。
- 應用程式內建 DoH 是最常見的漏網通道,可以把
dns.google、cloudflare-dns.com、mozilla.cloudflare-dns.com等公共 DoH 網域指向 REJECT,逼應用程式回退到系統解析,交給 Clash 統一處理。
全部改完後,按這份清單複檢:
- 重新跑一遍洩漏檢測,確認結果裡只剩境外解析器。
- 換一個網路環境(比如從家用寬頻切到手機熱點)再測一次,排除單一連線的偶然性。
- 手動更新一次訂閱,確認 dns 覆寫仍然生效,然後再測一遍。
- 接下來幾天留意有沒有網站打不開:個別服務與 fake-ip 不相容,把對應網域加進
fake-ip-filter即可,不必為此退回 redir-host。
DNS 洩漏不是一次性問題:換用戶端、換網路、訂閱更新都可能把設定打回原形。把「改完就測、更新後再測」變成習慣,防洩漏才算真正完成。