规则的执行顺序:命中即停止
Clash 的 rules 是一份从上到下顺序执行的列表,每一条格式大致为 类型,匹配内容,策略。客户端拿到一个网络请求后,从第一条规则开始逐条比对,一旦命中就立即应用对应策略,不再继续往下匹配。这一点是理解规则文件最关键的前提,很多"规则明明写对了却不生效"的问题都是因为忽略了这一点。
举个例子,假设规则文件里有这四条:
- DOMAIN-SUFFIX,example.com,DIRECT
- DOMAIN-SUFFIX,google.com,PROXY
- GEOIP,CN,DIRECT
- MATCH,PROXY
一个访问 www.google.com 的请求会先检查第一条——不匹配 example.com,跳过;检查第二条——匹配 google.com 的子域名,命中,直接应用 PROXY 策略并停止,后面的 GEOIP 和 MATCH 规则根本不会被执行到。
常用规则类型完整清单
除了教程页速查表里最常用的六种,Clash 实际支持的规则类型更丰富,按用途整理如下:
- DOMAIN:精确匹配单个完整域名,不含子域名。
- DOMAIN-SUFFIX:匹配域名及其所有子域名,最常用的写法。
- DOMAIN-KEYWORD:域名中包含指定关键字即匹配,一次覆盖多个变体域名。
- DOMAIN-REGEX:用正则表达式匹配域名,适合处理规律性强但难以逐个列举的域名。
- IP-CIDR / IP-CIDR6:按 IPv4 / IPv6 地址段匹配,常用于内网直连。
- GEOIP:按请求目标 IP 所属的国家 / 地区分流,例如
GEOIP,CN,DIRECT。 - SRC-IP-CIDR:按发起请求的本机源 IP 匹配,适合多网卡或局域网多设备场景下按来源分流。
- PROCESS-NAME:按发起请求的进程名匹配,可以给某个具体应用单独指定策略(桌面端支持较好)。
- MATCH:兜底规则,匹配所有未命中前面规则的流量,必须放在列表最后一行。
Rule Provider:不用手写、跟着远程源自动更新
逐条手写规则显然不现实——国内网站几千个域名不可能一条条列。rule-providers 的作用就是引用一份由社区或服务商维护、远程托管的规则集合,规则内容会跟随远程源自动更新,你只需要在规则列表里用一行引用它:
rule-providers:
reject:
type: http
behavior: domain
url: "https://example.com/rules/reject.txt"
path: ./ruleset/reject.yaml
interval: 86400
rules:
- RULE-SET,reject,REJECT
- GEOIP,CN,DIRECT
- MATCH,PROXY
大多数订阅服务商已经把这一层配置好了,普通用户开箱即用;只有当默认规则集无法满足你的需求(比如想额外拦截某个新出现的广告域名)时,才需要在它的前面插入自己的规则——因为顺序在前的规则优先命中。
新手最容易犯的三个规则错误
1. 把 MATCH 写在中间而不是最后
MATCH 是兜底规则,一旦写在列表中间,它后面的所有规则都不会再被执行到,因为 MATCH 本身匹配一切流量。永远把它放在整个 rules 列表的最后一行。
2. 自定义规则写在了 Rule Provider 引用的后面
如果你想让自己写的规则优先于订阅自带的规则集生效,必须把它放在 RULE-SET 引用行的前面,否则订阅规则集会先命中,你的自定义规则永远排不上号。
3. 忘记给 IP-CIDR 加 no-resolve
匹配内网 IP 段时,建议加上 no-resolve 参数(如 IP-CIDR,192.168.0.0/16,DIRECT,no-resolve),表示不对域名做提前解析,避免因为解析行为触发不必要的 DNS 查询。
实战示例:给某个域名单独指定策略
假设你想让某个特定网站始终走代理,而不受订阅规则集判断影响,只需要在规则列表最前面加一行:
rules:
- DOMAIN-SUFFIX,example.com,PROXY # 自定义规则放最前面
- RULE-SET,reject,REJECT
- RULE-SET,direct,DIRECT
- RULE-SET,proxy,PROXY
- MATCH,PROXY
因为它排在所有 RULE-SET 引用之前,会最先被匹配到,不会被订阅规则集"抢先"判定为直连或其他策略。
写在最后
理解"顺序匹配、命中即停"这一条核心逻辑,剩下的规则类型只是词汇量的积累。不确定某个词是什么意思,可以随时去术语表查一下;如果只是想知道某个网站为什么打不开,使用教程的排查方法可能比手写规则更快解决问题。