规则匹配的基本原则:自上而下,命中即停
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),排查异常连接时应优先检查这类宽泛规则是否放置得过于靠前。