mihomo DNS 設定教學:nameserver、fallback 與 DNS 劫持

逐一說明 dns 區段的 enhanced-mode、nameserver、fallback、fallback-filter 與 dns-hijack,並提供可直接參考的情境設定範例。

先確認 DNS 請求經過哪些環節

先分清楚「網域名稱解析」與「連線轉送」。DNS 負責將網域名稱轉換成 IP 位址;代理規則則決定連線要直連或經由代理。解析成功不代表流量已經走代理;即使啟用了系統代理,也不表示系統所有 DNS 查詢都會送進 mihomo。

接著確認用戶端使用的核心。mihomo 是 Clash Meta 更名後持續維護的核心;圖形介面用戶端則負責產生設定、啟動核心及管理系統網路。本文依據 mihomo 欄位撰寫,範例不一定適用於較早期的原版 Clash。請先在用戶端的核心資訊頁查看版本,或執行下列命令,記錄版本與設定檢查結果。

mihomo -v
mihomo -t -f config.yaml

依照以下順序檢查。只修改出問題的環節,比同時更換 DNS、節點和規則更容易找出原因。

  1. 應用程式發出查詢:瀏覽器可能使用內建的安全 DNS;終端機程式通常會呼叫系統解析器。
  2. 請求進入解析器:請求可能送到路由器、系統 DNS,或 mihomo 的 DNS 監聽埠。
  3. 核心選擇上游:mihomo 會依解析策略選擇 DNS 伺服器,並依設定篩選回應。
  4. 應用程式建立連線:核心接著依代理規則,為後續連線選擇出口。

認識 dns 區段:分開設定監聽、模式與上游

先了解各欄位的用途。下表中的埠號僅為本文範例,不代表每個用戶端的預設值;請以目前實際載入的設定為準。

欄位用途檢查重點
enable啟用核心 DNS 模組設為 true 後,仍須讓請求進入核心
listen開放 DNS 查詢監聽位址127.0.0.1:1053 僅供本機存取
enhanced-mode選擇增強解析模式常用 fake-ip 或 redir-host
default-nameserver解析 DNS 上游伺服器本身的網域名稱用來啟動解析流程,不代表所有業務網域都以此作為預設上游
nameserver設定一般解析上游清單順序不能直接理解成逐一故障切換
fallback提供可參與備援結果選擇的解析上游不只是主要上游逾時後才會使用的備用位址
fallback-filter決定何時採用備援解析結果可搭配網域名稱、GeoIP 與 IP 網段判斷

選擇 fake-ip 或 redir-host

先依相容性需求選擇模式。fake-ip 會為符合條件的查詢指派虛擬位址,並在核心中保存網域名稱對應資料。應用程式連線至這個位址時,核心可以找回網域名稱,再處理連線。範例中的 198.18.0.1/16 是虛擬位址池設定,不是要填入公共 DNS 的伺服器位址。

若程式需要取得真實解析位址,可考慮針對網域加入 fake-ip-filter,或改用 redir-host 比較。後者會回傳真實解析位址。切換模式後,請清除系統與應用程式的 DNS 快取並重新啟動舊連線;否則程式可能仍在使用切換前的位址,讓人誤以為「設定沒有生效」。

情境一:以最精簡設定測試 nameserver

先只啟用一組上游,等基本查詢正常後再加入 fallback。以下是獨立的診斷設定,使用本機混合代理埠 7890 與 DNS 埠 1053。這份設定沒有訂閱節點,最後的規則全部設為直連,目的是測試 DNS 流程,並非完整的代理方案。

mixed-port: 7890
allow-lan: false
mode: rule
log-level: info

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

rules:
  - MATCH,DIRECT

若要保留現有訂閱,只合併這裡的 dns 區段,不要用範例中的 rules 覆蓋原有的分流規則。YAML 同一層級不可出現兩個 dns:,縮排請使用空格。設定檢查通過後,再透過用戶端重新載入核心設定。

認識 DoH 與啟動解析

先辨認上游位址使用的協定。https://dns.alidns.com/dns-query 是 DoH,也就是透過 HTTPS 傳送 DNS 查詢;使用一般 IP 位址的上游通常採用傳統 DNS。DoH 加密的是用戶端與該解析服務之間的查詢傳輸,不代表後續所有網站連線都會經過代理。

先確保能解析上游伺服器的網域名稱,再處理一般業務網域。範例透過 default-nameserver 中的 IP 位址,啟動 DoH 伺服器網域名稱的解析,避免陷入「必須先連上 DoH,才能得知 DoH 位址」的循環。公共解析服務能否連線取決於目前的網路環境,不應將任何單一位址視為通用解法。

情境二:設定 fallback 與 fallback-filter

新增伺服器前,先了解備援結果的選擇方式。設定 fallback 後,不能把它當成一般網路設備裡的「第二組 DNS」。一般與備援上游可能會同時參與解析;是否採用備援結果,取決於篩選條件、解析狀態等因素,並非單純等到第一個位址逾時。

以下片段用來取代上一份設定中的整個 dns 區段。範例示範如何依 GeoIP 判斷一般上游的結果,並將 240.0.0.0/4 列為需要改採備援結果的網段條件。

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
  fallback:
    - https://cloudflare-dns.com/dns-query
  fallback-filter:
    geoip: true
    geoip-code: CN
    ipcidr:
      - 240.0.0.0/4

逐項檢查篩選條件

  • 檢查地區判斷:geoip: true 會啟用 IP 地理位置判斷。geoip-code: CN 表示一般解析結果不符合指定地區時,系統會傾向採用備援結果。這不是「中國大陸網域一律直連」的代理規則。
  • 檢查位址網段:ipcidr 是 IP 網段清單。一般上游回傳的位址若符合這些篩選網段,就會觸發備援結果選擇。請勿任意加入所有企業內網網段,否則可能導致內部服務解析異常。
  • 檢查資料依賴:GeoIP 判斷需要可用的地理資料。若資料缺漏或版本過舊,請先處理核心日誌中的載入問題,不要只靠反覆更換 DNS 伺服器來掩蓋原因。
  • 檢查兩條連線:備援 DoH 也必須能連線。主要上游能正常回應,不代表備援上游的連線也正常。

若要指定特定網域使用固定的解析上游,優先了解 nameserver-policy 這類依網域指定解析器的機制,而不是一再擴大備援篩選網段。企業網域尤其應交由企業 DNS 解析,因為公共解析器可能完全沒有內網記錄。

請分別檢查 DNS 上游連線與網站連線使用的出口,兩者並不相同。若要讓 DNS 上游連線遵循路由規則,可進一步設定 respect-rules,並依目前核心的要求設定 proxy-server-nameserver,用來解析代理伺服器網域名稱,避免代理連線與 DNS 解析互相等待。本文的最精簡範例不會啟用這組進階設定。

情境三:透過 TUN 的 dns-hijack 接管 53 埠

先確認欄位放在正確層級。dns-hijack 屬於頂層的 tun 區段,不是 dns 區段。TUN 是虛擬網路介面,核心會透過它處理路由進來的 IP 流量;這裡的 DNS 劫持是指將符合條件的 DNS 請求重新導向核心 DNS 模組。

保留現有設定中的 dns 區段,再合併下方的 tun 區段。啟用前請確認用戶端具備所需的系統管理員或服務權限,並避免另一個 VPN 同時接管預設路由。

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

分清楚兩條劫持規則。any:53 用來比對由 TUN 接管的 UDP 53 查詢;tcp://any:53 則涵蓋 TCP 53 查詢。這兩項設定描述的是要攔截的目標,不是要求將 DNS 監聽位址改成 any:53。實際能否攔截,也會受到系統路由、網路介面與平台限制影響。

確認接管範圍

  • 檢查瀏覽器安全 DNS:瀏覽器自行使用的 DoH 通常透過 HTTPS 的 443 埠傳輸,不會因為劫持 53 埠就自動變成核心 DNS 查詢。
  • 檢查加密 DNS:DoT 是透過 TLS 傳輸的 DNS,通常使用 853 埠,也不在上述兩條規則的涵蓋範圍內。
  • 檢查區域網路目標:送往路由器的 DNS 流量是否會進入 TUN,取決於路由設定,不能假設所有區域網路請求都會被攔截。
  • 檢查監聽範圍:在個人電腦上測試時,優先使用回送位址監聽。不要為了讓 TUN 生效,就將 DNS 無條件開放給所有網路介面。

依序驗證解析、接管與規則

先測試核心監聽,再測試日常連線。這樣才能分辨是「DNS 模組本身沒有回應」,還是「系統查詢沒有送進來」。以下命令僅示範檢查方式,不代表任何公共解析器在目前網路環境下的實測速度。

第一步:直接查詢 1053 埠

在已安裝 dig 的 Linux 或 macOS 環境中執行下列兩個命令,分別測試 UDP 與 TCP。Windows 可使用後面的 nslookup 命令指定埠號。

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

先確認是否逾時,再檢查回應類型。啟用 fake-ip 時,符合條件的 A 查詢若回傳虛擬位址池中的位址,屬於正常情況,不能據此判定上游回傳了錯誤 IP。若要比對真實解析結果,可暫時改用 redir-host,重新載入設定並清除快取後,再執行相同查詢。

第二步:透過系統預設路徑查詢

nslookup example.com

比較明確指定的查詢與預設查詢。如果 1053 埠查詢正常,但預設查詢逾時,應優先檢查系統 DNS、TUN 路由與安全軟體,而不是立刻更換 nameserver。啟用劫持後,命令顯示的 DNS 伺服器名稱可能仍是原本的目標;請搭配核心日誌確認實際處理請求的對象。

第三步:清除快取,再檢查連線出口

Windows 可執行 ipconfig /flushdns;使用 systemd-resolved 的 Linux 可執行 resolvectl flush-caches。接著重新啟動瀏覽器或關閉舊連線,並在用戶端的連線面板檢查網域名稱、命中規則與出口。瀏覽器自身的快取與連線重用,不一定會隨系統快取一併清除。

若需要更多線索,可暫時將 log-level 設為 debug,重現一次問題後再改回 info。分享日誌前,請刪除訂閱網址、驗證資訊與敏感網域名稱。日誌有助於找出上游逾時、監聽失敗與路由問題,但不應公開完整的執行設定。

常見問題:依照現象縮小排查範圍

現象優先檢查項目下一步處理方式
本機 1053 查詢逾時DNS 是否已啟用、埠號是否衝突、設定是否已重新載入檢查啟動日誌,再執行設定語法檢查
1053 查詢正常,一般查詢失敗系統 DNS 路徑與 TUN 路由確認請求是否進入核心,不要先更換備援上游
瀏覽器與終端機的查詢結果不同瀏覽器安全 DNS、各自的快取、代理擴充功能暫時統一解析路徑,再查詢相同網域
無法存取內部網站公共 DNS 沒有內部記錄、虛擬位址相容性為內部網域指定企業解析器,必要時加入 fake-ip 篩選
啟用 fallback 後查詢變慢備援上游連線狀況與篩選條件命中範圍先恢復單一上游的基準設定,再逐項還原篩選條件
訂閱更新後設定恢復原狀用戶端產生的設定覆蓋了手動修改將變更移至支援的覆寫設定,並確認最後產生的結果

最後確認三件事:請求是否進入核心、上游是否正確回應,以及後續連線是否符合預期規則。一次只變更一項條件,並保留修改前後的設定與查詢結果。如此排查 nameserver、fallback 或 dns-hijack 時,才能確認究竟是哪項設定解決了問題。

下載Clash選擇用戶端平台