适合已经能正常连接节点、想把国内站点切成直连的用户。读完可以自己排出一份顺序正确的规则列表:拦截在最前,内网与国内域名直连居中,其余流量兜底走代理;同时知道每条规则在什么条件下会失效,失效后该回查哪个环节。
分流判断的两个维度:域名与 IP
路由规则的基本结构是「条件 + 出站」。条件主要有域名、IP、端口、网络类型四类,出站只有三种:代理、直连、拦截。国内外分流的常见做法是用两类条件各写一套:域名命中 geosite:cn 走直连,IP 命中 geoip:cn 走直连,其余流量交给代理。
判断发生在内核内部,顺序是固定的。目标地址先以它本来的形态参与匹配:应用交给内核的是域名,就先比对域名规则;域名规则全都没命中,内核才按域名策略决定要不要解析成 IP,再拿 IP 去比对 IP 规则。
这个顺序解释了一个高频现象:只写了 geoip:cn、没有写 geosite:cn 的配置,在域名策略为 AsIs 时几乎不起作用——内核没有解析域名,也就没有 IP 可比对,请求会全部落到底部的默认出站。
反过来,只写域名规则也有边界:应用自己先做了 DNS 解析、把 IP 形态的地址交给内核时,域名规则同样没有作用对象。分流准确的前提,是让域名以域名的形态进入内核。
匹配顺序:从上到下,首条命中即生效
规则列表是有序数组,不是集合。内核从第一条开始逐条比对,命中第一条就结束匹配,后面的规则不再参与。顺序本身就是逻辑:拦截排在直连之前,直连排在兜底之前。
v2rayN 的「设置」→「路由设置」维护的就是这个数组,出站下拉里的「代理」「直连」「拦截」分别对应内核配置里的 proxy、direct、block 三个出站标签。每一行只描述一个条件组合,先后次序靠上下移动调整。
一份能覆盖大多数场景的顺序如下。最后一行不是规则,而是所有规则都没命中时内核使用的默认出站。
| 顺序 | 条件 | 出站 | 作用 |
|---|---|---|---|
| 1 | geosite:category-ads-all | 拦截 | 广告与统计域名直接拒绝 |
| 2 | geosite:private | 直连 | 内网域名不走代理 |
| 3 | geoip:private | 直连 | 192.168.0.0/16 等地址段直连 |
| 4 | geosite:cn | 直连 | 国内站点按域名判定 |
| 5 | geoip:cn | 直连 | 未被域名规则覆盖的国内 IP 兜底 |
| 6 | 无规则命中 | 代理 | 默认出站,其余流量走节点 |
顺序放错的代价很具体。把 IP 规则放在域名规则之前,在 IPOnDemand 策略下每条连接都会先解析一次域名,既增加首包延迟,也可能因为 CDN 解析结果落在境外而误判;把拦截规则放到最后,广告域名会先被前面的直连或代理规则吃掉,拦截永远不会被读到。
域名规则的四种写法
域名条件支持四种前缀,粒度从宽到窄。写错前缀是分流不准最常见的原因。
| 写法 | 匹配范围 | 示例 |
|---|---|---|
| 裸字符串 / domain: | 该域名及其所有子域 | domain:qq.com 命中 www.qq.com |
| full: | 完全相同的域名 | full:www.example.cn 不命中 a.www.example.cn |
| keyword: | 域名中包含该字符串 | keyword:doubleclick 命中任意含该串的域名 |
| regexp: | 正则表达式 | regexp:.*\.google\.com$ 命中其子域 |
除了前缀写法,还可以直接引用 geosite 集合:geosite:cn 覆盖常见国内域名,geosite:geolocation-cn 是更宽的一档,geosite:private 是内网域名,geosite:category-ads-all 是广告与统计域名集合。集合数据随规则文件打包发布,新出现的域名会有滞后,这也是「规则写了还是漏」的常见来源。
一条规则可以同时写多个条件,用逗号分隔,任意一个命中即算匹配。
"domain": [
"domain:qq.com",
"full:www.example.cn",
"keyword:doubleclick",
"regexp:.*\\.google\\.com$",
"geosite:cn"
]
需要提醒的是,keyword: 与 regexp: 属于 Xray 内核的扩展写法,在 v2ray 内核下不生效。v2rayN 可以在「设置」→「参数设置」里切换内核,v2rayNG 固定使用 Xray 内核,v2flyNG 使用 v2fly 内核;跨内核迁移规则前,先确认这两类写法是否被支持。
IP 规则与 geoip:cn 的适用边界
geoip:cn 判断的是 IP 归属,不是域名归属。国内域名解析到境外 CDN 的 IP 时会被判成非国内,境外域名解析到国内节点时会被判成国内。所以 IP 规则适合做兜底,不适合当主要判据。
内网地址必须显式直连。geoip:private 覆盖 10.0.0.0/8、172.16.0.0/12、192.168.0.0/16、127.0.0.0/8 等地址段;只写 geoip:cn 的话,访问路由器管理页、NAS 或局域网打印机会被送进代理,表现是节点连通但内网服务打不开。
域名策略决定了解析时机
AsIs 不解析域名,IP 规则形同虚设;IPIfNonMatch 只在域名规则全部未命中时解析一次,并带着解析结果从第一条规则重新匹配;IPOnDemand 只要遇到 IP 规则就立即解析。v2rayN 的默认模板使用 IPIfNonMatch,没有按 IP 精确判定的需求,不要改成 IPOnDemand。
还有一个容易忽略的细节:IPIfNonMatch 的第二轮匹配会带着 IP 从第一条重新开始。放在列表靠前的 IP 规则会在第二轮「截胡」原本该被域名规则命中的请求。排查时如果发现日志里的出站与预期不符,先确认这次命中发生在第几轮。
结论:域名规则决定精度,IP 规则决定兜底
把 geosite:private、geosite:cn 放在 geoip:cn 之前,再用 geoip:private 兜住内网,国内外分流的误差就只剩 CDN 与 DNS 两项;这两项靠调整顺序解决不了,要靠 DNS 配置收敛。
可直接改用的规则骨架与落地步骤
把前面的结论拼起来,就是一份顺序完整的骨架:广告与统计域名拦截、内网直连、国内域名直连、国内 IP 直连,其余流量走代理。可以直接抄进 v2rayN 的路由设置,也可以作为自定义规则集导入。
"routing": {
"domainStrategy": "IPIfNonMatch",
"rules": [
{ "type": "field", "domain": ["geosite:category-ads-all"], "outboundTag": "block" },
{ "type": "field", "domain": ["geosite:private"], "outboundTag": "direct" },
{ "type": "field", "ip": ["geoip:private"], "outboundTag": "direct" },
{ "type": "field", "domain": ["geosite:cn"], "outboundTag": "direct" },
{ "type": "field", "ip": ["geoip:cn"], "outboundTag": "direct" }
]
}
直连组
- 域名
- geosite:cn, geosite:private
- IP
- geoip:cn, geoip:private
- 出站
- direct
- 位置
- 拦截规则之后
域名条件在前、IP 条件在后,国内站点优先按域名判定。
代理组
- 域名
- geosite:geolocation-!cn
- 出站
- proxy
- 位置
- 规则列表末尾
- 兜底
- 未命中时的默认出站
这条可以省略,靠默认出站兜底;显式写出便于日后加例外。
在 v2rayN 里落地的步骤如下。
- 打开 v2rayN 主界面,进入「设置」→「路由设置」;7.x 版本在「设置」→「参数设置」→「路由」标签页里维护同一份列表。
- 按顺序逐条添加规则:条件一栏依次填
geosite:category-ads-all、geosite:private、geoip:private、geosite:cn、geoip:cn,出站分别选「拦截」或「直连」,备注写清用途。 - 把「域名策略」设为 IPIfNonMatch。除非需要按 IP 精确判定,不要选 IPOnDemand——它会让每条连接多做一次解析。
- 保存后重启内核,让新配置写入 config.json 并生效。
- 用 SOCKS 端口 10808(HTTP 端口 10809)分别访问一个国内站点和一个境外站点,在「日志」标签页确认两条请求的出站标签分别是 direct 与 proxy。
验证环节不要只看网页能不能打开。国内站点通过代理同样能打开,判断依据是日志里的出站标签:显示 direct 的是直连,显示 proxy 的是代理。国内站点显示 proxy,说明规则没有命中,按域名策略、规则顺序、DNS 的次序回查。
常见问题与排查顺序
下面四个问题覆盖了大多数分流异常,排查顺序固定为:先看域名策略,再看规则顺序,最后看 DNS。
国内站点还是走了代理,网页能开但明显变慢
先确认域名策略。AsIs 下内核不解析域名,geoip:cn 这类 IP 规则不会生效;改成 IPIfNonMatch,重启内核后再看日志里的出站标签。
加了 geosite:cn,新域名还是漏
geosite 集合是打包数据,新增域名有滞后。把漏掉的域名用 domain: 前缀补一条直连规则,插在兜底之前,再测一次。
局域网设备的管理页打不开
补一条 geoip:private 直连规则并放到列表最前。只写 geoip:cn 覆盖不到 192.168.0.0/16 这类地址段,请求会被送进节点。
规则保存后没有任何变化
v2rayN 在保存路由设置后才会重新生成核心配置,需要重启内核才生效;顺带确认日志里读到的规则条数与界面里显示的一致。
改完规则不要只看单次结果。国内站点与境外站点各测两三个,再打开日志扫一眼出站标签,确认 direct 与 proxy 都出现在预期的位置,规则才算定型。