V2Ray 自定义路由规则写法:domain、ip、geosite 匹配语法与优先级

详解 domain 前缀、full 与 regexp 匹配,ip 与 geoip 写法,geosite 分类引用,以及规则从上到下的命中顺序和 domainStrategy 的影响。

本文速览

本文适合已能连接节点、准备调整分流规则的用户。先确认内核拿到的是域名还是 IP,再选择匹配语法、排列规则,并通过日志验证出口。文中的 JSON 是内核配置片段,不是订阅内容;理解这些差别后,可以定位“规则已添加却没生效”“私网流量误走代理”和“分类规则加载失败”等问题。

一、路由规则如何决定出口

v2rayN 是客户端界面,V2Ray 或 Xray 内核负责实际匹配与转发。VMess、VLESS 是连接节点时使用的协议,不决定某个网站必须走哪个出口。路由位于连接处理过程中,依据目标域名、目标 IP、端口及入站标签等信息,选择一个已有的出站。

接收入站 读取目标 顺序匹配 选择出站 建立连接

routing.rules 从上到下检查,第一条满足条件的规则决定出口,不会继续寻找“更精确”的规则。没有规则命中时,通常使用 outbounds 数组的第一项;因此默认出口也必须检查,不能只看规则末尾。

二、domain、full 与 regexp 的匹配边界

domain 既是规则中的字段名,也可以是字段值的前缀,两者不是一回事。字段负责容纳域名条件,前缀负责规定如何匹配。需要覆盖主域名及所有子域名时,优先使用 domain:;只允许一个完整主机名时,使用 full:。

写法匹配行为边界示例
example.com不带前缀时按子串匹配也可能匹配 notexample.com
domain:example.com匹配主域名及其子域名匹配 img.example.com,不匹配 notexample.com
full:api.example.com匹配完整域名不匹配 img.api.example.com
regexp:^api[0-9]+\\.example\\.com$正则表达式;此处展示 JSON 字符串内的写法匹配 api12.example.com,不匹配 api.example.com

域名规则不匹配网页 URL 的路径。若要处理 https://api.example.com/v1/status,目标域名是 api.example.com,不能把协议头、路径或查询参数一并写进域名字段。HTTPS 路径也不是普通路由规则可直接识别的条件。

{
  "type": "field",
  "domain": [
    "full:api.example.com",
    "domain:static.example.net",
    "regexp:^edge[0-9]+\\.example\\.org$"
  ],
  "port": "443",
  "outboundTag": "proxy"
}

这条规则表示:三个域名条件满足任意一个,并且目标端口为 443,才走 proxy。正则中的点号需要转义;在 JSON 字符串里,一个反斜杠还要再转义,所以写成 \\.。若在客户端的纯文本域名输入框中填写,通常只需要 \.,不要把两种输入环境混用。

三、ip、CIDR 与 geoip 的适用场景

ip 字段处理目标 IP,可以填写单个地址、CIDR 网段或 geoip: 分类。它判断的是这次请求的目标地址,不是电脑本身的网卡地址,也不是节点服务器的地址。应用直接访问 IP 时,即使不进行域名解析,仍然可以命中 IP 规则。

显式网段规则

单个地址
192.168.1.10
IPv4 网段
192.168.0.0/16
IPv6 网段
fc00::/7
数据依赖
不依赖地理分类文件

适合明确知道边界的局域网或固定服务网段。

geoip 分类规则

私有地址类
geoip:private
地区地址类
geoip:cn
常见数据文件
geoip.dat
维护重点
分类存在且数据可读取

分类范围由所用数据集决定,不等同于实时网络位置。

{
  "type": "field",
  "ip": [
    "127.0.0.0/8",
    "10.0.0.0/8",
    "172.16.0.0/12",
    "192.168.0.0/16",
    "::1/128",
    "fc00::/7"
  ],
  "outboundTag": "direct"
}

上述片段展示显式直连网段,并不是完整的特殊用途地址清单。若采用 geoip:private,应以当前数据集收录范围为准。对于公司内网,最好把实际使用的网段单独写明,避免仅凭“私网分类应该包含”作判断。

四、geosite 分类引用与数据文件

geosite: 写在 domain 数组中,用来引用域名集合;geoip: 则写在 ip 数组中。两者不是可以互换的前缀。geosite:cn 表示引用数据集中名为 cn 的集合,不能简单理解为所有以 .cn 结尾的域名。

{
  "type": "field",
  "domain": [
    "geosite:cn"
  ],
  "outboundTag": "direct"
}

若内核在加载配置时立即退出,应先查日志中的资源加载错误,而不是反复切换节点。分类规则尚未成功加载时,连接速度测试无法证明路由配置正确。暂时移除有问题的分类引用、保留一条明确域名规则,有助于区分配置错误与网络故障。

五、domainStrategy 如何影响 IP 规则

routing.domainStrategy 控制路由判断时是否为域名目标解析 IP,不直接等同于最终出站的 DNS 策略。它也不会凭空恢复应用已经丢失的域名:如果应用提交的只有 IP,想使用域名规则还需要考虑入站嗅探等条件,而且嗅探并非对所有流量都有效。

策略域名目标的处理常见影响
AsIs不为路由匹配主动把域名解析成 IP域名目标通常不能仅靠 IP 规则分流;原本就是 IP 的目标仍可匹配
IPIfNonMatch先按现有目标信息匹配;未命中时再解析域名并重新匹配首轮若已命中兜底规则,就不会触发这次回退解析
IPOnDemand匹配过程中遇到需要目标 IP 的条件时解析域名靠前的 IP 规则可能先命中,影响后面的域名例外

一个常见误区是:设置了 IPIfNonMatch,又在规则末尾写了覆盖全部 TCP、UDP 的代理规则。由于这条兜底在首轮就能命中,域名目标不会走到“未命中后解析 IP”的步骤;前面的 geoip:cn 因而可能没有机会判断解析结果。

结论:先确定兜底方式,再选择解析策略

若需要用 IP 分类承接未匹配的域名,使用 IPIfNonMatch 时可依靠第一出站兜底,而不是加一条首轮必中的末尾规则;若选择 IPOnDemand,则把必须保留的域名例外放在宽泛 IP 分类之前。

这里的 DNS 结果会直接影响 IP 分类判断。遇到“同一个域名今天直连、明天代理”,应同时查看解析结果和分类数据,而不是立即认定规则顺序失效。更完整的 DNS 与路由字段说明可参照配置参考。

六、一份按优先级排列的路由示例

下面选用 IPOnDemand,明确展示“指定域名例外、私网直连、域名分类、IP 分类、最后代理”的顺序。它只是可并入现有配置的 routing 对象:前提是配置中已经有 proxy 和 direct 两个出站标签,并且相关分类数据可用。

{
  "routing": {
    "domainStrategy": "IPOnDemand",
    "rules": [
      {
        "type": "field",
        "domain": [
          "full:api.example.com"
        ],
        "outboundTag": "proxy"
      },
      {
        "type": "field",
        "ip": [
          "geoip:private"
        ],
        "outboundTag": "direct"
      },
      {
        "type": "field",
        "domain": [
          "geosite:cn"
        ],
        "outboundTag": "direct"
      },
      {
        "type": "field",
        "ip": [
          "geoip:cn"
        ],
        "outboundTag": "direct"
      },
      {
        "type": "field",
        "network": "tcp,udp",
        "outboundTag": "proxy"
      }
    ]
  }
}

示例中的 api.example.com 是用于解释规则的保留示例域名,不是可用性测试服务。它被放在第一条,因此即便之后的 IP 分类可能匹配,也会优先选择代理。实际使用时,把这一条改为需要固定出口的真实业务域名,或者直接删除。

  1. 保留原配置:在客户端中导出现有配置,记录当前启用的路由方案,避免修改失败后无法恢复。
  2. 检查真实标签:查看生成配置中 outbounds 的 tag,确认与示例一致;客户端可能使用不同的标签名。
  3. 仅合并路由对象:不要用这段内容覆盖完整配置,否则会丢失入站、节点出站、DNS 等必要部分。
  4. 在界面中保存并启用:v2rayN 的菜单名称会随版本变化,常见入口为「设置」→「路由设置」;新增规则后还需确认目标路由方案已启用。
  5. 重新建立测试连接:保存后按客户端提示重载或重启内核,并关闭旧网页连接再测试。已建立连接不一定重新执行路由匹配。

七、如何确认规则真正命中

网页能打开,只能说明连接成功,不能说明出口正确。验证分流应同时记录目标、协议、命中出口和测试时间。先用单个完整域名建立最小测试,再逐步加回分类规则,比一次修改十几条规则更容易定位问题。

  1. 确认流量进入内核:检查浏览器是否遵循系统代理。命令行测试可使用 curl --proxy socks5h://127.0.0.1:10808 https://example.com/ -I;其中 10808 必须替换为客户端实际 SOCKS 入站端口。
  2. 保留域名目标:上述命令使用 socks5h,把域名交给代理端处理;若应用先在本地解析再提交 IP,域名规则的测试前提就变了。
  3. 查看内核日志:关注目标地址和出站标签;日志格式因内核版本而异。访问日志未启用时,应按当前版本设置临时开启,而不是把“没有记录”当成没有流量。
  4. 建立三组对照:分别测试一个明确域名例外、一个可达的内网地址、一个普通公网域名,记录预期出口与实际出口。内网服务端口可按实际情况使用 80 或 443。
  5. 清理测试条件:关闭旧连接后重试;必要时重启测试应用。完成后恢复日常日志级别,避免长期积累详细访问记录。

为什么加了 full 规则,子域名还是不走代理?

full:example.com 只覆盖这个完整主机名。若需要同时覆盖 www.example.com,改用 domain:example.com,并把规则移到宽泛直连规则之前,再重新建立连接。

domain 和 ip 都填了,为什么更难命中?

同一条规则的两个字段不是二选一。若目标是“这些域名或这些 IP 都直连”,应拆成两条规则,并为两条分别设置同一个 outboundTag。

复制 geosite 分类后内核无法启动怎么办?

查看首条加载错误,确认 geosite.dat 的资源路径和分类名称。先移除该分类,使用 full: 规则验证内核能正常运行,再恢复有效的数据文件与分类。

安卓端能直接照搬桌面的整份配置吗?

v2rayNG 使用 Xray 内核,v2flyNG 使用 v2fly 内核;基础匹配语法相近,但出站标签、资源文件位置与导入方式由客户端决定。先核对所选内核支持的字段,再迁移路由片段,不要直接覆盖整份运行配置。

排查时优先遵循“目标信息、规则顺序、解析策略、数据文件、实际出口”的顺序。先证明一条精确规则能够生效,再扩大到域名集合和 IP 分类,通常比反复更换整套规则更可靠。

V2Ray客户端下载