DNS 是網路請求的第一個環節,也是代理場景中最容易出問題的地方。Clash 內建了一套完整的 DNS 處理系統,理解它的工作原理,是排查「明明開了代理但某些網站還是慢」「DNS 洩露」「節點能 ping 通但連不上」等問題的根本。本文從原理層面對比 redir-host 與 fake-ip 兩種模式,並給出生產可用的配置模板。
為什麼代理場景中 DNS 如此特殊
普通上網時,瀏覽器發起請求的流程是:DNS 查詢域名 → 獲取真實 IP → 建立 TCP 連線。代理場景下,這個流程變得複雜:如果 DNS 查詢走本地(不經代理),國內 DNS 伺服器會對境外域名返回被汙染的 IP 或錯誤結果;如果全部走代理伺服器解析,又會帶來額外延遲,而且國內域名走代理解析也毫無必要。
Clash 需要在「拿到真實 IP 之前」就判斷這條流量應該走代理還是直連,這就是 DNS 模式設計的核心矛盾。
redir-host 模式:真實 IP 優先
redir-host 是 Clash 早期預設的 DNS 模式。其工作流程如下:
- 應用發起 DNS 查詢(如解析
openai.com) - Clash 同時向多個 DNS 上游併發查詢,取最快返回的結果
- 將真實 IP 返回給應用
- 應用用該 IP 建立連線,Clash 此時再根據 IP-CIDR 或 GEOIP 規則判斷路由
redir-host 的缺點是:規則匹配依賴真實 IP,而獲取 IP 的過程本身就可能受到 DNS 汙染,導致規則誤判。此外,每次連線都需要先完成 DNS 解析,增加了首次連線延遲。
fake-ip 模式:假 IP 先行
fake-ip 是 Mihomo(原 Clash.Meta)推薦的現代方案,也是 TUN 模式的最佳拍檔。其核心思路是:不等待真實 IP,立刻返回一個虛假的私有 IP,將真實的 DNS 解析推遲到代理側完成。
- 應用發起 DNS 查詢
- Clash 立刻從
fake-ip-range(預設198.18.0.0/15)中分配一個假 IP 返回給應用,同時在內部記錄「假 IP ↔ 域名」的對映 - 應用用假 IP 建立連線請求
- Clash 攔截連線,透過對映表還原出真實域名,再按域名規則判斷走代理或直連
- 若走代理,由代理伺服器在出口端完成 DNS 解析;若直連,Clash 在本地發起真實 DNS 查詢後直接轉發
fake-ip-filter:哪些域名不能用假 IP
並非所有請求都適合 fake-ip。部分應用(如微信、QQ、國內遊戲客戶端)依賴真實 IP 進行服務發現或 P2P 連線,給它們返回假 IP 會導致連線失敗。fake-ip-filter 欄位用於將這些域名排除在 fake-ip 之外,對它們仍使用真實 IP。
dns: enable: true listen: 0.0.0.0:53 enhanced-mode: fake-ip fake-ip-range: 198.18.0.1/16 # 以下域名排除在 fake-ip 之外,使用真实 IP fake-ip-filter: - '*.lan' - '*.local' - localhost.ptlogin2.qq.com - +.stun.*.* - +.stun.*.*.* nameserver: - 223.5.5.5 # 阿里 DNS,用于直连域名 - 119.29.29.29 # 腾讯 DNS fallback: - tls://8.8.8.8:853 # Google DNS over TLS,用于代理域名 - tls://1.1.1.1:853 # Cloudflare DoT fallback-filter: geoip: true geoip-code: CN ipcidr: - 240.0.0.0/4
nameserver 與 fallback 的分工
nameserver 是主要 DNS 伺服器,負責解析所有域名的初次查詢。fallback 是備用伺服器,當 fallback-filter 條件滿足時(如 IP 歸屬為非中國),Clash 會用 fallback 結果替換 nameserver 的結果。這樣的分組設計保證了:國內域名用國內 DNS(快速準確),境外域名用加密 DNS(防止汙染)。
fallback,所有 DNS 查詢都走 nameserver。境外域名可能被國內 DNS 汙染,導致 GEOIP 規則誤判,部分網站即使走了代理也無法訪問。如何驗證 DNS 是否洩露
訪問 dnsleaktest.com,點選「Extended Test」。若測試結果中出現中國大陸的 DNS 伺服器,說明存在 DNS 洩露。正確配置 fake-ip + fallback 後,結果應只顯示代理伺服器所在地區的 DNS 伺服器(或 Cloudflare/Google)。
另一個驗證方法是在 Clash 日誌中觀察 DNS 查詢記錄。將 log-level: debug 後重啟,連線某個境外網站時日誌中應顯示該域名的查詢走了 fallback DNS。