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、節點和規則更容易找出原因。
- 應用程式發出查詢:瀏覽器可能使用內建的安全 DNS;終端機程式通常會呼叫系統解析器。
- 請求進入解析器:請求可能送到路由器、系統 DNS,或 mihomo 的 DNS 監聽埠。
- 核心選擇上游:mihomo 會依解析策略選擇 DNS 伺服器,並依設定篩選回應。
- 應用程式建立連線:核心接著依代理規則,為後續連線選擇出口。
認識 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 時,才能確認究竟是哪項設定解決了問題。