Shadowrocket 规则写法:DOMAIN、GEOIP、IP-CIDR 与 FINAL 各匹配什么

Shadowrocket(小火箭)的规则列表里,每一行都由「类型、值、策略」三段组成,匹配顺序自上而下、首条命中即停。本文逐条拆开 DOMAIN、DOMAIN-SUFFIX、DOMAIN-KEYWORD、GEOIP、IP-CIDR 与 FINAL 的匹配对象,并给出可以直接照抄的写法与排查顺序。

本文速览

规则列表是一份纯文本,一行一条,格式为「类型,值,策略」。本文把域名类(DOMAIN、DOMAIN-SUFFIX、DOMAIN-KEYWORD)、IP 类(GEOIP、IP-CIDR)与兜底(FINAL)逐个讲清匹配对象与命中顺序,并给出可以在 Config → Rules 里直接照抄的示例。适合已经导入订阅、想让流量按自己的意图分流的用户;读完能独立写出一份不互相打架的规则列表。

一条规则的三段结构

Shadowrocket 的规则列表是一份纯文本,保存在配置文件里,一行一条。每行用英文半角逗号切成三段:类型(TYPE)、值(VALUE)、策略(POLICY)。类型决定「拿什么去比」,值决定「比什么」,策略决定「命中之后怎么办」。

策略只有三种:PROXY 表示走当前选中的服务器,DIRECT 表示直连,REJECT 表示丢弃这条连接。以 # 开头的整行是注释,解析时跳过;空行同样忽略。写规则时用到的逗号必须是英文半角,中文逗号会让整行失效。

# 每行格式:类型 / 值 / 策略
DOMAIN-SUFFIX,example.com,PROXY
DOMAIN-KEYWORD,analytics,DIRECT
IP-CIDR,192.168.0.0/16,DIRECT,no-resolve
FINAL,DIRECT

三段里最容易出错的是值:域名类规则的值是主机名,IP 类规则的值是 CIDR 网段或两位国家/地区代码,端口类规则的值是数字。格式不对的行不会报错,只会被静默跳过——所以遇到「规则写了没反应」,先回头检查这一行的逗号与值格式,再去怀疑别的环节。

域名类:DOMAIN、DOMAIN-SUFFIX、DOMAIN-KEYWORD

域名类规则匹配的是请求里的主机名。HTTPS 请求的主机名通常来自 TLS 握手里的 SNI,HTTP 请求来自 Host 头,这两种信息在连接刚建立时就已经具备,不需要等待 DNS 解析,因此域名规则判断得最快,也最不受解析结果波动影响。三种常用写法的粒度依次放宽:

类型匹配对象写法示例命中范围
DOMAIN完整主机名,一字不差DOMAIN,api.example.com,PROXY只命中 api.example.com;www.api.example.com 不命中
DOMAIN-SUFFIX域名后缀,含自身与全部子域DOMAIN-SUFFIX,example.com,PROXYexample.com、a.example.com、a.b.example.com 都命中
DOMAIN-KEYWORD主机名中任意位置出现的关键词DOMAIN-KEYWORD,analytics,DIRECTanalytics.example.com、cdn-analytics.example.net 都命中
DOMAIN-SET外置域名列表文件,每行一条域名DOMAIN-SET,example-domains.txt,DIRECT列表中写过的域名按该行策略执行

粒度越宽,误伤的概率越高。DOMAIN-KEYWORD,analytics,DIRECT 会命中主机名里任何位置出现 analytics 的请求,包括你并不想直连的站点;DOMAIN-SUFFIX,example.com,PROXY 则会连带把 mail.example.com、static.example.com 一起送进代理。写宽泛规则之前,先确认这个后缀下确实没有需要区别对待的子域。

选择写法时按下面的顺序判断:

DOMAIN,www.example.com,DIRECT
DOMAIN-SUFFIX,example.com,PROXY
DOMAIN-KEYWORD,adservice,REJECT
DOMAIN-SET,example-domains.txt,DIRECT

IP 类:GEOIP 与 IP-CIDR 比的是解析后的地址

IP 类规则不看域名,只看连接目标的 IP 地址。要拿到 IP,系统必须先做一次 DNS 解析,所以 IP 规则比域名规则晚一步生效,而且会丢掉「域名」这个维度:同一个域名解析到不同地址时,命中结果可能跟着变化。

GEOIP 用两位国家/地区代码概括整段地址归属,GEOIP,CN,DIRECT 的含义是「目标是中国的 IP 就直连」。IP-CIDR 写精确网段,内网直连的常见写法是 IP-CIDR,192.168.0.0/16,DIRECTIP-CIDR,10.0.0.0/8,DIRECT;IPv6 目标用 IP-CIDR6。按端口判断由 DST-PORTSRC-PORT 承担,例如 DST-PORT,443,PROXY 表示目标端口是 443 的连接走代理。

GEOIP,CN,DIRECT
IP-CIDR,192.168.0.0/16,DIRECT,no-resolve
IP-CIDR,10.0.0.0/8,DIRECT,no-resolve
IP-CIDR6,fc00::/7,DIRECT,no-resolve
DST-PORT,443,PROXY

内网网段这类规则通常要在末尾补一个 no-resolve:它的作用是匹配这条规则时不要为了拿 IP 而触发 DNS 解析。少了这个参数,一个本来可以直接命中的请求会先被迫解析一次,既拖慢判断,也可能因为解析失败而落空。

结论:域名规则要写在 IP 规则前面

GEOIP 与 IP-CIDR 需要先拿到目标 IP。如果它们排在域名规则之前,一个本可被 DOMAIN-SUFFIX 精确命中的请求会先被迫解析,命中结果取决于当时解析到哪个地址。把域名类放前、IP 类放后,顺序才稳定。

命中顺序:自上而下,首条命中即停

Shadowrocket 从规则列表的第一行开始逐条比对,某一行命中后立即执行该行的策略,后面的规则不再参与判断。这条机制决定了排序原则:越具体、越需要优先处理的规则写在越上面,越宽泛的规则写在越下面。

FINAL 是一条只有策略、不需要匹配值的兜底规则,用来承接前面全部没有命中的请求:FINAL,DIRECT 让未命中的流量直连,FINAL,PROXY 让未命中的流量走代理。它必须放在列表最后一行——写在 FINAL 之后的规则不会被执行。

# 1. 内网与保留地址先直连
IP-CIDR,192.168.0.0/16,DIRECT,no-resolve
# 2. 明确要拦截的域名
DOMAIN-SUFFIX,ads.example.com,REJECT
# 3. 明确要走代理的域名
DOMAIN-SUFFIX,example.com,PROXY
# 4. 国内地址直连
GEOIP,CN,DIRECT
# 5. 兜底
FINAL,PROXY

排序时可以按下面五层从上往下摆:

让规则生效:Global Routing 与配置文件

规则列表只在 Global Routing 处于 Config 姿态时才参与判断。姿态在 Settings → Global Routing 里切换,三个常用选项的差别是:

配置(Config)

推荐

按配置文件里的规则列表逐条匹配:命中 PROXY 走代理,命中 DIRECT 直连,命中 REJECT 丢弃。

适合:日常主力,想让规则真正起作用

代理(Proxy)

忽略规则列表,所有连接一律走当前选中的服务器。

适合:临时全量代理、排查规则问题

直连(Direct)

忽略规则列表与服务器,所有连接直接发出。

适合:确认某个现象是否由代理引入

另一个前提是「改对了文件」。Config 标签里可能同时存在多份配置,只有当前选中(带勾)的那一份会被使用。编辑入口是 Config → 选中正在使用的配置文件 → Rules,列表按行展示,右上角「+」新增一行,点任意一行可以修改类型、值与策略。完整流程如下:

  1. 确认姿态

    Settings → Global Routing 选 Config,否则规则列表不参与判断。

  2. 打开 Config

    底部标签切到 Config,确认带勾的正是你在用的那份配置文件。

  3. 进入 Rules

    点进配置文件,找到 Rules 一行,里面就是完整的规则列表。

  4. 插入新行

    右上角「+」新增规则,按「类型,值,策略」三段填写,逗号用英文半角。

  5. 调整顺序

    把具体规则移到宽泛规则之前,FINAL 保持在最后一行。

  6. 保存并重连

    保存后回到 Home 断开再连接一次,让新的规则列表生效。

结论:先定姿态,再谈规则

规则写了不生效时,先确认 Global Routing 是否停在 Config、当前选中的是不是你改的那份配置文件,再去检查规则顺序与写法。顺序反过来查,通常会在写法上白折腾很久。

四个高频问题

下面四个问题覆盖了规则类反馈里最常见的场景,排查路径都是从「姿态 → 配置文件 → 规则顺序 → 规则写法」逐层往下。

加了 DOMAIN-SUFFIX,example.com,PROXY,这个域名还是直连?

先看列表里有没有更靠前的规则先命中——例如写在域名规则之前的 GEOIP,CN,DIRECT,或者一条宽泛的 DOMAIN-KEYWORD。再确认 Global Routing 停在 Config、当前选中的正是你编辑的那份配置,最后断开重连一次。

GEOIP,CN,DIRECT 为什么没让国内站点直连?

GEOIP 匹配的是解析后的 IP,不是域名。如果它写在域名规则之前、或者目标解析到的地址不在 CN 段内,这条规则就不会命中。把它放到域名规则之后、FINAL 之前,再重连一次观察。

IP-CIDR 规则为什么不匹配我写的域名?

IP-CIDR 只比对 IP 地址,不认域名。要按域名分流就用 DOMAIN-SUFFIX;要按网段分流,就确认目标解析到的地址确实落在你写的 CIDR 里。写内网网段时记得带上 no-resolve。

REJECT 写了,某些请求还是发出去了?

规则自上而下匹配、首条命中即停。如果 REJECT 上面已经有一条 PROXY 或 DIRECT 命中了同一个目标,请求就走不到这一行。把 REJECT 提到对应域名规则之前再试。

App Store 正版核验