适合已经导入节点、准备修改 v2rayN 分流规则的用户。本文先区分域名字段与 IP 字段,再用可检查的 JSON 片段解释前缀、规则顺序和域名解析策略;最后给出客户端内的验证步骤,避免把规则未命中、出站标签错误和 DNS 解析失败混成一个问题。
先分清:字段、匹配值与出站标签
V2Ray 与 Xray 的常见路由配置位于 routing.rules 数组中。每一项描述“哪些连接符合条件”和“符合后交给哪个出站”。domain、ip 是字段名;domain:、full:、geosite: 是域名匹配值里的前缀。不要把这两层语法混在一起。
下面是一条完整的路由规则,不是完整的内核配置。它把目标域名恰好为 example.com 的 TCP 443 端口连接交给名为 proxy 的出站。端口指目标服务端口,不是客户端本地监听端口。
{
"type": "field",
"domain": ["full:example.com"],
"network": "tcp",
"port": "443",
"outboundTag": "proxy"
}
- 同一字段内通常是“或”:
domain数组里的任意一个域名条件命中,即满足该字段。 - 不同条件字段之间是“且”:上例必须同时满足域名、TCP 和目标端口 443,才会选中该出站。
- 标签必须真实存在:
outboundTag引用outbounds中的tag,不是节点备注,也不是可以随意填写的中文动作说明。
域名前缀:domain、full、regexp 与 geosite
同一域名使用不同前缀,匹配范围会明显变化。配置“主域名及全部子域名”时,优先使用 domain:;只处理一个精确主机名时,使用 full:。这两种写法比宽泛的关键字匹配更容易检查。
| 写法 | 匹配范围 | 需要注意 |
|---|---|---|
domain:example.com | example.com 及其子域名,如 api.example.com | 不会匹配 notexample.com |
full:example.com | 仅 example.com | 不包含 www.example.com |
regexp:^api[0-9]+\.example\.com$ | 如 api1.example.com、api20.example.com | 正则锚点限制完整名称 |
geosite:cn | 数据文件中 cn 分类的域名条目 | 分类内容取决于所用数据文件 |
example.com | 域名中包含该文本的目标 | 裸字符串不是后缀边界匹配 |
geosite: 引用的是本地域名分类数据,不是实时查询网站所属地区。geosite:cn 也不等同于“所有以 .cn 结尾的域名”:它可以包含其他后缀的域名,也可能暂时缺少新站点。分类名、属性和条目必须以实际安装的数据文件为准。
正则还有一层 JSON 转义。表格中的正则是匹配表达式;写进 JSON 字符串时,表示字面点号的反斜杠要写两次。若在客户端的普通文本输入框填写规则,则按该输入框的格式要求输入,不要机械地再加一层转义。
{
"type": "field",
"domain": [
"domain:example.com",
"regexp:^api[0-9]+\\.example\\.net$"
],
"outboundTag": "proxy"
}
结论:先用精确规则验证,再扩大范围
排查单个网站时先添加 full: 规则。确认命中后,再决定是否改为 domain: 或分类规则;不要一开始就用宽泛正则覆盖大量目标。
IP 规则:地址、CIDR 与 geoip
IP 条件写在 ip 数组里。单个地址直接填写,网段使用 CIDR,地区或特殊地址集合使用 geoip:。标准写法不是给地址加上 ip: 前缀;将 ip:192.168.1.1 当作数组值,可能直接导致配置加载失败。
地址与网段
- 配置字段
ip- 单个地址
192.168.1.1- IPv4 网段
192.168.0.0/16- IPv6 网段
fc00::/7
适合明确的设备地址或内部网段,避免依赖域名分类。
IP 数据集合
- 配置字段
ip- 地区集合
geoip:cn- 私有地址集合
geoip:private- 数据依赖
geoip.dat
集合是否存在、覆盖哪些地址,要以当前数据文件为准。
当请求进入内核时已经是 IP 目标,IP 规则可以直接参与匹配;如果目标还是域名,能否用解析结果继续匹配,取决于 domainStrategy。浏览器自行解析、应用直接连接 IP、客户端嗅探恢复域名等因素,也会改变路由器最终能看到的目标信息。
- 不要按域名后缀推断服务器地区:一个域名可能解析到多个地区的地址,接入 CDN 后更常见。
- 不要只补 IPv4:如果应用实际连接 IPv6 地址,只写 IPv4 网段不会覆盖那次连接。
- 私有地址直连要结合网络环境:本地局域网通常需要直连;需要经过远端网络访问的内部地址,应单独设计规则并放在宽泛直连规则之前。
匹配优先级:先命中,不是越精确越优先
路由规则按数组顺序自上而下检查,首条满足条件的规则决定出站。内核不会在所有命中项里挑“看起来最精确”的一条。精确域名只有放在宽泛规则之前,才能稳定表达例外。
{
"routing": {
"domainStrategy": "AsIs",
"rules": [
{
"type": "field",
"domain": ["full:ads.example.com"],
"outboundTag": "block"
},
{
"type": "field",
"domain": ["domain:example.com"],
"outboundTag": "proxy"
},
{
"type": "field",
"ip": ["geoip:private"],
"outboundTag": "direct"
},
{
"type": "field",
"network": "tcp,udp",
"outboundTag": "proxy"
}
]
}
}
这是用于并入现有配置的 routing 片段,不包含入站、出站和 DNS 配置。假设三个标签均已定义:ads.example.com 命中第一条后被阻断;www.example.com 命中第二条走代理;直接访问私有地址时可命中第三条;其余 TCP、UDP 连接由最后一条兜底。
- 先放必须覆盖其他规则的精确例外,例如单个域名阻断或指定服务走代理。
- 再放域名集合与 IP 集合;如果它们可能重叠,应明确希望哪一类先决定结果。
- 最后才放宽泛兜底。把
network: tcp,udp对应的规则移到顶部,后面的普通 TCP、UDP 规则就没有匹配机会。
若所有规则都未命中,常规 V2Ray/Xray 配置会使用第一个出站,不会自动理解“国内直连、其他代理”。显式兜底便于阅读,但它也会影响域名解析后的再次匹配,不能脱离域名策略单独调整。
domainStrategy:何时解析,何时重试 IP 规则
routing.domainStrategy 控制路由匹配阶段如何处理域名,不等于客户端的全部 DNS 设置,也不代表应用一定把域名交给内核。先确认入站收到的是域名还是 IP,再判断该选哪种策略。
| 策略 | 路由阶段的行为 | 适用判断 |
|---|---|---|
AsIs | 不为了路由匹配主动解析目标域名 | 主要依靠域名规则,或希望减少路由阶段的解析依赖 |
IPIfNonMatch | 域名未匹配到规则时,再尝试解析并参与 IP 匹配 | 域名规则优先,IP 规则作为补充 |
IPOnDemand | 匹配过程中遇到需要 IP 判断的规则时,尝试解析 | 明确需要让较早的 IP 规则参与决策 |
关键陷阱是 IPIfNonMatch 与无条件兜底的组合:如果第一轮检查已经命中最后的 TCP、UDP 兜底规则,就不属于“未匹配”,不能指望随后再解析域名来命中 geoip:cn。需要依赖这一策略做 IP 补充分流时,应检查是否有提前结束匹配的宽泛规则,并同步确认未命中时的默认出站。
IPOnDemand 则需要特别关注顺序。较早的 IP 规则可能触发解析并命中,使后面的域名例外失去机会。要保证某个域名固定走代理,应把它的精确规则放在可能覆盖它的 IP 规则之前。
结论:改域名策略时,同时检查兜底位置
将策略切到 IPIfNonMatch 后,不要只测试一个网站是否打开。还要检查目标是否在第一轮被兜底截获,以及日志中最终选中的出站是否符合预期。
在 v2rayN 中修改并验证规则
v2rayN 的路由编辑界面会随版本调整。常见入口是「设置」→「路由设置」;进入后先确认正在编辑的规则集,再检查主窗口当前启用的路由是否就是这一组。只修改列表中未启用的规则集,不会改变现有连接的分流。
- 保存当前状态:备份现用规则,记录当前内核类型、域名策略及最终出站。本文讨论的是 V2Ray/Xray 格式,不要直接复制到其他内核的不同配置结构中。
- 只增加一条可验证规则:在域名条件中填入
full:加实际目标主机名,选择对应出站,并将它移到覆盖该目标的宽泛规则之前。 - 应用并重新建立连接:保存规则,必要时重启内核。关闭测试页面的既有连接后重试;已经建立的长连接不会因为调整规则而自动迁移出站。
- 查看日志证据:按当前版本提供的日志设置,临时提高到
info或排查所需级别,查找目标域名、目标端口和出站标签;检查完成后恢复日常日志级别。 - 逐步扩大规则:精确域名测试通过后,再改成
domain:或添加geosite:,每次只改一个因素,便于判断回归原因。
常见写法误区与修正
填了 domain:example.com,为什么另一个网站也被代理?
先检查是否还有裸字符串、分类规则或代理兜底命中。domain:example.com 本身只覆盖该域名及子域名,不会匹配 notexample.com。查看实际出站日志后,再逐条缩小规则范围。
写了 geosite:cn,为什么内核启动时报分类不存在?
核对当前内核使用的 geosite.dat 是否存在,以及文件内是否包含 cn 分类。通过当前客户端提供的数据更新入口更新后重试;不要把其他规则格式的文件直接改名替换进去。
正则放进 JSON 后报转义错误,应该改哪里?
检查反斜杠:匹配字面点号的正则 \. 在 JSON 字符串中应写为 \\.。同时检查英文双引号与数组逗号。若配置能加载却不命中,再检查锚点和真实主机名。
精确直连规则已经加了,为什么仍然走代理?
把它移到宽泛代理规则前,确认修改的是已启用规则集,再重建连接。如果日志只显示目标 IP,检查应用是否自行解析以及嗅探设置是否适用;内核拿不到域名时,精确域名规则无法直接命中。
domain 与 ip 放在同一条里,是任意命中就生效吗?
不是。不同条件字段需要同时满足。若想表达“这个域名或者这个网段都直连”,拆成两条规则,并为两条选择同一个直连出站。这样也更方便分别验证域名和 IP 条件。