規則匹配的基本原則:自上而下,命中即停
Clash 的分流引擎在處理一條連線請求時,按 rules 欄位中列出的順序逐條比對,一旦某條規則的條件與請求匹配,立即採用該規則指定的策略群組或代理節點,後續所有規則不再參與判斷。這意味著規則列表的排列順序本身就是優先級,與規則類型無關——寫在前面的 DOMAIN-KEYWORD 可以覆蓋寫在後面的 GEOIP,反之同樣成立。
這一機制帶來兩個直接後果。第一,規則條目越靠前,越應該覆蓋範圍小、判斷依據明確的場景,例如指定網域的直連或拒絕;越靠後,越應該放寬泛的兜底規則,例如按國家/地區分流的 GEOIP 與最終的 MATCH。第二,新增自訂規則時,插入位置決定了它是否會被前面已有的規則提前攔截而失效——很多「規則明明寫了卻不生效」的問題,根源都是順序問題,而不是語法錯誤。
Clash Meta(mihomo)在規則引擎邏輯上與 Clash 保持一致,同樣是自上而下、命中即停;差異主要體現在支援的規則類型更豐富(如 PROCESS-NAME、RULE-SET、邏輯規則 AND/OR/NOT),排列順序的處理原則不受影響。
常用規則類型與書寫格式
規則條目的通用格式為 類型,匹配內容,策略,策略可以是具體節點名,也可以是策略群組名(如 PROXY、DIRECT、REJECT)。以下是日常設定中最常用的幾類。
DOMAIN 系列:網域匹配
DOMAIN:精確匹配完整網域,僅命中該網域本身,不含子網域。DOMAIN-SUFFIX:匹配網域後綴,自動覆蓋其所有子網域,是最常用的網域規則。DOMAIN-KEYWORD:匹配網域中包含的關鍵字,覆蓋面最廣,也最容易誤傷無關網域。
DOMAIN,api.example.com,DIRECT
DOMAIN-SUFFIX,example.com,PROXY
DOMAIN-KEYWORD,analytics,REJECT
上面三條同時出現時,由於 api.example.com 同時滿足第一條與第二條,只要第一條排在前面,api.example.com 就會走 DIRECT,而 example.com 的其他子網域仍歸第二條的 PROXY 處理。這正是「覆蓋範圍小的規則要放前面」的典型場景。
IP-CIDR 與 IP-CIDR6:按網段匹配
當目標位址是已知的 IP 段而非網域(常見於內網位址、CDN 固定回源、或已知服務商網段)時使用 IP-CIDR。該規則預設只對連線的目標 IP 生效,如果需要連伺服器解析出的所有 A/AAAA 記錄都參與匹配,部分核心提供 no-resolve 選項跳過額外解析開銷。
IP-CIDR,192.168.0.0/16,DIRECT,no-resolve
IP-CIDR,10.0.0.0/8,DIRECT,no-resolve
IP-CIDR6,2001:db8::/32,DIRECT,no-resolve
不加 no-resolve 時,Clash 會先對網域做 DNS 解析再比對 IP 段,這會給每次匹配增加一次解析開銷;對內網位址段這類明確不需要解析的規則,建議始終加上 no-resolve。
GEOIP:按國家/地區分流
GEOIP 依據目標 IP 所屬的國家/地區代碼判斷,常用於「當地 IP 直連,境外 IP 走代理」這類粗粒度分流。由於判斷依據是整個國家/地區的 IP 資料庫,匹配範圍最大,通常放在規則列表接近末尾的位置。
GEOIP,CN,DIRECT
GEOIP,PRIVATE,DIRECT
RULE-SET 與規則集:批量維護的分流片段
Clash Meta(mihomo)支援 rule-providers 欄位引入外部規則集,設定中用 RULE-SET 引用,便於把某一類站點(如串流媒體、廣告網域清單)統一維護、定期更新,而不必逐條手寫。
rule-providers:
ads-reject:
type: http
behavior: domain
url: "https://example.com/rules/ads.txt"
path: ./rule-providers/ads-reject.yaml
interval: 86400
rules:
- RULE-SET,ads-reject,REJECT
MATCH:兜底規則
MATCH 匹配所有未被前面規則處理的連線,必須放在規則列表的最後一行,作為整個分流表的兜底出口,通常指向策略群組而非固定節點,以便後續切換。
MATCH,PROXY
規則排列順序建議:如何避免規則互相覆蓋
把上述規則類型組合到同一份設定中時,建議按照「匹配範圍從小到大」的順序自上而下排列,大致分為四層:
- 精確例外層:
DOMAIN與內網IP-CIDR,處理需要單獨指定策略的具體位址,例如內網管理後台走直連、某個已知惡意網域直接拒絕。 - 網域歸類層:
DOMAIN-SUFFIX為主,按業務分組(社交、影音、開發工具等)批量歸入對應策略群組。 - 規則集與關鍵字層:
RULE-SET、DOMAIN-KEYWORD覆蓋面較大,放在網域歸類層之後,避免關鍵字規則提前攔截本應精確匹配的網域。 - 地區與兜底層:
GEOIP處理剩餘的國家/地區分流,MATCH放最後一行收尾。
下表用狀態徽章標註了幾種典型規則在這套排序裡通常對應的出口方向,便於核對設定是否符合預期:
- DOMAIN-SUFFIX,cn
- DIRECT
- DOMAIN-SUFFIX,googlevideo.com
- PROXY
- DOMAIN-KEYWORD,ad
- REJECT
- GEOIP,CN
- DIRECT
- MATCH
- PROXY
如果某條自訂規則加入後沒有生效,先檢查它上方是否已有一條更寬泛的規則提前命中了同樣的目標——這是排查順序問題最快的方法,比反覆檢查語法更有效率。
實戰範例:自訂分流片段與放置位置
以「給某個開發環境網域單獨走直連,同時保留原有的廣告攔截與地區分流」為例,新增規則時應插入到廣告攔截規則之前、網域歸類層之後,理由是這條例外規則的匹配範圍比 DOMAIN-KEYWORD 更精確,需要優先判斷:
rules:
# 精確例外層
- DOMAIN,192-168-1-1.local,DIRECT
- IP-CIDR,172.16.0.0/12,DIRECT,no-resolve
# 新增:開發環境網域直連(插入在關鍵字規則之前)
- DOMAIN-SUFFIX,dev.internal-project.com,DIRECT
# 網域歸類層
- DOMAIN-SUFFIX,github.com,PROXY
- DOMAIN-SUFFIX,googlevideo.com,PROXY
# 規則集與關鍵字層
- RULE-SET,ads-reject,REJECT
- DOMAIN-KEYWORD,analytics,REJECT
# 地區與兜底層
- GEOIP,CN,DIRECT
- MATCH,PROXY
若把這條新增規則誤放到 MATCH 附近,由於它前面已經存在覆蓋面更大的關鍵字或地區規則,新增規則大概率永遠不會被執行到,表現就是「設定儲存了,但流量走向沒變化」。
另一種常見需求是讓某個具體 IP 段走拒絕而非直連,例如封鎖一批已知的探測伺服器:
rules:
- IP-CIDR,203.0.113.0/24,REJECT,no-resolve
- GEOIP,CN,DIRECT
- MATCH,PROXY
這條 IP-CIDR,REJECT 必須放在 GEOIP,CN,DIRECT 之前,否則如果該網段恰好被判定為當地 IP,會先被 GEOIP 規則命中並直連,拒絕規則將永遠不會被觸發。
排查規則不生效的常見思路
遇到自訂規則未按預期生效時,建議按以下順序排查,而不是立即懷疑規則語法有誤:
- 檢查排列位置:確認新增規則上方沒有覆蓋範圍更大且更早命中的規則,這是最常見的原因。
- 確認規則類型與內容格式:
DOMAIN-SUFFIX不需要通配符前綴(不要寫成*.example.com),寫法應為純網域後綴example.com。 - 核對策略群組名是否存在:規則末尾的策略名必須與
proxy-groups中定義的群組名或具體節點名完全一致,拼寫錯誤會導致核心在載入設定階段直接報錯或忽略該行。 - 確認是否命中了 DNS 層的分流:若開啟了
fake-ip或自訂nameserver-policy,網域可能在進入規則引擎前已經被 DNS 分流影響,需要一併檢查 DNS 設定段而非只看rules。
不要把 DOMAIN-KEYWORD 當作 DOMAIN-SUFFIX 的替代品濫用。關鍵字規則不區分網域結構,容易誤傷包含相同字串的無關網域(例如關鍵字 ad 會命中 adobe.com),排查異常連線時應優先檢查這類寬泛規則是否放置得過於靠前。