分流规则入门:DOMAIN、GEOIP、RULE-SET 全解析
本文目录
同样是打开网页,有的直连、有的走节点,决定权在 rules 这一段。它是 mihomo 配置里最像「程序」的部分:一条条判断语句从上往下执行,谁先命中谁说了算。
规则的写法高度统一,都是 类型,匹配内容,目标 三段式,目标是一个代理组名或内置的 DIRECT(直连)、REJECT(拒绝)。搞懂常用的几种类型和匹配顺序,你就能自己加一条规则解决「这个网站不该走代理」之类的问题。
规则的匹配顺序:自上而下,命中即停
内核处理每个新连接时,从 rules 第一条开始逐条比对,一旦命中就立即按该条的目标执行,后面的规则全部不再看。这条机制带来两个实践结论:
- 顺序决定一切。同一个域名被多条规则覆盖时,写在上面的生效。把精确的、特例的规则放前面,宽泛的放后面,否则特例永远轮不到。
- 最后必须有兜底。列表末尾的
MATCH匹配一切剩余流量,是整份规则的安全网。没有它,未命中的连接行为将不确定。
rules:
- DOMAIN-SUFFIX,ads.example.com,REJECT
- DOMAIN-SUFFIX,example.com,DIRECT
- MATCH,PROXY
上面这三行的效果是:广告子域直接拒绝,其余 example.com 走直连,剩下一切走 PROXY 组。把前两行对调,广告子域就会先被第二条捕获,第一条形同虚设。
域名类规则:三兄弟的差别
| 类型 | 匹配方式 | 示例与效果 |
|---|---|---|
DOMAIN | 完全相等 | DOMAIN,www.example.com 只匹配这一个域名 |
DOMAIN-SUFFIX | 后缀匹配 | DOMAIN-SUFFIX,example.com 匹配 example.com 及其所有子域 |
DOMAIN-KEYWORD | 包含关键词 | DOMAIN-KEYWORD,google 匹配任意含该词的域名 |
日常最常用的是 DOMAIN-SUFFIX:一条规则覆盖整个站点,不必逐个列举子域。DOMAIN-KEYWORD 要谨慎——关键词过于常见时会误伤大量无关域名,用它之前先想想有没有更精确的写法。
IP 类规则与 no-resolve
当连接的目标是 IP 而非域名,或者你想按地理归属分流时,用 IP 类规则:
- IP-CIDR,192.168.0.0/16,DIRECT,no-resolve
- IP-CIDR,127.0.0.0/8,DIRECT,no-resolve
- GEOIP,CN,DIRECT
- MATCH,PROXY
IP-CIDR 匹配一个网段,上面两条把局域网和本机地址放行直连;GEOIP,CN 借助内置的 IP 地理数据库匹配中国大陆 IP,是「国内直连、国外代理」的常规写法。
末尾的 no-resolve 值得单独说:IP 类规则要拿到目标 IP 才能判断,如果连接给出的是域名,内核就必须先做一次 DNS 解析。加上 no-resolve 表示「域名请求遇到这条规则时直接跳过,不要为它专门解析」。这样做有两个好处——避免每个连接都触发额外解析拖慢速度,也避免在解析阶段就发生 DNS 泄漏。习惯上,写在规则列表靠前位置的 IP 类规则都会带上它,相关机制见 mihomo DNS 配置详解。
说明:GEOIP,CN 通常不加 no-resolve,因为它需要真实 IP 才能判断归属;但也正因如此,它应该放在域名类规则之后——能用域名判断的,就别劳烦 DNS。
RULE-SET 与 rule-providers:把规则外包出去
手写几千条域名显然不现实。rule-providers 允许你引用外部维护的规则集文件,内核定期自动更新,规则里用 RULE-SET 引用它:
rule-providers:
reject:
type: http
behavior: domain
url: "https://example.com/rules/reject.yaml"
path: ./ruleset/reject.yaml
interval: 86400
rules:
- RULE-SET,reject,REJECT
- MATCH,PROXY
各字段的含义:type 为 http 表示从网络拉取(也可用 file 读本地文件);behavior 声明规则集的内容形态,常见有 domain(纯域名)、ipcidr(IP 网段)、classical(可混合多种规则类型);path 是本地缓存路径;interval 是更新间隔(秒),86400 即一天一次。behavior 必须与规则集文件的实际内容对得上,写错会导致加载失败。
一段完整的 rules 结构
把上面的要点组合起来,一份规则的骨架通常长这样——顺序本身就是设计的一部分:
rules:
# 1. 特例与拒绝,优先级最高
- DOMAIN-SUFFIX,ads.example.com,REJECT
# 2. 局域网与本机,跳过解析
- IP-CIDR,192.168.0.0/16,DIRECT,no-resolve
- IP-CIDR,127.0.0.0/8,DIRECT,no-resolve
# 3. 明确要直连的域名
- DOMAIN-SUFFIX,cn,DIRECT
# 4. 明确要走代理的域名
- DOMAIN-KEYWORD,github,PROXY
# 5. 外部规则集
- RULE-SET,reject,REJECT
# 6. 按 IP 归属兜底判断
- GEOIP,CN,DIRECT
# 7. 最终兜底
- MATCH,PROXY
规则里出现的 PROXY 必须是配置中真实存在的代理组名,写错内核会启动失败;代理组本身怎么定义见 代理组详解。改完照例先用 mihomo -t -f config.yaml 校验一遍,方法见 mihomo 配置文件入门。
怎么确认某条规则真的命中了
规则写了不等于生效,验证靠客户端自带的两个面板:
- 连接面板:列出当前所有活动连接,每条会显示目标地址、命中的规则以及最终走的代理组。想确认某个网站走没走代理,打开它再回来看这一行最直接。
- 日志面板:把日志级别调到
debug,可以看到更详细的匹配过程与 DNS 解析情况,适合排查「为什么这条规则没生效」。
常见的翻车原因就两个:规则顺序不对,被上面某条宽泛规则提前截胡;或者目标名字拼错、大小写不符。遇事先看连接面板里那一行实际命中的是谁,比反复读配置有效得多。