規則結構與生效條件
Mihomo 的 rules 是依序排列的規則清單。常見格式為 規則類型,比對內容,目標策略;最後的預設規則寫作 MATCH,目標策略。目標可以是內建的 DIRECT、REJECT,也可以是設定檔中已定義的代理或策略群組名稱。
規則決定連線交由哪個目標處理,不會自動接管系統的所有流量。瀏覽器使用系統代理、應用程式手動指定代理,或用戶端透過 TUN 接管連線,都會影響核心能否看見請求。如果連線清單中完全沒有該應用程式的流量,請先檢查流量接入方式,再修改規則。
先確認三項條件
- 目前模式為
rule。Global 模式不會依照這份一般規則清單逐條分流;Direct 模式則會直接連線。 - 編輯的是目前正在使用的設定檔,而且已儲存並重新載入。用戶端編輯器中的文字不一定等於核心實際載入的內容。
- 所有目標策略都確實存在。例如規則使用
PROXY,設定檔中就必須有同名的代理或策略群組,大小寫與空格也要一致。
mode: rule
rules:
- DOMAIN,example.com,DIRECT
- DOMAIN-SUFFIX,example.org,DIRECT
- MATCH,PROXY
以下是合併至現有設定檔的片段,並非包含節點、DNS 與監聽連接埠的完整設定檔。範例假設現有策略群組名稱為 PROXY;如果實際群組名稱是「節點選擇」,就應將對應目標改為該群組名稱。example.com 與 example.org 是文件範例網域,實際使用時請依照需要分流的服務修改。
DOMAIN 類規則:精確比對、網域後綴與關鍵字
網域規則適用於網站與使用網域提供服務的 API。選擇規則類型時,應先確認比對範圍,不要把所有網域都寫成關鍵字。關鍵字範圍太廣,容易連名稱相近但無關的服務也一起分流。
| 類型 | 範例 | 比對範圍 |
|---|---|---|
| DOMAIN | DOMAIN,api.example.com,DIRECT |
只比對 api.example.com 這個網域 |
| DOMAIN-SUFFIX | DOMAIN-SUFFIX,example.com,DIRECT |
example.com 及其子網域 |
| DOMAIN-KEYWORD | DOMAIN-KEYWORD,example,DIRECT |
網域名稱中包含 example 的目標 |
規則中不需要填寫通訊協定與頁面路徑
DOMAIN 的比對內容應為網域名稱,而非完整 URL。將 https://api.example.com/v1 放入 DOMAIN 規則,無法依網頁路徑分流。一般網域規則也無法區分同一網域下的不同頁面。
rules:
- DOMAIN,api.example.com,PROXY
- DOMAIN-SUFFIX,example.com,DIRECT
- MATCH,PROXY
這組規則會先將 api.example.com 交由 PROXY 處理,其餘 example.com 子網域則直接連線。這取決於規則的排列順序,而不是 DOMAIN 自動享有較高優先序。若對調前兩行,網域後綴規則會先符合,精確規則就沒有機會執行。
GEOSITE 與規則集:分類不等於固定清單
GEOSITE 使用網域分類資料。例如 GEOSITE,cn,DIRECT 表示符合目前 geosite 資料中名為 cn 的分類。它不會依網站伺服器所在地判斷,也不代表能識別所有中文網頁。實際比對範圍取決於使用的資料來源及其更新狀態。
rules:
- DOMAIN,api.example.com,PROXY
- GEOSITE,cn,DIRECT
- GEOIP,CN,DIRECT,no-resolve
- MATCH,PROXY
GEOSITE用於網域分類,GEOIP用於目標 IP 所屬分類,兩者不能互換。- 引用前請確認相關資料可用。缺少資料檔、下載失敗或分類名稱不存在,都可能導致載入錯誤。
- 自訂例外規則應放在分類規則之前。例如某個網域需要走代理,就不要把它排在已涵蓋該網域的直連分類之後。
RULE-SET 必須先定義 provider
RULE-SET 會引用 rule-providers 中的名稱。以下範例使用本機檔案,避免將遠端下載問題與比對問題混為一談。檔案路徑是相對於核心的工作目錄;用戶端可能也會限制可存取的位置。
rule-providers:
local-direct:
type: file
behavior: domain
format: yaml
path: ./rules/local-direct.yaml
rules:
- RULE-SET,local-direct,DIRECT
- MATCH,PROXY
對應的 local-direct.yaml 內容如下:
payload:
- 'example.com'
- '+.example.org'
behavior: domain 的 payload 填寫網域比對項目;+.example.org 涵蓋該網域及其子網域。若使用 behavior: classical,payload 則應填入 DOMAIN-SUFFIX,example.org 等規則運算式,出口通常由外層 RULE-SET 指定。不要混用這兩種內容格式,也不要只憑副檔名判斷規則集類型。
IP-CIDR 與 no-resolve:比對目標位址
IP-CIDR 比對 IPv4 位址範圍,IP-CIDR6 比對 IPv6 位址範圍。斜線後方是前綴長度:/32 代表單一 IPv4 位址,/24 則代表包含 256 個位址的網段。這裡判斷的是目標位址,而非發出連線的裝置來源位址。
rules:
- IP-CIDR,192.168.0.0/16,DIRECT,no-resolve
- IP-CIDR,10.0.0.0/8,DIRECT,no-resolve
- IP-CIDR,172.16.0.0/12,DIRECT,no-resolve
- IP-CIDR6,fc00::/7,DIRECT,no-resolve
- MATCH,PROXY
no-resolve 不會關閉 DNS
no-resolve 表示目前這條 IP 類規則不會主動觸發網域解析。如果連線已有可用的目標 IP,仍可進行比對;若連線只有網域名稱、尚無可用 IP,就可能略過這條 IP 判斷,繼續檢查後續規則。它不是全域 DNS 開關,也不保證網域在其他階段完全不會被解析。
因此,替 IP 規則加上 no-resolve 後,不能假設某個網域一定會依最終解析出的位址分流。若要讓內網網域明確直連,通常還需要設定相應的網域規則,並確認核心 DNS 能透過正確的內網解析器取得位址。
PROCESS-NAME:程序辨識與權限限制
PROCESS-NAME 依程序名稱比對,適合需要讓整個應用程式使用同一出口的情境。它仰賴核心從作業系統取得程序資訊,而不是根據網域推斷應用程式身分。能否使用會受到作業系統、用戶端實作、執行權限與流量接入方式影響。
find-process-mode: strict
rules:
- PROCESS-NAME,curl,DIRECT
- PROCESS-NAME,curl.exe,DIRECT
- DOMAIN-SUFFIX,example.com,PROXY
- MATCH,PROXY
strict 是按需查詢程序的模式。排查時可以暫時改成 always,觀察能否取得程序資訊;確認後再依實際需求調整。程序名稱應以連線詳細資訊或系統中的實際執行檔名稱為準,不要直接照抄桌面捷徑名稱。
- Windows 常見的程序名稱會帶有
.exe;其他桌面作業系統的執行檔名稱可能不同。 - 瀏覽器、啟動器與下載工具可能會使用子程序。主視窗的名稱不一定與實際建立連線的程序名稱相同。
- 如果請求是經由另一個本機代理程式轉送,核心可能只能辨識轉送程序,無法還原最初發出請求的應用程式。
- TUN 可以接入更多應用程式的流量,但不代表所有平台都會提供完整的程序資訊;若程序欄位為空,請先檢查權限與平台支援情況。
將程序規則放在網域規則之前,代表該程序的連線會先依程序策略處理。如果希望瀏覽器中的特定網站直連、其他網站則走代理,請將網域例外規則放在瀏覽器程序規則之前。
比對順序:符合第一條規則與 MATCH 預設規則
就本文討論的一般規則清單而言,可以理解為「由上往下檢查,符合第一條規則後便選定目標」。核心不會為了尋找更長的網域後綴而略過已符合的規則,也不會自動將程序規則排到網域規則前面。
常見錯誤:範圍較大的規則蓋過精確規則
rules:
- DOMAIN-SUFFIX,example.com,DIRECT
- DOMAIN,api.example.com,PROXY
- MATCH,PROXY
在這個例子中,連線至 api.example.com 時會先符合第一行。修正方式是將精確例外移到網域後綴規則之前,而非重複新增相同規則。同樣地,排在前面的 GEOSITE、RULE-SET 或程序規則,也可能先行攔截後面的自訂項目。
建議的規則排列順序
- 少數明確例外:指定網域、指定程序或特殊位址。
- 區域網路與內網服務:依實際環境安排網域及位址範圍。
- 服務規則集與地區分類:涵蓋範圍較大,請先檢查規則是否互相涵蓋。
MATCH:放在最後作為預設規則,處理未符合前面規則的連線。
這個順序是維護建議,並非核心的強制要求。如果區域網路直連必須優先於某條程序代理規則,就應將區域網路規則排得更前面。MATCH 沒有比對內容欄位,寫成 MATCH,PROXY 即可;若放在清單中間,後續的一般規則就沒有機會符合。
符合策略群組不代表最終出口已確定。例如規則將連線交給 PROXY,但該群組目前選中 DIRECT,實際連線仍會直連。排查時應分別確認「符合哪條規則」以及「策略群組最後選擇哪個出口」。
規則未生效:依連線資訊逐項檢查
不要一次修改 DNS、TUN 和整份規則。請先選一個可重複存取的目標,記錄目標網域、請求時間、符合的規則、策略鏈與日誌錯誤,再一次只調整一個變因。不同用戶端的選單名稱不盡相同,請尋找對應的連線詳細資訊、執行記錄與目前設定檔檢視畫面。
- 確認連線已進入核心。發出新的請求後,在連線清單中搜尋目標網域或程序。若沒有記錄,請檢查系統代理、應用程式代理位址或 TUN 接管範圍。
- 確認監聽連接埠。若設定為
mixed-port: 7890,測試工具就應連線至127.0.0.1:7890,不要沿用其他用戶端的連接埠。 - 確認目前模式與載入結果。檢查模式是否為 Rule,並查看重新載入時是否出現 YAML、未知策略或規則集載入錯誤。
- 確認實際比對內容。檢查存取過程是否轉址至其他網域,或是否由多個靜態資源與 API 網域組成。只為頁面的主網域設定分流,不代表所有資源都會走相同路徑。
- 從符合的規則往前檢查。找出排在更前面的 DOMAIN-SUFFIX、GEOSITE、RULE-SET、程序規則或 MATCH,確認是否已提前攔截目標。
- 確認出口與新連線。檢查策略群組目前的選擇,並關閉舊連線或重新啟動測試應用程式。重新載入設定後,不應使用既有長連線作為新規則的測試樣本。
使用 curl 固定測試入口
以下命令適用於已啟用 mixed-port: 7890 的本機設定。--noproxy "" 會清空此次請求的代理略過清單,減少環境變數對測試的干擾;-I 會送出 HEAD 請求,主要用來觀察連線是否建立及符合哪條規則。Windows PowerShell 可使用 curl.exe 明確呼叫執行檔。
curl --noproxy "" -I --proxy http://127.0.0.1:7890 https://example.com
curl --noproxy "" -I --proxy socks5h://127.0.0.1:7890 https://example.com
socks5h 會將目標網域交由代理端解析,適合用來減少本機預先解析造成的差異。這兩條命令用於檢查明確設定代理的連線路徑,不代表已驗證 TUN 路徑。測試 TUN 時,需另行確認應用程式未使用明確代理,並參照用戶端連線記錄,判斷流量是否確實進入虛擬網卡。
| 現象 | 優先檢查項目 | 處理方式 |
|---|---|---|
| 儲存後設定檔無法重新載入 | 縮排、策略名稱、分類資料、規則集格式 | 依照日誌中的行號修正,並確認使用空格縮排 |
| 始終符合 MATCH | 網域是否一致、程序資訊是否可用 | 查看連線的實際欄位,不要只看網址列 |
| 符合 PROXY,連線卻仍是直連 | 策略群組是否選中 DIRECT 或巢狀直連群組 | 展開完整策略鏈,檢查最終出口 |
| 更新訂閱後自訂規則消失 | 是否直接編輯了訂閱產生的檔案 | 使用用戶端支援的持久化覆寫機制 |
訂閱更新與規則維護
訂閱可能提供完整設定檔,也可能只提供節點。直接修改由完整訂閱產生的檔案,下次更新時可能會被覆寫。如果用戶端提供覆寫、合併或指令碼處理功能,請先確認它如何處理 rules:是整份取代、插入前方,還是附加至末尾。
附加至末尾特別容易造成「規則存在卻沒有生效」。如果原始訂閱已用 MATCH 結尾,新增項目就必須放在最終生效設定檔的 MATCH 之前。不要只檢查覆寫編輯框,也應確認合併後的規則順序,並以新連線進行驗證。
保留可還原的修改紀錄
- 每次只新增一組用途明確的規則,並記錄目標網域、預期出口與新增原因。
- 將本機規則集與主要設定檔一併備份,避免只還原 YAML 卻遺失外部檔案。
- 更新用戶端或核心後,重新檢查程序辨識、規則集載入與重要例外規則,不要依賴舊連線的結果。
- 分享記錄前,請隱藏訂閱網址、節點驗證資訊與控制介面金鑰。排查時優先提供規則片段與符合資訊。
維護規則的關鍵,是讓比對範圍與排列順序清楚可查:精確例外要放在會涵蓋它的廣泛規則之前,預設規則放在最後,並透過連線詳細資訊確認實際符合結果。先確認流量入口,再檢查比對欄位,最後檢視策略鏈,通常比反覆切換模式更容易找出問題。