進階設定 閱讀時間約 12 分鐘

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

說明 nameserver、fallback、fallback-filter 與 dns-hijack 的設定方式,解析 fake-ip 和 redir-host 的差異,並提供可直接套用的 YAML 範例。

DNS 設定的三個環節:入口、解析與連線

排查 Clash Meta(mihomo)的 DNS 問題時,請先釐清三個環節:應用程式將查詢送給誰、核心向哪個上游查詢,以及取得結果後連線會套用哪條規則。網頁無法開啟,問題可能出在其中任何一個環節。只更換 nameserver,無法解決系統未將 DNS 請求送進核心的問題。

  • 入口:dns.listen 開啟核心的 DNS 監聽連接埠;使用 TUN 時,dns-hijack 會接管符合條件的 DNS 流量。
  • 解析:nameserver、fallback 和 nameserver-policy 決定查詢哪些上游,以及如何選擇結果。
  • 連線:應用程式取得 IP 位址後發起連線,核心再依代理模式、規則與策略群組處理流量。

系統 HTTP 代理通常不會自動接管所有應用程式的 DNS。瀏覽器的安全 DNS、Android 私人 DNS,以及應用程式內建的 DoH,也可能使用獨立通道。因此,「已啟用系統代理」不代表「所有 DNS 查詢都經過 Mihomo」。

nameserver 與 default-nameserver:上游與引導解析

nameserver 是一般網域查詢使用的上游伺服器清單。直接填入 IP 位址通常代表一般 DNS;https:// 表示 DoH,tls:// 表示 DoT。一般 DNS 常用連接埠為 53,DoT 預設使用 853,DoH 通常使用 HTTPS 的 443 連接埠。

上游若設定為 https://dns.alidns.com/dns-query,核心必須先取得 dns.alidns.com 的 IP 位址。default-nameserver 用來解析 DNS 伺服器本身的網域,屬於引導解析,不是「所有查詢優先使用的預設伺服器」。此欄位填入 IP 位址,可避免一開始就依賴尚未解析的網域名稱。

欄位用途常見誤解
listen設定本機 DNS 監聽位址與連接埠設定後系統就會自動使用
default-nameserver解析 DNS 上游伺服器的網域名稱它是所有網域的優先解析伺服器
nameserver處理一般 DNS 查詢多個位址一定會依清單順序逐一嘗試
proxy-server-nameserver專門解析代理節點的網域名稱它負責所有透過代理造訪的網站
nameserver-policy為符合條件的網域指定解析上游它會直接決定網站連線使用哪個節點

代理節點本身若使用網域名稱,也需要 DNS 解析。可以透過 proxy-server-nameserver 指定可連線的上游,避免陷入「必須先連上代理,才能解析代理位址」的循環。這和網站連線的規則分流是兩回事,不能互相取代。

fallback 與 fallback-filter:並行查詢後如何選擇結果

不要把 fallback 簡單理解為傳統的「主要 DNS 逾時後才啟用的備用伺服器」。在需要搭配 fallback 選擇結果的一般解析流程中,核心會同時向相關上游發出查詢,再依篩選條件判斷是否採用 fallback 的結果。因此,加入 fallback 可能會讓同一次網域查詢送到兩組解析服務。

三種常用篩選條件

  • geoip:啟用依 IP 位址所屬地區進行判斷的功能;搭配 geoip-code 指定地區代碼。例如設為 CN 時,一般解析結果不符合該地區條件,就會改採 fallback 結果。此判斷仰賴 GeoIP 資料。
  • ipcidr:一般解析結果落在指定的 IP 網段時,改採 fallback。此條件比對的是 IP 位址範圍,不是網域名稱。
  • domain:符合條件的網域直接採用 fallback 結果。範例中的 +.github.com 表示根網域及其子網域。

以下完整 DNS 片段明確設定 geoip: false,僅示範網段與網域條件,避免初次設定時混入 GeoIP 資料更新問題。0.0.0.0/8 與 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
  fake-ip-filter-mode: blacklist
  fake-ip-filter:
    - localhost
    - "+.lan"
    - "+.local"

  default-nameserver:
    - 223.5.5.5
    - 119.29.29.29

  proxy-server-nameserver:
    - https://dns.alidns.com/dns-query

  nameserver:
    - https://dns.alidns.com/dns-query

  fallback:
    - https://cloudflare-dns.com/dns-query

  fallback-filter:
    geoip: false
    ipcidr:
      - 0.0.0.0/8
      - 240.0.0.0/4
    domain:
      - "+.github.com"

此範例要求列出的上游伺服器在目前網路與路由條件下都能連線。DoH 使用加密傳輸,但加密不代表流量會自動經過代理;上游連線的實際路徑仍由相關設定決定。如果網路無法連上某個上游,請先改用已確認可連線的服務,不要一次加入多組未知位址。

fake-ip 與 redir-host:回傳給應用程式的位址不同

enhanced-mode: fake-ip 會針對適用的 DNS 查詢回傳映射位址。應用程式連線至該位址時,核心會透過映射找回網域名稱,再套用規則處理。範例中的 198.18.0.1/16 屬於基準測試專用位址範圍;看到此範圍的回應時,不應立刻判定 DNS 遭到污染。

redir-host 則會將實際解析到的位址回傳給應用程式,再透過網域名稱與 IP 位址的關聯協助處理連線。這種方式較接近傳統 DNS 行為,但遇到共用 IP、多個網域指向同一位址,或應用程式使用快取時,網域關聯可能不如 fake-ip 直接。

項目fake-ipredir-host
應用程式取得的位址通常是映射位址,排除篩選項目上游回傳的實際位址
適合優先測試的情境TUN 接管與依網域進行規則分流應用程式必須取得實際位址的相容性情境
檢查重點連線是否也回到持有映射資料的核心DNS 解析結果與連線是否仍能互相關聯

篩選清單只會改變回傳位址的方式

範例中的 fake-ip-filter-mode: blacklist 表示清單中的比對項目不會回傳 fake-ip。為區域網路後綴加入篩選,可避免向這些名稱回傳映射位址,但不保證名稱一定能解析。.local 通常與 mDNS 有關;區域網路裝置也可能只登記在路由器 DNS 中,公用 DNS 並不知道這些名稱。

因此,NAS 名稱仍無法解析時,應先確認它仰賴 mDNS 還是路由器 DNS,再決定是否加入區域網路解析策略。不要為了迴避問題而將所有網域都加入篩選。切換兩種模式後,也應清除舊 DNS 快取並重新建立連線,避免應用程式繼續使用先前取得的位址。

TUN 的 dns-hijack:接管連接埠 53 的查詢

dns-hijack 位於頂層的 tun 區段,不在 dns 區段內。以下片段適用於支援相應 TUN 設定的桌面用戶端。此設定需要建立 TUN 的權限;用戶端也可能透過服務模式或權限輔助程式管理相關設定。

tun:
  enable: true
  stack: mixed
  auto-route: true
  auto-detect-interface: true
  dns-hijack:
    - any:53
    - tcp://any:53
  • any:53 會接管進入 TUN 且符合條件的 UDP 53 連接埠 DNS 查詢。
  • tcp://any:53 會一併接管 TCP 53 連接埠,涵蓋使用 TCP 的一般 DNS 查詢。
  • auto-route 用於自動設定相關路由,但能否涵蓋特定應用程式,仍取決於系統路由與用戶端實作。
  • auto-detect-interface 用於自動偵測出口網路介面;使用多張網卡或特殊路由時,仍須確認實際出口。

此處的「any」不代表能攔截網路上的所有 DNS。只有進入接管路徑的流量才有機會被處理;瀏覽器透過 HTTPS 443 連接埠傳送的 DoH,也不會因此自動轉成一般 DNS。DoT 的 853 連接埠同樣不在上述兩個比對項目內。

範例中的 DNS 監聽位址為 127.0.0.1:1053,適合在本機測試。一般系統 DNS 設定介面通常只接受位址,不接受自訂連接埠;直接填入 127.0.0.1 會查詢連接埠 53,而不是 1053。TUN 內部的 DNS 劫持與手動設定系統 DNS 是兩種不同的入口,請勿混為一談。

依序驗證:監聽、上游、接管與規則

第一步:確認最終設定與監聽連接埠

重新載入設定後,先查看用戶端記錄,確認是否有 YAML 解析失敗、不支援欄位或連接埠綁定失敗等訊息。重點檢查最終設定中的 dns.enable、listen 與 enhanced-mode。各用戶端的選單名稱不盡相同,請找出實際執行設定或設定預覽,不要只查看訂閱原始內容。

在 macOS、Linux 或已安裝 dig 的環境中,可直接向連接埠 1053 發出查詢。第一個測試使用 UDP,第二個使用 TCP;這些是驗證指令,不代表已預先測得特定結果。

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

在 fake-ip 模式下,未被篩選的 A 記錄查詢通常會回傳映射範圍內的位址。這只能確認目前的 DNS 入口有回應,無法單獨證明遠端網頁可正常存取。還須確認連線是否進入同一個核心,以及節點是否能建立連線。

第二步:判斷是上游無法連線,還是入口未被接管

  1. 指定連接埠 1053 查詢也逾時:先確認監聽是否成功,再檢查上游連線錯誤。必要時暫時只保留一個已確認可連線的 nameserver,縮小排查範圍。
  2. 指定連接埠 1053 有回應,但應用程式仍使用其他 DNS:檢查 TUN 是否啟用、路由是否生效,以及瀏覽器的安全 DNS 是否使用其他通道。
  3. 網域可以解析,但網頁仍無法開啟:檢查連線記錄中的規則命中結果、策略群組選擇與節點錯誤,不要再盲目更換 DNS。
  4. 只有區域網路名稱無法解析:確認路由器 DNS 或 mDNS 的解析路徑,並檢查是否需要專用的區域網路策略。

第三步:清除快取後重新測試

Windows 可在終端機執行 ipconfig /flushdns。macOS 可依序執行以下兩個指令,第二個指令需要管理員授權。瀏覽器與應用程式可能也有自己的快取;清除系統快取後,請關閉舊連線,再重新嘗試連線。

sudo dscacheutil -flushcache
sudo killall -HUP mDNSResponder

要確認 DNS 查詢是否仍送往非預期的伺服器,應同時觀察系統、瀏覽器與核心的實際行為。只看到 DoH 位址,或只造訪一次 DNS 檢測網站,都不足以說明所有程序的解析路徑。fallback 的並行查詢、瀏覽器獨立使用的 DoH,以及系統背景請求,都需要分開判斷。

合併設定與後續調整

同一個 YAML 檔案不要重複加入兩個頂層 dns: 或兩個 tun:。重複的鍵值可能會遭解析器拒絕,也可能讓其中一段覆蓋另一段。請將範例欄位合併到現有區段,並確認用戶端套用覆寫的順序;訂閱更新後,再檢查執行中的設定是否保留。

  • 先建立可用的基準設定:確認單一上游可以連線,且本機 1053 查詢正常,再加入 fallback 與 TUN 接管。
  • 再處理特定網域:需要依網域指定解析上游時,使用 nameserver-policy;需要設定連線分流時,修改 rules,並分別驗證兩者。
  • 最後處理 IPv6:範例中的 dns.ipv6: false 用於停用 DNS 的 AAAA 回應,不代表停用作業系統的所有 IPv6 功能,也不會阻止應用程式使用已取得的 IPv6 位址。
  • 保留復原步驟:若發生整體斷網,先停用 TUN、還原原本的系統 DNS 與代理設定,再載入備份;不要繼續疊加未知設定。

若要進一步確認規則與 TUN 設定之間的關係,請參閱DNS 設定手冊與TUN 設定說明。排除問題的關鍵是每次只調整一個環節:先確認請求進入核心,再確認上游有回應,最後檢查連線規則。如此才能判斷是哪項修改解決了問題。

下載Clash