01 / POLICY
策略組類型與實際組合
先區分節點、策略組與最終策略
Clash 設定中的代理節點是具體的連線參數,策略組則是組織節點或其他策略組的方式,而規則行尾端寫的是最終策略名稱。三者名稱可能同時出現在介面中,但職責不同。例如訂閱提供多個節點時,可以先將它們放入名為「節點選擇」的 select 組,再讓「開發服務」、「串流媒體」等業務組引用「節點選擇」。規則只需指向業務組,不必逐條綁定特定節點。如此更換節點時不必修改規則,訂閱更新後也不必重新整理每一行的分流邏輯。
策略組名稱必須與規則目標完全一致,包括空格與大小寫。設定能成功解析,不代表策略一定存在:部分用戶端會在載入時直接提示找不到策略,另一些情況則要等規則命中後才會暴露問題。調整名稱後需要重新載入設定,接著在連線詳細資訊或日誌中確認規則命中的目標組。不要只憑網頁能否開啟來判斷,因為瀏覽器快取、現有連線重複使用與系統 DNS 快取,都可能讓舊結果暫時延續。
四種常用組別的職責
| 類型 | 選擇邏輯 | 適用位置 | 注意事項 |
|---|---|---|---|
select |
由使用者手動選擇 | 總入口、業務分組 | 不會自行切換,結果最容易控制 |
url-test |
定期測試並選擇回應時間較合適的候選項目 | 同類節點的自動選擇 | 測試結果只反映測試位址,不代表所有網站的使用體驗 |
fallback |
依候選順序選擇目前可用的項目 | 主備線路切換 | 順序代表優先級,不以最低回應時間為唯一目標 |
load-balance |
依策略將不同連線分配給多個候選項目 | 多出口並行使用 | 同一業務使用不同出口時,可能觸發登入風控 |
url-test 適合一組可互換的節點。常見參數包括測試位址 url、測試間隔 interval 與可接受差值 tolerance。間隔過短會產生額外連線並增加耗電,行動裝置尤其明顯;差值過小則可能讓選擇結果頻繁變動。測試位址應回傳穩定且容量很小的回應。測試成功只能表示從目前網路經候選節點連往測試位址的路徑可用,不代表目標業務的握手、地區判定或帳號狀態一定正常。
fallback 更重視順序,適合「優先使用主線路,主線路無法使用時才切換備援」的情境。相比之下,load-balance 會將並行連線分散到不同節點。需要維持來源位址穩定的登入、付款、即時通訊與長連線業務,不宜直接放入負載平衡組。即使使用一致性雜湊,也要理解網域變更、連線重建與規則變動仍可能導致出口改變。
一套易於維護的分層寫法
proxy-groups:
- name: 節點選擇
type: select
proxies:
- 自動選擇
- 故障轉移
- DIRECT
- name: 自動選擇
type: url-test
use:
- airport-main
url: https://www.gstatic.com/generate_204
interval: 600
tolerance: 80
- name: 故障轉移
type: fallback
use:
- airport-main
url: https://www.gstatic.com/generate_204
interval: 600
- name: 開發服務
type: select
proxies:
- 節點選擇
- 自動選擇
- DIRECT
- name: 最終匹配
type: select
proxies:
- 節點選擇
- DIRECT
這套結構將「如何選擇節點」與「業務要走哪裡」分開。use 引用的是 proxy-providers 名稱,而 proxies 引用的是具體節點或其他策略組名稱,兩者不能互換。訂閱節點很多時,優先使用 provider 搭配篩選條件維護候選項目,避免每次訂閱變更後手動修改 proxies。如果用戶端覆寫系統支援為策略組追加內容,也應維持相同層次:節點來源由 provider 管理,業務語意由本地策略組管理。
組別之間不能形成循環引用。例如「節點選擇」包含「自動選擇」,而「自動選擇」又將「節點選擇」寫入 proxies,就無法得到明確的最終出口。實際修改時可以從規則末端反向檢查:規則指向業務組,業務組指向總入口,總入口最終指向節點或 DIRECT。每條鏈都應能夠終止。對於 REJECT、DIRECT 這類內建策略,不需要再建立同名節點。
驗證策略組時,先在用戶端介面明確選取預期項目,再關閉目標應用程式中的現有連線並重新發起請求。接著查看連線記錄中的規則類型、規則內容、策略組與最終節點。如果介面顯示舊組名,通常表示目前執行中的設定尚未重新載入;如果組內缺少新節點,則檢查 provider 是否更新成功,以及篩選運算式是否排除了所有節點。更完整的規則優先級說明可繼續閱讀自訂規則語法與匹配優先級。
02 / RULE PROVIDERS
規則集訂閱化管理
將規則內容與主要設定分開
規則數量增加後,繼續把所有項目寫入主要設定的 rules,會帶來三個問題:更新設定容易覆蓋本地修改、重複網域難以追蹤,載入失敗時也難以判斷是哪一批規則出錯。rule-providers 用於宣告外部規則集的來源、行為類型、檔案路徑與更新週期,主要規則區只透過 RULE-SET 決定它在匹配順序中的位置,以及命中後使用哪個策略組。
規則集不會繞過由上而下的匹配機制。RULE-SET,developer,開發服務 放在中國大陸直連規則之前或之後,會直接改變重疊網域的結果。規劃時先確定業務優先級,再排列規則集,而不是依下載檔案的名稱或大小排序。高確定性的自訂網域通常放在前面,區域網路與必要的直連規則靠前,寬泛的地區集合靠後,最後用 MATCH 接住未命中的流量。
provider 欄位逐項說明
rule-providers:
developer:
type: http
behavior: domain
format: yaml
path: ./ruleset/developer.yaml
url: https://example.com/rules/developer.yaml
interval: 86400
private-network:
type: file
behavior: ipcidr
format: text
path: ./ruleset/private-network.txt
rules:
- RULE-SET,developer,開發服務
- RULE-SET,private-network,DIRECT,no-resolve
- GEOIP,CN,DIRECT
- MATCH,最終匹配
type: http 表示由核心依照 url 取得並快取,type: file 表示只讀取本地檔案。範例網域僅用於展示結構,實際使用時應替換為自己確認可存取的規則來源。path 是快取或本地規則檔案的位置,同一份設定中的 provider 不應共用同一路徑,否則後寫入的內容可能覆蓋先前檔案。相對路徑的基準取決於用戶端為核心設定的工作目錄;桌面用戶端通常會將它映射到自己的設定目錄,而不是使用者目前開啟的終端機目錄。
behavior 決定如何解讀規則載荷。domain 適合網域集合,ipcidr 適合 IPv4 與 IPv6 網段,classical 則允許每行攜帶完整的規則類型。選錯時,檔案可能成功下載,卻無法如預期匹配。例如含有 DOMAIN-SUFFIX,example.com 的 classical 內容若宣告為 domain,解析方式就不一致。先查看規則來源提供的原始格式,不要依檔案副檔名推測行為。
format 描述載荷編碼,常見有 yaml、text 或核心支援的二進位規則格式。不同格式的內容結構不同。YAML domain provider 常見寫法是頂層 payload 陣列;文字格式通常逐行儲存項目。如果訂閱來源明確提供 Mihomo 格式,應依說明選擇,不要把一般 hosts 檔案、廣告過濾語法或瀏覽器擴充功能規則直接當作 Clash 規則集。
interval 的單位是秒,用來控制檢查更新的週期,不代表設定載入後必須等待這段時間才會首次取得。週期不宜設定過短;規則來源的更新頻率通常不像節點狀態那麼高,頻繁拉取只會增加啟動與網路負擔。如果用戶端提供「更新規則集」操作,可以在修改來源後手動觸發一次,再從日誌確認 HTTP 狀態、解析結果與快取路徑。
網域集、IP 集與 no-resolve
網域規則在請求仍保留網域資訊時最直接。IP-CIDR 規則針對目標 IP;當一條 IP 規則後帶有 no-resolve,表示匹配該規則時不要為取得目標 IP 而主動解析網域。它不是「停用 DNS」,也不會阻止應用程式已經完成的解析。對純 IP 連線,核心仍可直接使用目標 IP 進行匹配。是否加入此參數,取決於前面的 DNS 與嗅探流程是否已提供足夠資訊,以及該規則是否值得觸發額外解析。
| 規則集內容 | behavior | 典型載荷 | 常見用途 |
|---|---|---|---|
| 網域與網域後綴 | domain |
example.com、+.example.org |
網站與服務分組 |
| IPv4/IPv6 網段 | ipcidr |
192.0.2.0/24 |
地區網段、私有網路 |
| 完整規則列 | classical |
DOMAIN-SUFFIX,example.com |
混合多種規則類型 |
更新失敗時的檢查順序
首先區分「下載失敗」與「解析失敗」。下載失敗通常會在日誌中出現連線、憑證、逾時或 HTTP 狀態相關資訊;解析失敗則多半表示檔案已取得,但欄位、縮排、行為類型或格式不符合要求。接著檢查 URL 是否能在目前網路路徑下存取。規則 provider 的下載流量如何路由,會受到目前核心啟動階段與設定影響;首次載入時若依賴尚未成功建立的策略,可能出現先後順序問題。
接著檢查快取目錄是否可寫入。桌面用戶端透過圖形介面管理設定時,不建議將 path 指向受系統保護的目錄。檔名應彼此唯一,目錄層級也不要依賴尚未建立的絕對路徑。最後確認主要規則中確實存在對應的 RULE-SET,名稱與 provider 鍵一致。provider 下載成功但未在 rules 中引用,只會佔用快取,不會參與分流。
當規則集來源不穩定時,應保留一份最小可運作設定:基本直連、必要代理與最終規則不要全部依賴遠端檔案。如此即使某個 provider 暫時無法更新,現有快取或本地基本規則仍能讓設定啟動。若要依中國大陸直連、其他流量代理的情境組織完整順序,可參考中國大陸與其他地區的規則分流設定思路,再依本章方法將穩定的大型集合拆分成 provider。
03 / DNS
DNS 設定最佳化與洩漏排查
理解 DNS 在分流鏈中的位置
DNS 設定不只是更換解析伺服器。啟用 Mihomo DNS 後,核心需要決定要向哪個上游查詢、查詢流量走哪條網路路徑、回傳真實位址還是 Fake-IP,以及解析結果如何參與規則匹配。應用程式可能直接向系統 DNS 發送請求,也可能自帶加密 DNS;瀏覽器還可能啟用安全 DNS。只有先確認請求是否進入核心,後續調整 nameserver 才有意義。
常見流程是:應用程式請求網域,系統或 TUN 將 DNS 請求交給核心,核心依網域規則選擇上游,取得結果或分配 Fake-IP,接著在建立連線時還原網域並執行分流。如果應用程式繞過系統解析,直接連到自己的 DNS 伺服器,就需要透過 TUN 路由、DNS 劫持或應用程式設定,將請求納入同一條路徑。僅將系統 DNS 位址改成某個公共服務,並不能自動保證所有查詢都遵循 Clash 策略。
一份便於排錯的基本設定
dns:
enable: true
listen: 0.0.0.0:1053
ipv6: false
enhanced-mode: fake-ip
fake-ip-range: 198.18.0.1/16
fake-ip-filter-mode: blacklist
fake-ip-filter:
- "*.lan"
- "localhost.ptlogin2.qq.com"
- "+.stun.*.*"
default-nameserver:
- 223.5.5.5
- 1.1.1.1
nameserver:
- https://dns.alidns.com/dns-query
- https://cloudflare-dns.com/dns-query
proxy-server-nameserver:
- https://dns.alidns.com/dns-query
direct-nameserver:
- https://dns.alidns.com/dns-query
respect-rules: true
default-nameserver 主要用於解析加密 DNS 上游本身的網域,因此通常填寫可直接存取的 IP 位址,避免出現「需要先解析 DNS 伺服器網域,但解析它又必須先連到該伺服器」的循環依賴。它不是所有業務網域的預設最終答案來源。nameserver 才是一般查詢的主要上游,既可使用 IP 形式的傳統 DNS,也可使用核心支援的加密 DNS 位址。
proxy-server-nameserver 用來解析代理伺服器本身的網域。節點位址若寫成網域,核心必須先取得其真實 IP 才能建立代理連線;這一步不能依賴尚未建立的代理鏈。該上游應能在目前直連環境中穩定存取。若節點位址本身就是 IP,此項的重要性會降低,但保留清楚的引導解析路徑仍有助於切換訂閱來源。
direct-nameserver 可為預計直連的網域指定解析路徑,搭配 respect-rules 時要特別注意規則與 DNS 之間的依賴。設定過於複雜時,可能發生查詢需要先知道規則,而規則又依賴查詢結果的情況。排錯階段建議先使用少量、確定可連線的上游,確認一般查詢與代理節點解析都正常,再增加依網域分流的 nameserver-policy。
精確使用 nameserver-policy
dns:
nameserver-policy:
"geosite:cn":
- https://dns.alidns.com/dns-query
"+.example.internal":
- 192.168.1.1
"rule-set:developer":
- https://cloudflare-dns.com/dns-query
nameserver-policy 依網域選擇解析上游,適合內部網域、特定服務或地區網域的解析需求。它決定的是「要向哪裡查詢」,不直接等同於連線流量的代理策略。網域由本地 DNS 解析,並不表示連線一定直連;最終仍由 rules 決定。相反地,透過遠端加密 DNS 取得位址,也不代表業務連線必須使用代理。將解析路徑與連線路徑分開理解,可以避免許多看似矛盾的匹配結果。
內部網域必須由路由器或企業 DNS 回答時,可以為明確的後綴指定區域網路 DNS。不要把寬泛的萬用字元都交給內部伺服器,否則離開該網路後會造成大量逾時。筆記型電腦經常切換網路時,可以將辦公網路專用規則放入獨立覆寫,必要時再啟用,而不是永久寫入所有情境的主要設定。
IPv6、快取與回退行為
ipv6: false 通常表示 DNS 模組不回傳 AAAA 結果,但不等同於在作業系統層級停用 IPv6。若應用程式透過其他解析路徑取得 IPv6 位址,或直接連線到 IPv6,仍可能繞過預期路徑。當網路沒有穩定的 IPv6、代理節點不支援 IPv6,或規則集只涵蓋 IPv4 時,先停用 DNS 的 IPv6 回傳有助於減少連線等待;確實需要 IPv6 時,則應同時檢查 TUN 路由、規則集與出口能力。
DNS 快取會讓修改後的結果無法立即反映。重新載入設定後,應清除用戶端內部快取;必要時再清除作業系統與瀏覽器快取,並重新建立連線。不要在同一個未關閉的瀏覽器分頁中持續重新整理來判斷規則,因為 HTTP/2、HTTP/3 與連線池可能繼續重複使用舊連線。可靠的方法是關閉目標應用程式連線、清除快取、重新載入設定,然後結合 DNS 日誌與連線記錄重新測試。
| 現象 | 優先檢查 | 常見原因 |
|---|---|---|
| 節點網域無法解析 | default-nameserver、proxy-server-nameserver |
引導解析循環或上游直連無法存取 |
| 內部網域無法開啟 | nameserver-policy、Fake-IP 篩選 |
內部網域查詢被送往公共上游 |
| 修改規則後仍沿用舊路徑 | DNS 快取、現有連線 | 舊解析結果與連線池仍在重複使用 |
| 部分應用程式未進入日誌 | 應用程式安全 DNS、TUN 路由 | 應用程式繞過系統 DNS 或代理設定 |
判斷 DNS 是否依預期運作時,應記錄四項事實:應用程式查詢的網域、請求進入核心的方式、實際使用的上游,以及連線最終命中的規則。若只有「檢測網站顯示某個 DNS」這一項,無法定位問題是由瀏覽器安全 DNS、系統快取、上游轉送還是核心設定造成。遇到複雜故障,可在說明中心依 DNS、系統代理與連線日誌的順序繼續核對。
04 / TUN & FAKE-IP
TUN 模式與 Fake-IP 協同運作
系統代理與 TUN 的涵蓋範圍
系統代理只會影響遵循作業系統代理設定的應用程式。瀏覽器與多數桌面軟體通常支援,但命令列工具、遊戲、虛擬機器、部分商店應用程式,以及自行實作網路堆疊的軟體可能忽略它。TUN 模式會建立虛擬網路介面,透過系統路由將更多 TCP、UDP 流量交給核心,因此涵蓋範圍更廣。代價是它會介入路由、DNS 與介面選擇,設定錯誤時造成的影響也比一般系統代理更明顯。
啟用 TUN 前,先確認一般代理模式下節點、規則與 DNS 都能正常運作。否則一旦進入 TUN,節點無法使用、DNS 循環與路由衝突會同時出現,難以判斷根本原因。建議順序是:先驗證節點連線,再驗證規則命中,接著啟用 TUN,最後才啟用 DNS 劫持與 Fake-IP。每次只改變一組變數,並保留可復原的設定副本。
TUN 基本參數
tun:
enable: true
stack: mixed
dns-hijack:
- any:53
- tcp://any:53
auto-route: true
auto-detect-interface: true
strict-route: true
mtu: 1500
dns:
enable: true
enhanced-mode: fake-ip
fake-ip-range: 198.18.0.1/16
stack 決定由哪種網路堆疊處理 TUN 流量。Mihomo 常見選項包括 system、gvisor 與 mixed。系統堆疊通常具有直接的效能路徑,gVisor 使用者態堆疊在部分平台或特殊網路下的相容性有所不同,mixed 則用於混合處理。不存在適合所有系統的固定答案;若預設設定穩定,就沒有必要只為追求參數複雜度而切換。遇到 UDP、區域網路存取或特定遊戲異常時,再將網路堆疊作為單獨變數進行對照測試。
auto-route 讓核心自動新增必要路由,auto-detect-interface 用於辨識目前的預設出口。筆記型電腦在有線、無線、個人熱點與 VPN 之間切換時,自動偵測通常更方便;伺服器、多網卡主機或策略路由環境則可能需要明確指定介面。若日誌顯示流量反覆進入 TUN,或代理節點連線本身又被送回 TUN,應檢查出口介面、路由排除,以及既有 VPN 是否形成迴圈。
strict-route 用於更嚴格地限制流量經過 TUN,在不同作業系統上的具體效果與權限要求有所差異。它有助於減少部分繞行,但也可能暴露原本由系統自動處理的路由衝突。啟用後若區域網路印表機、共用資料夾或虛擬機器網路無法存取,應先檢查私有網段規則與路由排除,而不是直接將所有區域網路位址加入代理策略。
dns-hijack 將指定連接埠的 DNS 流量交給核心。any:53 涵蓋常見的 UDP 查詢,補充 TCP 形式可處理截斷回應後的 TCP 重試。它無法自動攔截所有基於 HTTPS 或 TLS 的應用程式自帶 DNS;這類流量表面上是一般加密連線,需要透過應用程式設定、網域規則或完整路由路徑處理。是否需要劫持,取決於應用程式是否遵循系統 DNS。
Fake-IP 的運作原理
Fake-IP 模式收到網域查詢後,不會立即將真實目標位址交給應用程式,而是從保留位址池分配一個映射位址。應用程式連線到該位址時,核心會依映射還原原始網域,再執行網域規則與代理轉送。如此即使應用程式後續只攜帶 IP,核心仍保留網域脈絡,網域分流更穩定,也減少先在本地取得真實位址再決定策略的依賴。
198.18.0.0/15 屬於基準測試用途的保留位址範圍,常被 Fake-IP 使用。設定中的位址池不能與現有區域網路、容器網路、測試網路或企業路由衝突。如果目前網路恰好使用相同範圍,系統可能會將 Fake-IP 當成真實路由目標。此時需要更換不衝突的保留範圍,並重新啟動相關連線、清除 DNS 快取,確保不再使用舊映射。
某些協定需要真實位址,或會檢查 DNS 行為,不適合回傳 Fake-IP。常見對象包括區域網路主機名稱、STUN、網路連線能力檢測、特定遊戲探索協定與少數裝置控制服務。它們應放入 fake-ip-filter。篩選項目應盡量精確,先從日誌確認網域,再加入後綴或萬用字元模式。排除過大範圍的網域,會大幅降低 Fake-IP 保留網域資訊的優勢。
MTU、UDP 與區域網路存取
MTU 過大時,某些隧道、行動網路或多層 VPN 環境會發生分片與丟包,表現為網頁部分資源卡住、TLS 握手逾時或 UDP 不穩定;過小則會增加封包數量與處理負擔。不要只因某個網站速度慢就盲目降低 MTU。先確認問題是否只在 TUN 下出現,再比較不同網路與協定,觀察日誌是否有明顯重傳或握手失敗。每次調整幅度都應記錄,並在重新啟動 TUN 後測試。
區域網路存取應同時考慮規則與路由。規則中可將 RFC1918 私有網段、鏈路本地位址及實際區域網路網域設為 DIRECT,但 DIRECT 只決定連線不經過代理節點,不保證作業系統路由一定指向正確介面。若 TUN 自動路由搶佔區域網路路徑,還需檢查路由排除與嚴格路由設定。將代理分享給同網段裝置時,則需要額外設定監聽位址、allow-lan 與防火牆,可參閱混合連接埠與區域網路分享。
| 問題範圍 | 對照測試 | 下一步 |
|---|---|---|
| 僅系統代理正常 | 關閉 TUN 後恢復正常 | 檢查路由、介面偵測與權限 |
| 網域規則失效 | 檢查 Fake-IP 映射與嗅探結果 | 確認 DNS 是否真正進入核心 |
| 區域網路裝置無法存取 | 查看目標網段與出口介面 | 補上直連規則與路由排除 |
| UDP 應用程式異常 | 更換網路堆疊並單獨測試 | 檢查節點的 UDP 能力與 MTU |
05 / SNIFFER
網域嗅探與連線還原
嗅探能解決什麼問題
規則系統更擅長依網域分類,但部分應用程式建立連線時只向核心暴露目標 IP。網域嗅探會從連線早期資料中辨識 HTTP Host、TLS ClientHello 中的 SNI,或支援的協定中的目標網域,再使用還原出的網域參與規則匹配。它不會解密 HTTPS 內容,也不會讀取頁面內容;可見資訊來自協定握手階段原本就攜帶的網域欄位。
嗅探與 Fake-IP 都能保留網域脈絡,但路徑不同。Fake-IP 在 DNS 查詢階段建立網域與映射位址的關係;嗅探則在建立連線階段從協定資料還原網域。兩者可以同時啟用:Fake-IP 處理經過核心 DNS 的連線,嗅探則補足繞過該解析流程或直接使用目標 IP 的部分情境。如果 DNS 已穩定提供映射,不必將所有故障都歸因於嗅探。
依協定與連接埠限制範圍
sniffer:
enable: true
force-dns-mapping: true
parse-pure-ip: true
override-destination: false
sniff:
HTTP:
ports:
- 80
- 8080-8880
override-destination: true
TLS:
ports:
- 443
- 8443
QUIC:
ports:
- 443
skip-domain:
- "Mijia Cloud"
- "+.push.apple.com"
skip-src-address:
- 192.168.0.0/16
skip-dst-address:
- 192.168.0.0/16
parse-pure-ip 允許對最初呈現為純 IP 的目標連線嘗試嗅探,這正是許多依網域分流情境的補足方式。force-dns-mapping 與 DNS 映射協作,用於利用既有的映射關係。不同用戶端附帶的核心設定範本可能調整預設值,修改前應查看目前實際執行的設定,而不是只看訂閱原文。
override-destination 決定辨識出網域後,是否以嗅探結果覆蓋原始目標,供後續連線使用。啟用後可改善部分網域分流,但誤判的影響也會更直接。建議先在協定子項中針對 HTTP 等明確情境啟用,而不是一開始就全域覆蓋。修改後要檢查連線詳細資訊中的原始目標、嗅探網域與最終規則,確認變化確實符合預期。
連接埠範圍越寬,不代表辨識效果越好。嗅探器需要依協定解析連線前段資料,在明顯不是 HTTP、TLS 或 QUIC 的連接埠上強行嘗試,只會增加誤判與處理成本。常用連接埠以外的業務應依實際應用程式補充。例如某個內部 HTTPS 服務運作於 9443,可以將該連接埠加入 TLS 範圍;不應為了涵蓋它而將所有連接埠都交給 TLS 嗅探。
QUIC、ECH 與不可見邊界
QUIC 通常基於 UDP,能否辨識取決於核心、網路堆疊與握手資訊是否可用。瀏覽器可能在網路變更後退回 TCP/TLS,因此同一個網站的連線記錄可能出現不同協定。排查時應分別觀察 TCP 與 UDP,而不是只查看一次存取。如果節點或網路對 UDP 的支援不穩定,可以暫時關閉應用程式的 QUIC 作為對照,但這只是定位方法,不應取代對實際 UDP 路徑的檢查。
加密用戶端問候等機制會減少中間層可見的網域資訊。當握手中沒有可供辨識的明文網域時,嗅探無法憑空還原業務名稱。此時應依賴核心 DNS、Fake-IP 映射、應用程式程序規則或目標 IP 規則。設定目標應是讓多個可靠資訊來源互相補足,而不是要求嗅探涵蓋所有連線。
CDN 共用 IP 也是嗅探具有價值的原因之一。僅依 IP 判斷時,同一個位址可能承載多個完全不同的網域;依寬泛網段分流容易誤傷其他業務。如果能取得網域,就應優先使用網域規則。只有在連線確實沒有網域脈絡時,才退回 IP-CIDR、GEOIP 或最終規則。
跳過清單與誤判處理
skip-domain 用於跳過已知不適合嗅探或覆蓋目標的網域,skip-src-address 與 skip-dst-address 可排除特定來源或目標網段。智慧家庭、投放、區域網路探索與廠商推播服務出現異常時,應先透過日誌鎖定具體連線,再加入最小範圍的排除項目。直接跳過整個私有網路雖然簡單,卻可能讓需要網域分流的本地容器或開發環境失去資訊。
若辨識出的網域與應用程式預期不符,先檢查目標是否經過 CDN、重新導向或第三方靜態資源。一個頁面會同時連線到主網域、登入網域、圖片網域與統計端點,連線清單中出現多個名稱是正常現象。真正的誤判通常表現為原本可用的連線在啟用覆蓋後失敗,停用該協定的 override-destination 後即恢復,且日誌中的嗅探結果與憑證或服務目標明顯不一致。
| 日誌現象 | 含義 | 處理方向 |
|---|---|---|
| 目標只有 IP,未出現網域 | 沒有可用映射或協定資訊 | 檢查 DNS 路徑、連接埠範圍與協定支援 |
| 已辨識網域但仍命中 IP 規則 | 規則順序或覆蓋設定未採用網域 | 檢查網域規則位置與 override 設定 |
| 停用嗅探後應用程式恢復正常 | 可能是誤判或目標覆蓋不相容 | 縮小連接埠範圍並加入精確跳過項目 |
| TCP 正常、UDP 異常 | QUIC 路徑與 TLS 路徑不同 | 分別檢查 TUN、節點 UDP 與 QUIC |
程序規則可以作為補充,但不同平台取得程序資訊的能力、權限與準確性並不一致。行動裝置應用程式沙盒、系統服務與容器環境尤其需要謹慎。能以穩定的網域規則解決時,優先使用網域;沒有網域且程序資訊可靠時,再考慮程序;兩者都不可用時才使用 IP 範圍與最終規則。這樣的降級順序比將所有流量綁定到應用程式名稱更容易跨平台維護。
06 / OVERRIDES
本地覆寫與多訂閱合併
將遠端訂閱視為輸入,而不是直接當成成品
遠端訂閱主要提供節點,有時也包含策略組、規則與 DNS。直接修改訂閱產生的 YAML,下一次更新通常會覆蓋本地內容。更穩妥的結構是將訂閱當作可更新的輸入,把長期規則、策略命名、DNS 與 TUN 參數保存在本地覆寫層。用戶端每次更新訂閱後重新套用覆寫,執行中的設定因此能保持一致。
不同用戶端對覆寫的稱呼與能力不完全相同,可能呈現為腳本、擴充設定、合併設定或設定預處理。Clash Plus 等用戶端應以介面實際提供的設定入口為準。無論採用哪種方式,都要區分三份內容:遠端原始訂閱、本地覆寫來源與核心最終執行設定。排錯時最後一份最重要,因為介面儲存成功不代表合併結果符合預期。
合併映射與陣列的差異
YAML 映射由鍵值組成,例如 dns 下的 enable;陣列則由具有順序的項目組成,例如 rules 與 proxy-groups。映射通常可以依鍵覆蓋,陣列卻涉及替換、前置追加、後置追加與去重。若合併工具對陣列採用整體替換,本地只寫一條規則就可能刪除訂閱原有的全部規則;若採用追加,關鍵自訂規則放在末尾又可能永遠無法匹配。
因此應先確認用戶端的合併語意,再決定覆寫結構。規則陣列通常需要「前置」能力,讓精確的本地規則排在寬泛規則之前;策略組陣列常需要依名稱替換或追加;DNS 映射適合依鍵覆蓋。不要假設所有名為 Merge 的功能都實作相同的行為。更新用戶端或轉移平台後,應重新匯出最終設定進行比對。
# 本地維護的邏輯範例,具體合併入口以用戶端為準
prepend-rules:
- DOMAIN-SUFFIX,example.internal,DIRECT
- DOMAIN-SUFFIX,github.com,開發服務
override:
mode: rule
log-level: info
dns:
enable: true
enhanced-mode: fake-ip
append-proxy-groups:
- name: 本地服務
type: select
proxies:
- DIRECT
- 節點選擇
上面的 prepend-rules、override 與 append-proxy-groups 用於說明合併意圖,不是 Mihomo 主要設定的通用頂層鍵。實際用戶端可能使用圖形表單、JavaScript 處理腳本或自己的擴充語法。不要將這段直接貼入核心設定。真正交給核心的結果仍應是標準的 rules、proxy-groups 與 dns 等欄位。
使用 provider 組合多個節點來源
proxy-providers:
provider-a:
type: http
url: https://example.com/subscription/a
path: ./providers/a.yaml
interval: 21600
health-check:
enable: true
url: https://www.gstatic.com/generate_204
interval: 600
provider-b:
type: http
url: https://example.com/subscription/b
path: ./providers/b.yaml
interval: 21600
filter: "(?i)香港|HK|Hong Kong"
health-check:
enable: true
url: https://www.gstatic.com/generate_204
interval: 600
proxy-groups:
- name: 全部節點
type: select
use:
- provider-a
- provider-b
- name: 香港自動
type: url-test
use:
- provider-a
- provider-b
filter: "(?i)香港|HK|Hong Kong"
url: https://www.gstatic.com/generate_204
interval: 600
proxy-providers 能讓多個訂閱獨立更新、獨立快取,再由策略組透過 use 引用。它比直接拼接多份訂閱文字更容易定位問題:某個來源失效時,其他 provider 仍可載入。每個 provider 都必須使用不同的 path。訂閱連結屬於敏感設定,不應複製到日誌截圖、公開規則儲存庫或分享設定中;範例中的位址僅用於展示結構。
filter 通常依節點名稱篩選,正規表示式應配合訂閱的實際命名。篩選後組別為空,是多訂閱合併中很常見的故障。先查看 provider 實際載入的節點名稱,再測試運算式;不要只依地區中文名稱編寫。使用 (?i) 可在支援的運算式中忽略拉丁字母大小寫,但中文別名、旗幟符號與縮寫仍需依來源調整。
兩個來源存在同名節點時,介面辨識與策略引用可能產生歧義。最穩妥的做法是在預處理階段為節點加上來源前綴,或要求訂閱提供者維持唯一名稱。如果用戶端支援 provider 層級前綴,可以在合併層統一加上「A-」、「B-」等簡短標記。不要依節點排列位置來區分,因為訂閱更新後順序可能改變。
多訂閱更新的故障隔離
更新失敗時逐一檢查 provider,不要一次刪除全部快取。先看請求是否成功,再看 YAML 是否能解析,接著確認篩選後是否仍有節點,最後檢查策略組是否正確引用。某個 provider 失敗不應讓基本設定失去 DIRECT 與本地故障組。可以讓總入口同時包含多個獨立 provider 產生的組,以便單一來源異常時手動切換。
合併後的設定還要檢查連接埠衝突、策略重名與規則目標缺失。多份完整訂閱若直接合併,常會重複定義 mixed-port、external-controller、DNS 監聽位址,以及名為「節點選擇」的組。節點來源可以有多份,但控制連接埠與核心策略結構應只有一個權威定義。將這些全域欄位固定在本地層,遠端輸入只負責節點,維護成本最低。
| 內容 | 建議歸屬 | 原因 |
|---|---|---|
| 節點參數 | 遠端 provider | 需要隨訂閱更新 |
| 業務策略組 | 本地覆寫 | 名稱要與本地規則長期穩定對應 |
| DNS 與 TUN | 本地覆寫 | 取決於裝置與目前網路環境 |
| 大型公共規則集 | rule provider | 獨立更新並減少主要設定檔大小 |
| 少量精確規則 | 本地規則前段 | 便於控制優先級與快速修正 |
轉移用戶端時,不要只匯出訂閱連結。還應記錄本地策略組名稱、規則集來源、覆寫順序、Fake-IP 篩選與 provider 路徑。不同用戶端支援的擴充合併語法可能不同,但標準 Mihomo 設定部分可以重複使用。先在新用戶端建立最小設定,再逐層轉移 provider、策略、規則與 TUN,可避免一次匯入大量擴充欄位後無法啟動。
07 / CONTROLLER
外部控制面板與安全邊界
控制介面能做什麼
Mihomo 的外部控制介面可供圖形用戶端或網頁面板讀取執行狀態、切換策略、查看連線與日誌,並執行設定重新載入等操作。它不是一般的代理連接埠,權限明顯更高。桌面用戶端內建介面通常已透過本地控制介面管理核心;只有需要獨立網頁面板、遠端維運或讓其他工具接入時,才需要手動調整監聽範圍。
控制介面與面板靜態檔案是兩回事。external-controller 定義 API 監聽位址,external-ui 指向本地面板檔案目錄。瀏覽器開啟面板後,面板仍需連線到 API 才能顯示策略與連線。頁面能載入但資料為空,通常是控制位址、驗證、跨來源許可或協定不一致,而不是面板檔案本身損壞。
本機使用的最小設定
external-controller: 127.0.0.1:9090
secret: "your-password"
external-ui: ./ui
external-ui-name: metacubexd
external-controller-cors:
allow-origins:
- http://127.0.0.1
- http://localhost
allow-private-network: true
僅在本機管理時,應優先監聽 127.0.0.1。如此控制連接埠不會直接出現在區域網路介面上。secret 用於 API 驗證,範例值必須替換為自己的高強度隨機字串,並儲存在本機設定中。控制面板要求輸入密鑰時,使用的就是這個值。修改後需要重新啟動或重新載入核心,並同步更新面板連線設定。
external-ui 是面板靜態資源目錄。部分用戶端會自行下載並管理面板,使用者不需要手動設定;自行部署時則要確認目錄存在,且核心程序具有讀取權限。external-ui-name 是否生效取決於目前核心與下載機制;遇到介面仍顯示舊內容時,應檢查實際目錄、瀏覽器快取,以及用戶端是否覆蓋了該欄位。
CORS 許可決定哪些網頁來源能在瀏覽器中呼叫控制 API。允許來源應寫成精確的協定、主機與連接埠組合,而不是寬泛放開。面板透過本機靜態服務存取時,瀏覽器來源可能是 http://127.0.0.1:連接埠;直接透過檔案協定開啟則會有不同限制。先從瀏覽器開發者工具查看遭拒絕的 Origin,再增加精確項目。
區域網路管理的額外限制
external-controller: 0.0.0.0:9090
secret: "your-password"
external-controller-cors:
allow-origins:
- http://192.168.1.20:8080
allow-private-network: true
監聽 0.0.0.0 表示控制介面綁定所有可用網路介面,只有確實需要區域網路管理時才應這樣做。還要在系統防火牆中將來源限制在可信任網段或指定管理裝置,不能只依賴面板的登入輸入框。面板輸入的密鑰會用於呼叫 API,但網路層仍應先阻止不可信裝置接觸連接埠。
如果裝置會連線到公共 Wi-Fi,長期監聽所有介面的風險更高。可透過作業系統防火牆區分私人網路與公用網路,或在不需要時恢復迴路監聽。遠端跨網際網路管理不應直接暴露控制連接埠;更合適的方式是先建立受控的私人網路通道,再像存取區域網路服務一樣連線,並繼續保留 API 驗證。
代理連接埠的 allow-lan 與控制介面的監聽範圍並不等價。允許區域網路裝置使用 mixed-port,不代表控制 API 也必須對區域網路開放;反過來,控制介面監聽所有位址也不會自動讓代理連接埠可用。應分別檢查代理監聽、控制監聽、系統防火牆與驗證,避免為了修復其中一項而擴大另一項的存取範圍。
連線面板時的排錯路徑
第一步確認核心正在監聽預期的位址與連接埠。連接埠被其他程式佔用時,核心日誌通常會出現 bind 失敗;用戶端也可能自動改用自己的控制連接埠,因此最終值要以執行設定與日誌為準。第二步在同一台裝置上測試 API 是否可存取,再測試面板。若 API 本身無法存取,先處理監聽與防火牆,不必反覆清除瀏覽器快取。
第三步檢查驗證。回傳未授權通常表示密鑰為空、填寫錯誤,或面板沒有依要求傳送。注意複製時不要帶入額外空格,也不要將 YAML 外層引號當作密鑰內容。第四步檢查 CORS。瀏覽器主控台出現跨來源拒絕時,API 可能其實已經回應,只是瀏覽器不允許面板讀取;此時應加入面板的精確來源,而不是關閉所有來源限制。
第五步檢查協定與位址。HTTPS 頁面呼叫 HTTP 控制介面時,瀏覽器可能依混合內容規則阻止請求。面板填寫 localhost 時,它指向執行瀏覽器的裝置;如果面板在手機上開啟,localhost 就是手機,而不是執行 Mihomo 的電腦。透過區域網路存取時,必須填寫電腦在該區域網路中的位址,並確認防火牆允許來自手機的連線。
| 現象 | 可能層級 | 檢查動作 |
|---|---|---|
| 面板頁面無法開啟 | 靜態檔案或 Web 服務 | 檢查 external-ui 目錄與存取位址 |
| 頁面開啟但沒有資料 | API 位址、驗證或 CORS | 查看瀏覽器網路請求與主控台 |
| 本機可用,手機無法使用 | 監聽位址或防火牆 | 確認是否僅綁定 127.0.0.1 |
| 回傳未授權 | secret 不一致 | 重新填寫密鑰並檢查空格 |
| 切換策略後立即恢復 | 設定重新載入或用戶端託管 | 檢查用戶端是否重新套用訂閱設定 |
日誌、連線資訊與最小暴露
控制面板能顯示存取網域、目標位址、程序資訊與策略選擇,這些都屬於裝置的網路使用資訊。分享排錯截圖前,應遮蓋訂閱名稱、節點位址、控制密鑰、內部網路位址與和問題無關的存取記錄。日誌等級保持在足以排錯的範圍即可;長期啟用過於詳細的日誌會增加儲存與資訊暴露。
使用第三方面板前,應明確知道它只是 API 用戶端,不會取代核心設定。策略切換通常是執行狀態操作,重新載入設定後是否保留,取決於用戶端與組別類型。若要長期固定策略,應在本地設定或用戶端的持久化機制中設定,而不是只在網頁面板中點選一次。訂閱更新會重新產生策略組時,名稱變更也會使舊選擇無法恢復。
完成設定後進行一次閉環驗證:重新啟動用戶端,確認控制連接埠成功監聽;從允許的裝置開啟面板,使用密鑰連線;切換一個 select 組並觀察新連線;重新載入設定後確認狀態符合預期;最後從不受信任的網路介面測試連接埠無法存取。如此驗證的不只是「面板能開啟」,還包括驗證、存取邊界與設定持久化。
如果修改控制介面後用戶端無法啟動,先恢復為迴路位址並暫時移除外部 UI 擴充欄位,確保核心設定能夠載入,再逐項加回。常見原因包括連接埠佔用、YAML 縮排錯誤、用戶端已託管相同欄位,或面板目錄無效。其他啟動與設定載入問題可在說明中心依錯誤日誌查找;需要重新安裝時,前往下載頁選擇目前平台的用戶端。