先釐清三條路徑:接管、解析與連線

「啟用 DNS」不代表「所有應用程式都使用這份 DNS 設定」。排查 mihomo DNS 問題時,應拆成三個步驟:應用程式的查詢是否進入核心、核心向哪個上游查詢,以及解析後的連線由哪條代理規則處理。任何一步出錯都可能導致網頁無法開啟,但只改同一個開關,通常無法解決這三類問題。

  • 接管入口:dns.listen 提供 DNS 監聽服務;在 TUN 模式下,dns-hijack 會將符合條件的 DNS 流量導入內建解析器。
  • 上游選擇:nameserver、nameserver-policy、fallback 等欄位會決定解析路徑與結果選擇方式。
  • 連線分流:rules 決定網站連線要直連還是走代理;啟用 respect-rules 後,DNS 上游連線也會依路由規則處理。

本文適用於使用 mihomo 核心的用戶端。原版 Clash、Premium 與不同時期的 Meta 核心,支援的欄位不盡相同。請先在用戶端的核心資訊或啟動記錄中確認實際使用的核心,再編輯目前生效的設定檔;圖形介面用戶端的版本號不能代表核心版本。

default-nameserver:先解析 DNS 伺服器的網域名稱

上游若設定為 https://dns.alidns.com/dns-query,核心必須先取得 dns.alidns.com 的 IP,才能建立 HTTPS 連線。default-nameserver 主要負責這個初始解析步驟,並不是「所有網站預設使用的 DNS」。兩者名稱只差幾個字,排查方向卻完全不同。

DNS 初始解析範例
dns:
  enable: true
  default-nameserver:
    - 223.5.5.5
    - 119.29.29.29
  nameserver:
    - https://dns.alidns.com/dns-query

上方兩個 IP 用於初始解析。一般以 IP 位址表示的 DNS 通常使用 UDP 53;即使後續上游是 DoH,也不會因此自動變成加密請求。若網路要求連初始查詢也加密,請選用目前核心支援、且不必依賴其他網域解析的 IP 格式加密端點,並確認服務憑證與連線方式相容。

nameserver 與 fallback:不是主要伺服器逾時後才改用備援

nameserver 提供一般解析結果

nameserver 是未受更具體 DNS 策略覆蓋時使用的主要上游集合。設定多個位址可提升容錯能力,但不要把清單順序理解為嚴格的「第一個失敗才查第二個」。核心可能會同時查詢多個上游,DNS 快取也可能讓這次請求完全不會連到上游。

DoH 的 HTTPS 連線通常使用 TCP 443,DoT 則通常使用 TCP 853;加密協定保護的是查詢傳輸,不會直接決定連線要走哪個代理節點。瀏覽器能開啟某個 DoH 位址,也不代表 mihomo 在目前的路由、憑證與代理設定下能連上該服務。

fallback 搭配結果篩選

不宜把 fallback 理解成只有網路逾時後才啟用的傳統備援伺服器。設定後,核心會搭配 fallback-filter 選擇解析結果,相關查詢也可能同時進行。排查時若看到兩個上游都收到查詢,不代表設定被讀取了兩次。

欄位主要用途不要誤以為
default-nameserver解析 DNS 上游的主機名稱所有網站的預設上游
nameserver一般網域名稱解析嚴格依序執行的清單
fallback提供另一組供篩選的結果只有逾時才會查詢的備援伺服器
fallback-filter控制何時採用 fallback 結果代理規則或防火牆規則
dns-hijack接管 TUN 路徑中符合條件的 DNS 流量解密應用程式專用 DoH 的開關

fallback-filter:依地區、位址與網域篩選

以下以中國大陸上游搭配另一組公共 DoH,示範結果篩選方式。這個範例用於說明欄位,不代表每種網路都能直連所有端點。若備援上游無法連線,請先排除連線或路由問題,再確認回傳結果是否可信。

合併至現有的 dns 區段
dns:
  enable: true
  default-nameserver:
    - 223.5.5.5
    - 119.29.29.29
  nameserver:
    - https://dns.alidns.com/dns-query
    - https://doh.pub/dns-query
  fallback:
    - https://1.1.1.1/dns-query
    - https://dns.google/dns-query
  fallback-filter:
    geoip: true
    geoip-code: CN
    ipcidr:
      - 240.0.0.0/4
    domain:
      - '+.google.com'
  • geoip: true 與 geoip-code: CN:一般可理解為,主要上游回傳的位址若不屬於指定地區,就傾向採用 fallback 結果;此判斷取決於核心使用的 GeoIP 資料。
  • ipcidr:若主要上游回傳的位址符合列出的網段,就會觸發 fallback 結果選擇。範例中的 240.0.0.0/4 是保留位址範圍,並非完整的異常位址清單。
  • domain:符合條件的網域會直接使用 fallback 路徑。範例中的 +.google.com 涵蓋該網域及其子網域;加上引號可降低 YAML 解析時產生歧義的機率。

地區篩選是一種策略,並非判定 DNS 污染的數學證明。海外網域也可能使用中國大陸的 CDN,中國大陸的服務也可能回傳海外位址;GeoIP 資料過舊同樣會造成誤判。若只想替幾個已知網域指定解析器,使用 nameserver-policy 通常比堆疊複雜的地區條件更直接。命中這類策略後,也不要假設它一定會經過此處的一般 fallback 流程。

若不需要依地區判斷,可明確設定 geoip: false,只保留有明確依據的網域與位址條件。不要只為了消除一則逾時記錄,就隨意加入大範圍的私有網路位址過濾;內部網站回傳私有 IP 本來就是正確結果。

respect-rules:讓 DNS 上游連線依規則選路

respect-rules: true 控制的是「核心連線至 DNS 上游時如何選路」,而不是「是否啟用網域規則」。啟用前應先設定 proxy-server-nameserver,用來解析代理節點本身的網域,避免陷入「解析節點需要代理,建立代理又需要先解析節點」的循環依賴。

在現有的 dns 映射中新增或修改
dns:
  respect-rules: true
  proxy-server-nameserver:
    - https://dns.alidns.com/dns-query

這是增量設定片段,不要拿來取代整份 DNS 設定。請保留前面用於初始解析的 default-nameserver、一般上游與其他設定,並確保用來解析節點網域的上游在啟動階段本身可連線。替節點設定解析器,不代表所有服務網域都已設定解析器。

  1. 先確認代理節點可連線,且規則中引用的策略群組名稱確實存在。
  2. 檢查 DNS 服務網域或目標 IP 符合哪條規則。若規則將該上游導向無法連線的路徑,啟用這個選項只會讓故障更穩定地重現。
  3. 查看記錄中上游連線選用的出口,再測試網站連線;不要只憑節點延遲圖示判斷 DNS 是否正常。

TUN 模式的 dns-hijack:接管進入虛擬網卡的 53 埠流量

只設定 dns.enable: true,不會自動替作業系統變更所有 DNS 解析路徑。在 TUN 模式下,可使用 dns-hijack 將進入 TUN 且符合條件的 DNS 流量交由核心處理。以下是可合併至現有 mihomo 設定的基本範例;原有節點、策略群組與規則仍須保留。

TUN 與 fake-ip 基本設定範例
dns:
  enable: true
  listen: 127.0.0.1:1053
  ipv6: false
  enhanced-mode: fake-ip
  fake-ip-range: 198.18.0.1/16
  default-nameserver:
    - 223.5.5.5
    - 119.29.29.29
  nameserver:
    - https://dns.alidns.com/dns-query
    - https://doh.pub/dns-query

tun:
  enable: true
  stack: mixed
  auto-route: true
  auto-detect-interface: true
  dns-hijack:
    - any:53
    - tcp://any:53

any:53 用於 UDP DNS,tcp://any:53 則補上 TCP DNS。目標埠不必先改成 localhost 的 1053;接管後,符合條件的流量會送入內建 DNS。listen 則是供明確查詢使用的獨立監聽入口;保留迴圈位址可避免不慎向區域網路開放解析服務。

此處的 198.18.0.1/16 用於 fake-ip 對應。查詢回傳此範圍內的合成位址是預期行為,不代表上游真的回傳了這個位址。核心會透過對應關係還原網域並處理後續連線;若特定應用程式必須取得真實 IP,請依使用情境設定 fake-ip-filter,不要將整個保留位址區段視為 DNS 故障。

  • 桌面端:TUN 通常需要系統管理員權限、服務模式或相應的網路權限,視用戶端與作業系統而定。
  • Android:VPN 授權可能與其他 VPN 應用程式衝突;系統的「私人 DNS」也可能改變解析路徑。
  • 瀏覽器:內建的安全 DNS 會透過 HTTPS 使用 443 埠,不能預期接管 53 埠的功能會自動涵蓋這類流量。
  • 區域網路與 IPv6:未進入 TUN 的流量、被路由排除的位址,以及其他介面上的流量路徑,都需要另外確認。

範例中的 dns.ipv6: false 控制 DNS 如何處理 AAAA 查詢,不代表停用作業系統的 IPv6,更不是完整的 IPv6 防繞過方案。Linux 本機解析服務、macOS 的區域網路解析路徑,以及 Android 的 VPN 實作都可能各有其限制;要確認接管是否生效,必須觀察實際請求。

用指令分步驗證:先確認監聽,再測試接管,最後檢查上游

第一步:檢查設定與本機監聽

編輯前請先備份現有設定。若獨立執行核心,可先用以下指令檢查設定;使用圖形介面用戶端時,則應使用它實際呼叫的核心與工作目錄,避免檢查到另一份同名檔案。

終端機:檢查設定與明確指定 DNS 查詢
mihomo -t -f config.yaml

dig @127.0.0.1 -p 1053 example.com A
dig @127.0.0.1 -p 1053 example.com A +tcp

前兩個查詢分別用來驗證 1053 監聽的 UDP 與 TCP 路徑。沒有 dig 的 Windows 環境可執行 nslookup -port=1053 example.com 127.0.0.1。回傳 fake-ip 只能證明請求進入了解析器並取得對應位址,不能單獨證明指定的 DoH 已成功回傳真實 IP。

第二步:確認 TUN 是否接管 53 埠流量

終端機:比較 UDP 與 TCP 接管結果
dig @8.8.8.8 example.com A
dig @8.8.8.8 example.com A +tcp

此處明確指定的 8.8.8.8 是測試目標;若請求被 TUN 接管,它不一定是實際收到查詢的上游。請搭配核心記錄與 fake-ip 回傳結果判斷,不要只看 dig 輸出中的 SERVER 欄位,因為它可能仍顯示程式原先指定的目標。

第三步:確認實際解析結果與網站連線

  1. 暫時將記錄層級提高至 debug,保留一次問題請求的網域、錯誤訊息與上游位址;分享記錄前,請隱藏訂閱網址與節點憑證。
  2. 清除用戶端 DNS 快取,或重新啟動核心後,再測試尚未查詢過的網域。Windows 系統快取可使用 ipconfig /flushdns 清除,但這不會同時清除瀏覽器與核心快取。
  3. 若要觀察真實回應,可在受控測試中暫時使用 enhanced-mode: redir-host,重新啟動後再查詢;測試結束後請還原設定,避免應用程式中殘留的舊 fake-ip 對應影響判斷。
  4. 最後開啟網站並檢查連線規則。若 DNS 查詢成功但 HTTPS 逾時,應繼續檢查代理出口、連線路由、TLS 與 MTU,不要反覆更換解析器。

本文指令用於重現問題與定位原因,沒有包含特定網路的實測延遲。比較效能時,應在相同網路下分別記錄冷快取與暖快取的結果;只比較第二次查詢所需時間,測到的往往只是快取效率。

常見故障對照與回復順序

狀況優先檢查項目處理方向
本機 1053 查詢逾時設定載入、埠號占用、核心記錄先恢復監聽,再檢查上游
1053 正常,但應用程式仍使用系統 DNSTUN 權限、路由、瀏覽器安全 DNS確認請求是否進入接管範圍
啟用 respect-rules 後全部逾時節點網域解析與 DNS 上游的出口規則補上獨立的節點解析路徑
只有部分網域異常策略命中、fallback 條件、快取逐一驗證網域,不要同時修改整段設定
訂閱更新後故障再次發生最終生效設定與覆寫合併結果將修改放入可保留的覆寫設定

回復時,先恢復為「一個可連線的上游、停用複雜篩選」,確認一般解析正常;接著啟用 TUN 接管,最後再加入 fallback 與依規則選路。每個步驟都保留一份設定與查詢結果。欄位多不代表解析更穩定;能說明每個請求為何使用特定上游,設定才真正容易維護。