Clash 自訂規則寫法詳解:匹配類型、語法格式與優先級順序
涵蓋 DOMAIN、DOMAIN-SUFFIX、IP-CIDR、PROCESS-NAME 等常用規則類型的語法與適用場景,重點講清自上而下的匹配優先級、no-resolve 參數與規則排序的實戰原則。
Clash 的分流能力最終都落在配置檔的 rules 欄位上。一條規則決定一類流量走哪個代理組,寫錯順序或用錯匹配類型,輕則某個網站分流不生效,重則整段代理組失效、DNS 解析異常。這篇文章按 mihomo 核心(Clash Meta)的實現,把常用規則類型逐一拆開講清楚語法與適用場景,再講清楚規則是怎麼「從上到下」生效的,最後給出一套可以直接照搬的排序思路。
規則系統的基本結構與生效順序
Clash 配置檔裡的 rules 是一個陣列,每一行是一條規則,格式統一為:
规则类型,匹配内容,策略组[,附加参数]
比如:
rules:
- DOMAIN-SUFFIX,github.com,🚀 节点选择
- IP-CIDR,192.168.0.0/16,DIRECT,no-resolve
- GEOIP,CN,DIRECT
- MATCH,🚀 节点选择
核心處理一條網路請求時,會按陣列順序從上往下逐條比對,一旦某條規則匹配成功,立即採用它指定的策略組,後面的規則全部跳過,不會繼續往下匹配。這個「命中即停止」的機制是整套規則系統裡最容易被忽略、也最容易出問題的一點——很多人以為規則是「誰更精確誰生效」,實際上完全取決於寫在前面還是後面。
正因為如此,規則檔案末尾幾乎總會看到一條 MATCH,策略组 兜底,它代表「以上所有規則都沒有命中時的預設走向」,相當於分流表的最後一行,必須放在陣列最末尾,放在前面會導致後面所有規則永遠失效。
常用匹配類型逐一拆解
mihomo 支援的規則類型很多,但日常配置裡高頻出現的其實就下面幾類,按匹配對象可以分成域名類、IP 類、地理位置類和進程類。
域名類:DOMAIN / DOMAIN-SUFFIX / DOMAIN-KEYWORD
DOMAIN,www.example.com,策略组—— 精確匹配單個完整域名,子域名不會被命中,適合只想單獨處理某一個具體域名的場景。DOMAIN-SUFFIX,example.com,策略组—— 匹配該域名及其所有子域名(www.example.com、api.example.com都算命中),日常配置裡最常用的一種,寫一條規則能覆蓋一整個域名體系。DOMAIN-KEYWORD,example,策略组—— 只要域名中包含這個關鍵字就命中,匹配範圍最寬,容易誤傷無關域名,建議只在關鍵字足夠特殊、不會與其他服務重名時使用。
IP 與網段類:IP-CIDR / IP-CIDR6
IP-CIDR,192.168.1.0/24,DIRECT,no-resolve 這類規則按 CIDR 網段匹配目標 IP,常用於把局域網段、內網伺服器、CDN 固定 IP 段直接放行或強制走某條線路。IPv6 地址對應 IP-CIDR6,寫法完全一致。這類規則通常需要放在規則表靠前的位置,因為很多局域網存取一旦被域名規則或 GEOIP 規則先行攔截,反而會繞一圈走代理。
地理位置類:GEOIP
GEOIP,CN,DIRECT 依賴 GeoIP 資料庫判斷目標 IP 所屬國家或地區,常見寫法是把 GEOIP,CN 對應到直連策略,讓中國大陸 IP 不走代理。這類規則天然放在整個規則表偏後的位置,因為它的匹配範圍極寬,一旦放在前面會把大量本應細分處理的流量提前「收編」掉。
進程類:PROCESS-NAME / PROCESS-PATH
PROCESS-NAME,com.apple.WebKit.Networking,DIRECT 按發起請求的進程名匹配,常用於給特定用戶端單獨指定策略,比如讓某個下載工具始終直連,或者讓某個應用始終走特定節點。桌面平台上進程類規則的粒度最細,但要注意進程名在不同系統、不同版本之間可能有差異,不生效時優先檢查名稱是否寫對。
邏輯組合與兜底:AND / OR / NOT / MATCH
mihomo 還支援邏輯規則,把多個子條件組合成一條,例如:
- AND,((DOMAIN-SUFFIX,example.com),(NETWORK,tcp)),策略组
這類寫法適合需要同時滿足多個條件才生效的精細場景,日常配置裡出現頻率不高,但了解語法結構對讀懂社群分享的規則集很有幫助。最後,MATCH,策略组 是唯一不需要匹配內容的規則類型,代表兜底策略,規則表裡只應該出現一次,且必須在最後一行。
no-resolve 參數與 DNS 解析時機
IP-CIDR 與 IP-CIDR6 規則可以在末尾加上 no-resolve 參數,這是實戰中最容易被忽略、又最容易導致規則「看起來沒生效」的一個細節。
預設情況下,一條基於域名的規則(比如 DOMAIN-SUFFIX)命中前不需要提前解析 IP,直接按域名字串比對;而 IP-CIDR 類規則本質上是拿「目標 IP」去和網段比對,如果請求本身是一個域名,核心需要先把域名解析成 IP,再拿這個 IP 去匹配 IP-CIDR 規則。加上 no-resolve 之後,核心會跳過這一步解析,只對那些請求本身已經是 IP(而不是域名)的連線生效,不會主動為了匹配規則去發起額外的 DNS 查詢。
如果一條 IP-CIDR 規則的目標網段本來就該攔截域名請求提前觸發的解析(比如內網服務只用域名存取),不加 no-resolve 會導致每次匹配都先發出一次額外的 DNS 查詢,增加延遲且可能把解析請求發到了不該經過的 DNS 伺服器。反過來,如果只是想給「純 IP 直連」的流量做規則,加上 no-resolve 能減少不必要的解析開銷。
實際寫規則時的判斷標準很簡單:如果這條 IP-CIDR 規則針對的是明確會以 IP 形式出現的流量(比如內網設備、某些直接暴露 IP 的服務),建議加 no-resolve;如果目標本身是透過域名存取、需要依賴解析結果才能判斷走向的場景,交給前面的域名類規則處理會更直接,沒必要繞到 IP-CIDR 上。
規則排序的實戰原則與常見錯誤
理解了「從上到下命中即停止」的機制後,規則排序其實有一套相對固定的思路,按匹配範圍從窄到寬排列:
- 先寫局域網與內網直連規則。私有 IP 段、內網域名放在最前面,避免被後面更寬泛的規則提前攔截,導致內網存取也走了代理。
- 再寫需要特殊處理的具體域名或應用。比如要求走特定節點的串流媒體域名、需要直連的台灣本地常用服務域名,用 DOMAIN-SUFFIX 精確覆蓋。
- 接著放規則集合(rule-providers)。社群維護的分類規則集,比如廣告過濾、常見服務分類,按需要引用的順序排列。
- 再放地理位置類規則。典型是
GEOIP,CN,DIRECT,把沒被前面規則命中的中國大陸 IP 直接放行。 - 最後一條固定是 MATCH 兜底。所有沒命中的流量統一走這裡,通常指向節點選擇或代理組。
常見的排序錯誤集中在兩類:一類是把 GEOIP,CN,DIRECT 寫得太靠前,導致本應細分走代理的服務因為解析出的 IP 恰好在中國大陸網段而被提前直連;另一類是把 MATCH 兜底規則誤放在中間位置,後面辛苦寫的所有規則實際上永遠不會被執行到,除錯時容易誤以為是某條具體規則語法錯了,其實是排序問題。排查這類問題時,建議先看規則陣列順序,再看具體語法,順序錯了,語法再精確也不會生效。
用規則集合組織大規模規則
當自訂規則條數增長到幾十上百條,直接堆在 rules 陣列裡會變得難以維護。mihomo 支援 rule-providers 欄位,把規則拆分成獨立的遠端或本地檔案,再在 rules 裡透過 RULE-SET,规则集名称,策略组 引用:
rule-providers:
my-direct:
type: http
behavior: domain
url: "https://example.com/rules/direct.yaml"
path: ./rule-providers/direct.yaml
interval: 86400
rules:
- RULE-SET,my-direct,DIRECT
- GEOIP,CN,DIRECT
- MATCH,🚀 节点选择
behavior 欄位決定這份規則集裡的條目按域名、IP 網段還是分類規則解析,需要與規則檔案實際內容對應;interval 決定多久自動拉取一次更新。這種方式把「分類邏輯」和「具體規則內容」解耦,規則集本身的更新不需要改動主配置檔裡的排序,維護成本明顯低於把所有規則手寫在同一份配置裡。
寫規則前後建議做的兩項檢查
寫完規則後,建議做兩件事再上線使用:第一,檢查規則陣列裡是否只有一條 MATCH 且位於末尾,這是最容易漏檢的一處;第二,針對新增的 IP-CIDR 規則,確認 no-resolve 是否按預期加入或省略,尤其是涉及內網存取的規則,加錯或漏加都會帶來看似「隨機」的連線異常。日誌裡出現的分流結果如果和預期不符,先回到規則陣列按順序讀一遍,通常比逐條檢查語法更快定位問題。