如何判斷 DNS 洩漏
DNS 洩漏是指網域查詢偏離預期的解析路徑。例如,瀏覽器連線已經透過代理,但查詢網域的請求仍交由本地電信業者的 DNS 處理。網站能正常開啟、對外 IP 已改變,都不能單獨證明 DNS 也走了預期路徑。排查時應分別確認應用程式連線、DNS 上游,以及 DNS 連線實際使用的出口。
本文設定適用於使用 mihomo 核心的用戶端。舊版 Clash 核心與不同用戶端支援的欄位可能有差異,修改前請先在用戶端的「關於」或核心資訊頁面記下核心名稱、版本與目前的設定來源。選單名稱會因用戶端而異,以下直接說明設定欄位,避免將特定用戶端的開關位置當成通用操作路徑。
檢測步驟:建立基準,再比較代理狀態
1. 記錄未接管時的結果
- 暫停代理接管,記下目前的對外 IP、系統設定的 DNS 位址,以及瀏覽器的安全 DNS 設定。
- 前往
https://www.dnsleaktest.com/,分別執行 Standard test 與 Extended test,記錄解析器 IP、組織名稱和檢測時間。 - 啟用目前使用的系統代理或 TUN,清除快取後,在同一個瀏覽器再次執行兩種測試。
- 固定節點、瀏覽器與網路,每次只調整一項 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 出口就結束測試。
修復後驗收與常見問題
透過三層證據確認結果
- 入口證據:本機
1053埠查詢正常,fake-ip 對應符合預期;啟用 TUN 後,系統的一般 DNS 查詢能進入核心。 - 路由證據:在用戶端連線面板或偵錯記錄中,確認解析器位址、匹配策略與連線出口。啟用偵錯記錄後,請及時恢復常用記錄層級;分享前刪除網域、節點與訂閱資訊。
- 外部證據:重新執行標準與擴充檢測,確認所有出現的解析器都能由目前設定解釋,並驗證瀏覽器、命令列及其他需要保護的應用程式。
也可以在實際出口網卡擷取封包,使用 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、區域網路解析例外與其他網路工具,每恢復一項就重新檢測。如此才能找出新增的解析分支,而不是等下次出現異常時重新猜測。