先釐清三條路徑:接管、解析與連線
「啟用 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:
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:
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:
respect-rules: true
proxy-server-nameserver:
- https://dns.alidns.com/dns-query
這是增量設定片段,不要拿來取代整份 DNS 設定。請保留前面用於初始解析的 default-nameserver、一般上游與其他設定,並確保用來解析節點網域的上游在啟動階段本身可連線。替節點設定解析器,不代表所有服務網域都已設定解析器。
- 先確認代理節點可連線,且規則中引用的策略群組名稱確實存在。
- 檢查 DNS 服務網域或目標 IP 符合哪條規則。若規則將該上游導向無法連線的路徑,啟用這個選項只會讓故障更穩定地重現。
- 查看記錄中上游連線選用的出口,再測試網站連線;不要只憑節點延遲圖示判斷 DNS 是否正常。
TUN 模式的 dns-hijack:接管進入虛擬網卡的 53 埠流量
只設定 dns.enable: true,不會自動替作業系統變更所有 DNS 解析路徑。在 TUN 模式下,可使用 dns-hijack 將進入 TUN 且符合條件的 DNS 流量交由核心處理。以下是可合併至現有 mihomo 設定的基本範例;原有節點、策略群組與規則仍須保留。
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 實作都可能各有其限制;要確認接管是否生效,必須觀察實際請求。
用指令分步驗證:先確認監聽,再測試接管,最後檢查上游
第一步:檢查設定與本機監聽
編輯前請先備份現有設定。若獨立執行核心,可先用以下指令檢查設定;使用圖形介面用戶端時,則應使用它實際呼叫的核心與工作目錄,避免檢查到另一份同名檔案。
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 埠流量
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 欄位,因為它可能仍顯示程式原先指定的目標。
第三步:確認實際解析結果與網站連線
- 暫時將記錄層級提高至
debug,保留一次問題請求的網域、錯誤訊息與上游位址;分享記錄前,請隱藏訂閱網址與節點憑證。 - 清除用戶端 DNS 快取,或重新啟動核心後,再測試尚未查詢過的網域。Windows 系統快取可使用
ipconfig /flushdns清除,但這不會同時清除瀏覽器與核心快取。 - 若要觀察真實回應,可在受控測試中暫時使用
enhanced-mode: redir-host,重新啟動後再查詢;測試結束後請還原設定,避免應用程式中殘留的舊 fake-ip 對應影響判斷。 - 最後開啟網站並檢查連線規則。若 DNS 查詢成功但 HTTPS 逾時,應繼續檢查代理出口、連線路由、TLS 與 MTU,不要反覆更換解析器。
本文指令用於重現問題與定位原因,沒有包含特定網路的實測延遲。比較效能時,應在相同網路下分別記錄冷快取與暖快取的結果;只比較第二次查詢所需時間,測到的往往只是快取效率。
常見故障對照與回復順序
| 狀況 | 優先檢查項目 | 處理方向 |
|---|---|---|
| 本機 1053 查詢逾時 | 設定載入、埠號占用、核心記錄 | 先恢復監聽,再檢查上游 |
| 1053 正常,但應用程式仍使用系統 DNS | TUN 權限、路由、瀏覽器安全 DNS | 確認請求是否進入接管範圍 |
| 啟用 respect-rules 後全部逾時 | 節點網域解析與 DNS 上游的出口規則 | 補上獨立的節點解析路徑 |
| 只有部分網域異常 | 策略命中、fallback 條件、快取 | 逐一驗證網域,不要同時修改整段設定 |
| 訂閱更新後故障再次發生 | 最終生效設定與覆寫合併結果 | 將修改放入可保留的覆寫設定 |
回復時,先恢復為「一個可連線的上游、停用複雜篩選」,確認一般解析正常;接著啟用 TUN 接管,最後再加入 fallback 與依規則選路。每個步驟都保留一份設定與查詢結果。欄位多不代表解析更穩定;能說明每個請求為何使用特定上游,設定才真正容易維護。