Clash 规则分流实战:本地直连与境外走代理的 rules 和 rule-providers 写法
以常见分流场景为线索,拆解规则自上而下的匹配顺序、策略组引用方式与 rule-providers 远程规则集的组织方法,避免规则写反导致流量走错出口。
先确认分流范围:规则模式、流量入口与出口
“本地直连、境外代理”需要拆成三个动作:局域网地址交给 DIRECT,明确的国内站点按域名或 IP 归属直连,其余连接交给代理策略组。这里的“本地”包括路由器、NAS 和内网服务;它与“国内网站”不是同一个集合。先区分这两类目标,才能避免访问公司内网时误走远端节点。
本文示例面向 mihomo 内核。Clash Nyanpasu 是图形客户端,真正执行 rules 的是当前运行的内核。旧版 Clash 对部分字段的支持不同,尤其是下面用到的 include-all,不要把 mihomo 配置直接套给所有同名客户端。
- 代理模式:选择“规则 / Rule”。全局模式不会按本文的普通分流列表选择出口,直连模式也不会实现代理兜底。
- 流量入口:浏览器需要实际使用客户端的代理端口,或由 TUN 接管流量。系统代理通常不能覆盖所有应用。
- 策略组出口:规则命中代理组,不代表已经选中可用节点。还要检查组内当前选项。
- 配置来源:确认当前启用的是哪份订阅,以及是否有覆写、合并脚本改变最终规则。
先备份正在使用的配置。订阅管理器可能在更新时重建配置,应通过客户端支持的持久覆写或合并机制保存自定义规则,并检查最终生效结果,而不是只修改临时生成文件。
rules 匹配顺序:具体例外在前,MATCH 放最后
普通 rules 列表从上往下检查,首次命中后就使用对应策略,不会继续寻找“更精确”的下一条。规则并没有自动按域名长度或 IP 网段大小排序的机制。例如,把覆盖整个站点的后缀规则放在前面,后面的单个子域名例外便没有机会生效。
| 规则类型 | 示例 | 匹配范围 |
|---|---|---|
| DOMAIN | DOMAIN,example.com,DIRECT | 仅匹配这个完整域名 |
| DOMAIN-SUFFIX | DOMAIN-SUFFIX,example.com,代理出口 | 匹配根域名及其子域名 |
| IP-CIDR | IP-CIDR,192.168.0.0/16,DIRECT,no-resolve | 匹配目标 IPv4 网段 |
| GEOIP | GEOIP,CN,DIRECT | 依据本机 IP 归属数据库匹配 |
| MATCH | MATCH,代理出口 | 接住前面未命中的连接 |
域名例外如何覆盖后缀规则
rules:
- DOMAIN,example.com,DIRECT
- DOMAIN-SUFFIX,example.com,代理出口
- MATCH,代理出口
这组规则里,example.com 直连,www.example.com 进入代理出口。两行对调以后,根域名也会先命中后缀规则。这些保留示例域名只用于说明匹配关系,不是需要加入配置的业务站点。
no-resolve 表示不要为了这一条 IP 规则主动把域名解析成 IP;它不表示禁止连接过程中的所有 DNS 查询。如果连接本来就带有目标 IP,规则仍可按该 IP 判断。它适合局域网网段规则,避免检查内网地址时产生不必要的解析。
本地直连与境外代理:一组可检查的配置片段
下面是合并到现有 mihomo 配置的片段,不是包含节点、DNS 和监听端口的完整订阅。保留原有 proxies 或 proxy-providers,再合并策略组和规则;如果已有同名顶层字段,应编辑原字段,不能重复追加另一个 rules:。
mode: rule
proxy-groups:
- name: 代理出口
type: select
include-all: true
proxies:
- DIRECT
rules:
# 个人例外:域名信息可用时优先匹配
- DOMAIN-SUFFIX,home.arpa,DIRECT
- DOMAIN-SUFFIX,lan,DIRECT
# 回环、私有网络与链路本地地址
- IP-CIDR,127.0.0.0/8,DIRECT,no-resolve
- IP-CIDR,10.0.0.0/8,DIRECT,no-resolve
- IP-CIDR,172.16.0.0/12,DIRECT,no-resolve
- IP-CIDR,192.168.0.0/16,DIRECT,no-resolve
- IP-CIDR,169.254.0.0/16,DIRECT,no-resolve
- IP-CIDR6,::1/128,DIRECT,no-resolve
- IP-CIDR6,fc00::/7,DIRECT,no-resolve
- IP-CIDR6,fe80::/10,DIRECT,no-resolve
# 国内 IP 直连,剩余连接进入代理组
- GEOIP,CN,DIRECT
- MATCH,代理出口
先选节点,再验证代理结果
include-all: true 让这个 mihomo 策略组纳入已有节点及代理提供器中的节点。示例保留 DIRECT 作为可选项,应用后必须在“代理出口”组内主动选择一个可用节点;若仍选中 DIRECT,即使日志显示命中 MATCH,最终也会直连。若尚未导入任何节点,该片段不能凭空提供代理连接。
若原配置已有可用策略组,通常更简单的做法是保留原组,把规则中的“代理出口”替换成该组的准确名称。名称区分大小写,空格也属于名称的一部分。不要为了套用示例而删除订阅自带的自动选择组。
这套基础分流的边界
GEOIP,CN判断的是目标 IP 的数据库归属,不能据此推断公司注册地或顶级域名所代表的地区。- 国内服务可能使用境外 CDN,境外服务也可能分配国内地址,因此需要域名规则集补充意图。
GEOIP依赖可用的本地数据库;文件缺失或加载失败应先修复,不能把规则加载失败当成正常兜底。- 内网域名需要能够被正确解析。指定直连不会自动给客户端增加企业 DNS,也不会自动发现 NAS。
这里的 GEOIP 规则没有添加 no-resolve,允许在需要时解析域名来判断国内 IP。代价是部分连接会先触发本地 DNS 查询。如果目标是严格约束域名解析路径,应同时设计 DNS 策略,而不是把“走代理出口”等同于“DNS 一定通过代理”。
rule-providers 写法:远程规则集与行为类型
规则较多时,可以把域名列表移出主配置。rule-providers 负责定义规则集的来源、格式和更新方式,RULE-SET 才负责在规则列表中引用它。只定义提供器却没有写引用,并不会改变任何连接的出口。
以下使用公开的 Loyalsoldier 直连域名规则集演示 HTTP 提供器。该列表代表维护者整理的直连建议,并非严格的中国地域边界;采用前应检查其范围是否符合自己的业务需求。地址只是供内核按配置获取规则,网页不会自动请求它。
rule-providers:
direct-domains:
type: http
behavior: domain
format: yaml
url: "https://raw.githubusercontent.com/Loyalsoldier/clash-rules/release/direct.txt"
path: ./ruleset/direct-domains.yaml
interval: 86400
interval: 86400 的单位是秒,即每 24 小时检查更新。path 是内核工作目录下的本地缓存文件位置,不是相对当前网页的位置。首次加载时必须能获取远程内容,或已有可用缓存;不能假定下载失败后一定会跳过规则继续启动。
把规则集接入正确的位置
保留上一节的个人例外和局域网规则,在其后、GEOIP 之前插入下面这一行。此处只展示列表末段,不要直接覆盖并丢掉前面的内网规则。
- RULE-SET,direct-domains,DIRECT
- GEOIP,CN,DIRECT
- MATCH,代理出口
推荐顺序是“个人例外 → 局域网 → 直连域名集 → 国内 IP → 代理兜底”。若某个域名被直连列表收录,但你希望它走代理,应在 RULE-SET 之前添加明确的域名代理规则。把例外放在 MATCH 后面永远不会生效。
behavior 与文件内容必须匹配
| behavior | YAML payload 项示例 | 适用内容 |
|---|---|---|
| domain | '+ .example.com' 中去掉加号后的空格,即 '+. 域名写法 | 纯域名规则集,支持其规定的通配语法 |
| ipcidr | '192.168.0.0/16' | IP 网段集合 |
| classical | 'DOMAIN-SUFFIX,example.com' | 包含规则类型的经典规则集合 |
例如,一个本地的 behavior: domain、format: yaml 文件可以写成下面的形式。这里的 +.example.com 匹配根域名及子域名,不能误写成普通 rules 中的完整三段式。
payload:
- '+.example.com'
- 'example.net'
classical 内容则写 DOMAIN-SUFFIX,example.com 这一类匹配条件,不在每个 payload 项末尾添加 DIRECT;使用哪个策略由外层 RULE-SET,规则集名称,策略 指定。文件扩展名不能决定实际格式:上面的远程地址虽然以 .txt 结尾,内容仍是 YAML payload。
用三类连接验证:内网、国内网站、代理兜底
保存配置只说明编辑完成,不代表新规则已经接管连接。重新加载后,先在客户端的配置页面确认当前激活项,再到连接列表和内核日志检查。不同版本的页面名称可能不同,应以“查看连接的命中规则与完整出口链”为目标,而不是只看模式按钮。
- 测试局域网:如果路由器实际地址是
192.168.1.1,通过代理入口访问它,预期命中192.168.0.0/16并显示 DIRECT。不要假定所有家庭网络都使用这个网关。 - 测试国内站点:新建一次国内站点连接,检查是否命中 direct-domains 或 GEOIP CN。如果是 MATCH,先确认目标域名是否在列表内,再核对解析 IP 的归属。
- 测试代理兜底:访问不在直连集合中的境外站点,预期命中 MATCH,出口链应继续指向选中的实际节点,而不是停在 DIRECT。
- 测试例外:对临时指定的精确域名添加一条顶部规则,重新建立连接,确认它确实先于规则集命中;验证后删除不需要保留的临时条目。
用 curl 明确经过哪个代理端口
如果你的实际配置是 mixed-port: 7890,可以用下列命令产生一条明确经过 HTTP 代理入口的连接。端口以当前生效配置为准,7890 不是所有安装的固定值;Windows PowerShell 中可用 curl.exe 避免命令别名差异。
curl --proxy http://127.0.0.1:7890 --connect-timeout 10 -I https://example.com/
这个命令用于确认流量确实经过本机入口,不用于证明某个网站一定应走代理。应在连接列表中对照请求时间、目标域名、命中规则和出口链四项信息。对只支持 SOCKS 的入口,应使用相应端口;socks5h:// 可以把域名交给代理侧处理,避免测试工具先在本地解析而改变观察结果。
规则变更通常不会让已经建立的 TCP 连接重新选择出口。浏览器连接池、HTTP/2 和 QUIC 都可能复用会话;测试前关闭相关旧连接,再发起新请求,否则容易误判为“规则没有生效”。
分流不生效的逐项排查
命中了代理组,却仍然直连
先展开策略组的最终出口。手动选择组可能选中了 DIRECT,也可能嵌套了另一个选择组,后者最终仍选 DIRECT。只有完整链路显示实际代理节点,才能说明连接交给了该节点;组名叫“代理出口”本身没有强制代理的作用。
配置能保存,远程规则集却不可用
检查日志中的提供器名称、HTTP 状态和解析错误。状态码 403 表示服务端拒绝请求,404 通常指向路径或分支不正确;返回 HTML 错误页时,即使 HTTP 请求完成,也不代表拿到了合法规则。不要把订阅代理节点的 URL 填进规则提供器,它们的数据结构不同。
浏览器正常,游戏或命令行不按规则走
先看连接列表里有没有对应连接。没有记录时,应优先检查应用是否使用系统代理、是否自行直连,或 TUN 是否真正接管该流量。TUN 的职责是扩大流量入口范围,不会自动替你改正 rules 顺序;UDP 流量还需要入口、内核及节点链路共同支持。
IP 访问能直连,内网域名却打不开
这通常需要检查域名解析。printer.home.arpa 是否由路由器或企业 DNS 提供记录?应用使用的是系统解析器还是自己的加密 DNS?域名没有获得正确的内网 IP 时,增加 DIRECT 规则无法修复解析。另需注意,.local 常与 mDNS 有关,不宜把它简单当作普通单播 DNS 后缀处理。
订阅更新后,自定义规则消失
确认修改是否写进可持久保存的覆写层,并检查合并规则:有的处理方式追加数组,有的替换整个数组。若自定义规则被追加在原有 MATCH 之后,虽然文字还在,实际也不会命中。每次更新后至少检查列表开头、RULE-SET 引用和最后一条 MATCH。
维护分流时,优先保留少量可解释的例外,把批量域名交给来源明确的规则集,再用连接日志验证结果。更多基础设置可查阅使用指南;需要核对 DNS、TUN 与内核参数之间的关系时,可继续查看技术参考。规则越多不等于越准确,入口、顺序和最终出口一致,才是稳定分流的基础。