如何判斷 DNS 洩漏

DNS 洩漏是指網域查詢偏離預期的解析路徑。例如,瀏覽器連線已經透過代理,但查詢網域的請求仍交由本地電信業者的 DNS 處理。網站能正常開啟、對外 IP 已改變,都不能單獨證明 DNS 也走了預期路徑。排查時應分別確認應用程式連線、DNS 上游,以及 DNS 連線實際使用的出口。

本文設定適用於使用 mihomo 核心的用戶端。舊版 Clash 核心與不同用戶端支援的欄位可能有差異,修改前請先在用戶端的「關於」或核心資訊頁面記下核心名稱、版本與目前的設定來源。選單名稱會因用戶端而異,以下直接說明設定欄位,避免將特定用戶端的開關位置當成通用操作路徑。

檢測步驟:建立基準,再比較代理狀態

1. 記錄未接管時的結果

  1. 暫停代理接管,記下目前的對外 IP、系統設定的 DNS 位址,以及瀏覽器的安全 DNS 設定。
  2. 前往 https://www.dnsleaktest.com/,分別執行 Standard test 與 Extended test,記錄解析器 IP、組織名稱和檢測時間。
  3. 啟用目前使用的系統代理或 TUN,清除快取後,在同一個瀏覽器再次執行兩種測試。
  4. 固定節點、瀏覽器與網路,每次只調整一項 DNS 設定,再重新檢測。請勿同時更換節點、解析器與接管模式。

線上檢測通常會透過隨機子網域觀察遞迴解析器的來源。結果中的位址通常屬於解析器的遞迴出口,不是裝置的對外 IP,也不一定等於設定中的 1.1.1.1 等接入位址。公用 DNS 的 Anycast 調度與地理資料庫誤差也會影響顯示地區,因此「解析器所在國家與節點所在國家不同」只能作為線索,不能直接判定為洩漏。

2. 清除快取並固定測試條件

Windows 可在終端機執行以下命令;macOS 的第二個命令需要管理員授權。清除後請關閉並重新開啟瀏覽器,必要時重新連線代理,避免沿用舊連線原本的解析路徑。

# Windows
ipconfig /flushdns

# macOS
sudo dscacheutil -flushcache
sudo killall -HUP mDNSResponder

# 使用 systemd-resolved 的 Linux
resolvectl flush-caches

並非所有 Linux 發行版都使用 systemd-resolved;若找不到該命令,請確認目前使用的解析服務。測試紀錄建議包含五項:時間、接管模式、瀏覽器安全 DNS 狀態、解析器組織,以及實際連線出口。本文不提供虛構的實測百分比;修復是否有效,應以目前裝置的多次檢測結果為準。

3. 根據證據判讀,不要只看位址數量

檢測現象可能原因下一步
出現本地電信業者的解析器系統 DNS 未被接管,或策略明確設定為直連檢查 TUN、53 埠請求與 DNS 策略
只出現公用解析器核心或瀏覽器正在使用公用 DNS繼續確認連線出口,不能據此判定流量經過代理
出現多個公用解析器平行解析、fallback 或解析器叢集逐一比對設定中的上游
瀏覽器與命令列結果不同瀏覽器使用獨立 DoH、快取或應用程式代理設定不同統一解析入口後重新檢測

fake-ip 與 nameserver:先建立可驗證的解析入口

enhanced-mode: fake-ip 會讓核心對適用的網域回傳虛擬位址,再依據對應關係處理連線。這能減少部分連線在建立前對真實位址解析的依賴,但不代表完全不需要上游查詢。直連連線、位址規則判斷及部分應用程式情境,仍可能需要真實解析結果。

以下是用來檢查 DNS 連線路徑的設定片段,不是完整的訂閱設定。請將同名欄位合併至現有設定,保留原有節點、策略群組與規則;同一層級不要重複出現兩個 dns:。範例中的 7890 是混合代理埠,1053 是本機 DNS 監聽埠,兩者不可混用。

mixed-port: 7890
mode: rule

dns:
  enable: true
  listen: 127.0.0.1:1053
  enhanced-mode: fake-ip
  fake-ip-range: 198.18.0.1/16
  fake-ip-filter:
    - "localhost"
    - "*.lan"
  nameserver:
    - https://1.1.1.1/dns-query
    - https://8.8.8.8/dns-query
  • enable 用來啟用核心 DNS。只啟用此項,不會自動讓所有應用程式向這個監聽位址送出請求。
  • listen 綁定回送位址,供本機測試使用。排查時不要直接監聽所有網路介面,以免將解析服務開放給區域網路。
  • fake-ip-filter 中的網域會使用真實位址解析。請依實際相容性需求新增網域,不要為了修復單一應用程式就排除所有網域。
  • nameserver 用來指定上游解析器。設定多個上游不代表它們會嚴格依主備順序運作,也不能假設只有第一個位址完全失效後才會使用第二個。

可使用以下命令直接檢查核心的 UDP DNS 監聽。對未列入過濾清單的網域,預期會看到 198.18.0.0/16 範圍內的虛擬位址。這只能證明本次查詢已到達核心,還不能證明瀏覽器也使用相同入口。

# Windows
nslookup -port=1053 example.com 127.0.0.1

# 已安裝 dig 的 macOS / Linux
dig @127.0.0.1 -p 1053 example.com A

DoH 的出口:加密傳輸不等於透過代理傳輸

範例中的 DoH 通常透過 TCP 443 建立 HTTPS 連線,查詢內容不會以一般 UDP 53 的形式傳送。但若這條連線採用直連,解析器仍會看到本地網路的對外 IP;本地網路也仍可能觀察到連往解析器的目的位址。若希望解析器看到代理節點的出口 IP,還需要確認核心發起的 DNS 連線如何選擇路由。

使用 respect-rules 前,先處理節點網域解析

支援此欄位的 mihomo 可透過 dns.respect-rules: true,讓 DNS 連線遵循路由規則。這不是「強制所有 DNS 走代理」的開關:若解析器 IP 符合 DIRECT,連線仍會直連。請在實際規則中,將選定解析器的目標位址交由現有的代理策略處理,同時避免較早套用的直連規則先行匹配。

啟用時也應設定 proxy-server-nameserver,獨立處理代理節點伺服器網域的啟動解析。否則可能形成循環依賴:連線代理前必須先解析節點網域,但解析又要求先連上代理。這個啟動解析器本身也必須符合網路條件;若使用直連啟動解析,節點網域查詢會暴露給相應解析器,這是必須明確接受的界線。

使用網域形式的 DoH 位址時,也必須處理解析器本身網域的啟動解析。default-nameserver 用於這類基礎解析,不是一般查詢的預設分流策略。上方範例使用 IP 形式的 DoH 位址,方便先縮小排查範圍;但仍須確認上游可連線、TLS 驗證正常,並檢查實際出口。

fallback 與 nameserver-policy:減少非預期的解析分支

fallback 可能會參與平行查詢

fallback 不能簡單理解為「主要 DNS 逾時後才啟用」。完成設定後,核心可能同時向主要解析器與備用解析器送出查詢,再依據 fallback-filter 決定採用哪一方的結果。因此,檢測頁面出現備用解析服務,不一定代表主要解析器故障,也不必然表示請求繞過代理。

排查初期建議先省略 fallback,讓解析路徑更簡單。確認基本連線正常後,若確實需要過濾異常位址,再將以下欄位合併至同一個 dns 區塊。此例停用 GeoIP 判斷,只示範以明確位址範圍觸發備用結果,不代表能辨識所有遭污染的答案。

  fallback:
    - https://9.9.9.9/dns-query
  fallback-filter:
    geoip: false
    ipcidr:
      - 0.0.0.0/32
      - 240.0.0.0/4

若啟用 fallback-filter.geoip 並設定 geoip-code: CN,主要解析結果是否位於指定地區會影響結果選擇。這是答案篩選功能,不是 DNS 出口控制。資料庫過期、CDN 位址歸屬變動與跨地區部署,都可能影響判斷;不可將 GeoIP 判斷當成通用防洩漏開關。

nameserver-policy 指定「由哪個解析器處理」

nameserver-policy 可依網域選擇解析器。例如,以下片段會讓 example.com 及其子網域使用指定的 DoH。這個網域僅用於示範語法;實際設定時應填入確實需要專用解析器的網域,並在合併後進行驗證。

  nameserver-policy:
    "+.example.com":
      - https://1.1.1.1/dns-query

網域解析策略與連線分流規則是兩套不同的判斷。指定解析器不代表該網站流量會改走代理;同樣地,將網站規則設為代理,也不代表解析器連線必定走代理。企業內網及家用裝置的網域可能需要本地解析器;若為這些網域個別設定直連解析,請將它記錄為刻意保留的例外,不要和公用網域測試混在一起。

TUN DNS 劫持:接管系統的 53 埠查詢

系統代理主要影響遵循代理設定的應用程式,通常不會自動改寫系統 DNS 路徑。TUN 會將更多 IP 流量交給核心,再搭配 DNS 劫持接收一般 DNS 查詢。以下仍是合併用的設定片段;必須使用支援 TUN 的 mihomo 用戶端,並依平台要求授權建立虛擬網卡與修改路由。

tun:
  enable: true
  stack: mixed
  auto-route: true
  auto-detect-interface: true
  dns-hijack:
    - any:53
    - tcp://any:53
  • auto-route 用於自動設定路由。啟用後請確認用戶端顯示 TUN 正在執行,而不只是開關已切換至開啟狀態。
  • any:53 與 tcp://any:53 分別涵蓋進入接管路徑的一般 UDP、TCP DNS 請求。
  • auto-detect-interface 可協助辨識出口網卡。若有多個 VPN、虛擬網卡或特殊路由,仍須確認實際選用的介面。

DNS 劫持不等於攔截所有加密解析。應用程式內建的 DoH 使用 HTTPS,DoT 通常使用 TCP 853,不會因為列出 53 埠就改由核心 DNS 處理。已由其他 VPN 接管、透過排除路由繞過,或在特殊系統解析流程中處理的請求,也可能不會進入這組劫持規則。

分開檢查瀏覽器安全 DNS 與 IPv6

測試期間可先關閉瀏覽器的獨立安全 DNS,讓瀏覽器與系統共用解析路徑。Chrome 可在「設定」→「隱私權和安全性」→「安全性」中檢查「使用安全 DNS」;實際名稱可能隨版本變動。若要保留瀏覽器 DoH,請將它視為獨立路徑檢查,包括解析器、連線出口,以及失敗後的回退行為。

也請檢查 IPv6。DNS 回傳 AAAA 紀錄,與 IPv6 流量受到正確接管,是兩回事。設定 dns.ipv6: false 會影響核心處理 AAAA 回應的方式,無法取代系統 IPv6 路由控制;應用程式自行解析時仍可能取得 IPv6 位址。不要只看 IPv4 出口就結束測試。

修復後驗收與常見問題

透過三層證據確認結果

  1. 入口證據:本機 1053 埠查詢正常,fake-ip 對應符合預期;啟用 TUN 後,系統的一般 DNS 查詢能進入核心。
  2. 路由證據:在用戶端連線面板或偵錯記錄中,確認解析器位址、匹配策略與連線出口。啟用偵錯記錄後,請及時恢復常用記錄層級;分享前刪除網域、節點與訂閱資訊。
  3. 外部證據:重新執行標準與擴充檢測,確認所有出現的解析器都能由目前設定解釋,並驗證瀏覽器、命令列及其他需要保護的應用程式。

也可以在實際出口網卡擷取封包,使用 Wireshark 顯示篩選器 udp.port == 53 || tcp.port == 53 || tcp.port == 853,尋找一般 DNS 與常見的 DoT 連線。務必選對擷取介面:虛擬網卡中的明文請求之後可能由核心接管,不能直接視為實體出口洩漏。DoH 混在 HTTPS 流量中,單靠這個篩選器看不到查詢內容。

啟用 fake-ip 後,檢測仍顯示電信業者 DNS,該從哪裡查起?

先透過本機 1053 埠確認 DNS 設定已載入,再確認系統查詢確實進入 TUN。接著檢查瀏覽器是否使用獨立解析、其他 VPN、策略中的本地解析器,以及訂閱更新是否覆蓋修改。fake-ip 本身不會替系統選擇 DNS 入口。

設定 DoH 後所有網站都無法開啟,該如何復原?

還原修改前的設定,先確認節點與基本網路可正常使用。接著只啟用一個已確認可連線的 DoH,檢查是否有逾時、TLS 錯誤或節點網域解析循環。此階段不要同時加入 fallback、策略解析與規則跟隨。

訂閱更新後修復設定失效,如何保留修改?

優先使用用戶端支援的覆寫、合併設定或設定增強機制,不要只修改一次下載的訂閱檔案。儲存後查看最終生效的設定,確認 dns 與 tun 欄位沒有被後續合併覆蓋。實際功能名稱請以使用的用戶端為準。

驗收目標不是讓測試頁只顯示一個位址,而是確保每條解析路徑都有明確的來源與出口。完成後再逐項恢復瀏覽器安全 DNS、區域網路解析例外與其他網路工具,每恢復一項就重新檢測。如此才能找出新增的解析分支,而不是等下次出現異常時重新猜測。