一、先釐清 DNS 出口、網頁出口與規則預期

網頁顯示代理出口 IP,不代表網域解析也經過代理。一次連線至少會經過兩條路徑:應用程式先解析網域,再連線至目標位址。系統代理通常只會接管遵循代理設定的應用程式;系統解析器、應用程式內建 DNS,以及瀏覽器的安全 DNS,可能各自走不同路徑。

本文所稱的「DNS 洩漏」是指:原本應透過指定解析路徑處理的查詢,實際交由非預期的解析器處理,或直接經由本機網路送出。如果規則原本就設定本地域名直連並使用本機解析,檢測到本機解析器不一定代表故障;如果目標是讓所有一般查詢都經代理轉送,出現相同結果就值得進一步排查。

觀察項目代表的意義無法直接證明的事項
網頁顯示的公網 IP該網頁連線使用的出口其他應用程式或 DNS 也使用相同出口
檢測網站列出的 DNS IP參與遞迴解析的伺服器出口裝置到解析器之間是否經過代理
回傳 198.18.x.x這次查詢取得常見 fake-ip 位址範圍內的映射所有系統查詢都已受到接管
出現本地電信業者的解析器有本機解析路徑需要進一步確認所有連線都繞過代理

二、檢測網站要做三組比對,別只看國家名稱

先記錄固定條件

可使用 dnsleaktest.com 的 Standard test、Extended test,以及 browserleaks.com/dns 交叉比對。這些網站會觸發測試網域解析,並記錄查詢抵達權威伺服器時的遞迴解析出口;它們不會直接讀取瀏覽器中的作業系統 DNS 設定。

  1. 記錄目前使用的網路,例如家用 Wi-Fi;並記下用戶端模式、所選節點、TUN 開關與瀏覽器安全 DNS 狀態。
  2. 關閉代理後執行一次測試,作為基準。記下公網 IP、DNS 服務商與解析器位址,不必公開完整截圖。
  3. 開啟代理並維持相同節點,再執行一次測試。系統代理模式與 TUN 模式分開記錄,避免同時變更多個條件。
  4. 暫時關閉瀏覽器安全 DNS,重新啟動瀏覽器後再測一次。若結果有所變化,優先檢查瀏覽器本身的 DoH 路徑。

以上是建議的操作步驟,不是本站提供的實測數據。比對時請著重確認「開關前後是否有變化」及「是否符合設定策略」,不要只憑國家標籤判斷。公共 DNS 使用任播網路,地理資料庫也可能有延遲;解析器登記的位置不一定等同實際提供服務的節點位置。

依結果縮小排查範圍

  • 網頁 IP 已變更,但 DNS 仍是家用寬頻業者:先確認系統 DNS 是否已交由核心處理,以及瀏覽器是否另有解析設定。
  • 只有特定瀏覽器顯示不同的 DNS:優先檢查該瀏覽器的安全 DNS、擴充功能與獨立代理設定。
  • 出現兩家公共 DNS:可能是設定了多個上游或備援解析器,不能只憑數量判定為洩漏。
  • 啟用 TUN 後結果才符合預期:表示系統代理未涵蓋原本的解析路徑,請繼續確認應用程式涵蓋範圍與 IPv6。

三、以 fake-ip 建立網域映射,再檢查解析上游

fake-ip 會回傳虛擬位址給應用程式,並由核心保存網域映射。後續連線抵達核心時,核心便能依此套用網域規則。它不是加密協定,也不會自動接管作業系統 DNS。即使已啟用設定,若系統仍向路由器發出查詢,DNS 仍可能繞過這條路徑。

以下是合併至現有設定的 DNS 片段,並非完整訂閱內容。請保留現有節點、代理群組與規則,檢查並修改既有的頂層 dns: 區段;不要在同一個檔案中再加入第二個同名區段。

config.yaml · DNS 設定片段
dns:
  enable: true
  listen: 127.0.0.1:1053
  ipv6: false
  enhanced-mode: fake-ip
  fake-ip-range: 198.18.0.1/16
  fake-ip-filter:
    - '+.lan'
    - '+.local'
  respect-rules: true
  default-nameserver:
    - 223.5.5.5
  proxy-server-nameserver:
    - 223.5.5.5
  nameserver:
    - https://cloudflare-dns.com/dns-query
  • listen 是核心 DNS 的監聽位址。範例中的 1053 適合先用於指定測試,但不會自動讓系統改用這個通訊埠。
  • default-nameserver 用來解析 DNS 伺服器本身的網域,是啟動解析鏈的一環,不是一般查詢使用的上游清單。
  • proxy-server-nameserver 用來解析代理節點網域,避免「解析節點前要先連上代理,但連代理又得先解析節點」的循環依賴。
  • nameserver 中的 DoH 位址用於一般上游解析。HTTPS 加密的是通往解析服務的傳輸,不代表這段傳輸一定經過代理。
  • fake-ip-filter 中的網域不會使用 fake-ip 映射;此清單不等同直連規則,也不代表這些網域不再發出 DNS 查詢。

四、respect-rules 決定上游連線如何路由,不負責接管系統

respect-rules: true 會讓相關 DNS 上游連線遵循路由規則。它解決的是「核心向上游發出請求時要走哪個出口」,不是「系統的查詢有沒有進入核心」。分開驗證這兩件事,排查時就不必繞遠路。

確認最後套用的規則

  1. 確認目前使用規則模式,也就是 mode: rule。全域模式與直連模式的行為,不能代替規則模式的驗證。
  2. 檢查 DNS 服務網域是否被前置規則或規則集比對為 DIRECT。若命中直連規則,即使啟用 respect-rules,連線也不會因此改走代理。
  3. 透過用戶端的連線面板與記錄,確認上游連線套用的規則及出口;必要時可短暫提高記錄層級,排查完成後再調低,避免持續記錄過多網域。
  4. 若要為 DNS 服務網域指定專用出口,請使用現有代理群組的正確名稱,並將規則放在可能先命中的廣泛規則之前。不要引用設定中根本不存在的群組名稱。

若原設定包含 nameserver-policy、direct-nameserver 或 fallback,也要一併檢查。只修改 nameserver,可能完全沒有改變部分網域實際使用的解析器。初次排查時宜減少變數,確認最小設定運作正常後,再逐項恢復策略。

fallback 也不是單純的「主要 DNS 逾時才啟動」開關。備援結果如何採用,與 fallback-filter 等條件有關;為了修復洩漏而隨意加入多個解析器,通常只會讓檢測結果更複雜。

五、接管系統 DNS:TUN 與 53 通訊埠各自的用途

多數桌面作業系統的網路設定只能填入 DNS 伺服器位址,無法指定 1053 這類自訂通訊埠。因此,若系統 DNS 設為 127.0.0.1,核心卻只監聽 127.0.0.1:1053,就會發生通訊埠不相符的問題。若要讓系統直接連線至本機 DNS,需監聽 53 通訊埠,並處理權限與通訊埠占用;不要未經確認就把監聽位址改成對整個區域網路開放。

另一種常用方式是透過 TUN 接管網路流量,並將進入 TUN 的一般 DNS 請求交由核心處理。以下同樣是合併用的設定片段;請先確認目前的用戶端沒有透過介面另外產生一份 TUN 設定。

config.yaml · TUN 設定片段
tun:
  enable: true
  stack: mixed
  auto-route: true
  auto-detect-interface: true
  dns-hijack:
    - any:53
    - tcp://any:53
  • any:53 與 tcp://any:53 分別涵蓋進入 TUN 的 UDP 與 TCP 53 通訊埠 DNS 請求。
  • auto-route 負責自動設定相關路由;若啟動失敗,應先檢查服務權限、路由衝突及其他 VPN,而不是反覆切換 DNS 位址。
  • 送往本機網路或遭路由排除的 DNS 請求,不一定會進入 TUN。路由器 DNS、其他虛擬網卡與本機迴圈解析器都需要分別驗證。
  • DoH 通常使用 HTTPS 的 443 通訊埠,DoT 通常使用 853 通訊埠。攔截 53 通訊埠不會自動將它們轉成核心 DNS 查詢。

六、依序在 Windows、macOS、Linux 與 Android 重新測試

Windows:區分核心監聽測試與系統路徑測試

以系統管理員權限啟動用戶端所需的服務或 TUN 後,先執行以下兩個指令。第一個會明確查詢本機 1053 通訊埠,第二個使用系統預設 DNS;兩者驗證的是不同路徑。

Windows · PowerShell 或命令提示字元
nslookup -port=1053 example.com 127.0.0.1
nslookup example.com
ipconfig /all
ipconfig /flushdns

若網域不在過濾清單中,第一個指令通常應回傳設定位址池中的 fake-ip。即使第二個指令命中 TUN 攔截,介面仍可能顯示原先設定的 DNS 伺服器名稱,不能只看那一行就判定失敗。請搭配回傳位址、記錄與檢測網站交叉確認。清除快取後重新存取測試網域,避免舊結果造成干擾。

macOS:檢查系統解析器清單,不要只看 Wi-Fi 頁面

macOS · 終端機
scutil --dns
dig @127.0.0.1 -p 1053 example.com A
dscacheutil -q host -a name example.com
sudo dscacheutil -flushcache
sudo killall -HUP mDNSResponder

scutil --dns 可查看依介面或網域區分的解析器設定。dig 的指定查詢可用來檢查核心監聽狀態;dscacheutil 則適合用來輔助觀察系統解析路徑。取得啟用 TUN 所需的授權後,再測試瀏覽器;不要因為 dig 成功就略過系統層級的檢查。

Linux:留意 systemd-resolved 與迴圈位址

Linux · 使用 systemd-resolved 的系統
resolvectl status
resolvectl query example.com
dig @127.0.0.1 -p 1053 example.com A
sudo resolvectl flush-caches

/etc/resolv.conf 中出現 127.0.0.53,通常表示應用程式會先連到本機解析存根,不代表最終上游就在本機。請繼續查看 resolvectl status 中各介面的 DNS 設定。未使用 systemd-resolved 的發行版,應檢查 NetworkManager 或實際負責 DNS 的服務,不要直接覆寫由服務自動產生的檔案。

Android:分別排查私人 DNS 與瀏覽器安全 DNS

在原生 Android 常見路徑「設定」→「網路和網際網路」→「私人 DNS」中,暫時關閉指定的私人 DNS,再重新執行同一組測試;不同廠牌的選單名稱可能不同。確認用戶端已取得 VPN 授權,且分應用程式代理沒有排除測試用的瀏覽器。Android 通常一次只能執行一個一般 VPN 服務,其他 VPN 或本機過濾工具可能會占用這條路徑。

Chrome 桌面版常見路徑為「設定」→「隱私權和安全性」→「安全性」→「使用安全 DNS」。關閉此功能只是為了排除變因,測試結束後可以重新啟用,再確認該 DoH 連線實際使用的出口。保留瀏覽器 DoH 不一定代表發生洩漏,關鍵在於是否符合你的解析與路由策略。

七、fake-ip 已生效但仍有異常時,檢查這四項

  1. IPv6 走了另一條路徑:dns.ipv6: false 控制核心如何處理 AAAA 查詢,不等於停用系統 IPv6。應用程式快取、內建解析器或既有 IPv6 位址仍可能建立連線,請確認 IPv6 路由與 TUN 涵蓋範圍。
  2. 訂閱更新覆蓋了手動修改:重新載入後,請檢查實際生效的設定,而不只是編輯器中的檔案。需要長期保留的欄位,應透過用戶端支援的覆寫、合併或持續保存設定機制管理。
  3. 過濾清單過長:將大量公共網域加入 fake-ip-filter 會讓它們回傳真實位址,但不會自動修正解析出口。只為確實有相容性問題的網域加入例外,並在每次新增後重新測試。
  4. 快取與舊連線尚未清除:系統快取、瀏覽器快取、核心映射與已建立連線各有不同的有效時間。重新載入後先關閉測試分頁,必要時重新啟動瀏覽器,再執行新的檢測;別用舊連線來評估新設定。

最後以驗收清單確認設定

  • 指定查詢 127.0.0.1:1053 有回應,一般測試網域也取得預期的 fake-ip 映射。
  • 已檢查系統預設解析與實際瀏覽器測試,而不只是測試核心通訊埠。
  • DNS 上游出口符合規則,且已明確記錄節點網域與啟動解析的例外。
  • 已分別檢查一般 DNS、瀏覽器 DoH、IPv6 與分應用程式排除項目,沒有將 53 通訊埠攔截誤當成接管所有協定。
  • 訂閱更新、重新啟動用戶端及切換 Wi-Fi 後都重新測試,結果仍符合既定策略。

排查流程可以簡化成三步:先確認查詢進入核心,再確認上游連線使用正確出口,最後確認常用應用程式沒有改走其他路徑。fake-ip 負責網域映射,respect-rules 負責上游路由,系統 DNS 接管則負責涵蓋查詢入口;三者分工明確,記錄才不會變成猜謎。