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

逐条拆解 domain、full、regexp、ip、geosite、geoip 的写法,说明规则自上而下的匹配顺序,并整理常见误配的排查思路。

本文速览

适合已经导入订阅、需要给特定网站或网段单独分流的用户。先区分域名条件与 IP 条件,再看规则顺序和 DNS 解析时机。读完可以写出一组小范围例外规则,并用日志判断它为什么命中、为什么没有命中。

路由匹配优先级:先命中的规则生效

V2Ray 与 Xray 的常规路由规则按 routing.rules 数组从上到下检查。一旦某条规则匹配,就使用它指定的出站,不会继续寻找“更精确”的下一条。因此,精确域名写在大范围分类之后,并不会自动覆盖分类;需要主动把例外放到前面。

同一条规则里,domain 数组的多个条目通常是“或”的关系,任意一个匹配即可。不同条件字段通常是“且”的关系:同时写 domain 和 port,表示域名与目标端口都要符合。把域名和 IP 填进同一条规则,不等于“域名或 IP 任一匹配就生效”。

1 条
命中后结束本次规则选择
443
示例规则限定的目标端口
/32
单个 IPv4 地址的 CIDR 前缀

下面是一条“仅让指定主机的 443 端口走代理”的内核规则。这里的 proxy 是出站标签,不是内置关键字;完整配置中必须存在同名出站。它也不是节点显示名称,不能未经核对就替换成订阅里的节点名字。

{
  "type": "field",
  "domain": ["full:portal.example.com"],
  "port": "443",
  "outboundTag": "proxy"
}

domain、full、regexp:域名写法与匹配边界

domain 是规则里的字段名,domain: 则是字段值中使用的一种匹配前缀。两者不是同一层。写成 "domain": ["domain:example.com"] 才是完整的字段表达;不要把 full 或 regexp 当作与 domain 并列的规则字段。

条目写法实际含义边界提醒
full:example.com完整匹配该主机名不包含 www.example.com
domain:example.com匹配根域及其子域包含 a.example.com,不包含 notexample.com
regexp:^api[0-9]+\.example\.com$按正则表达式匹配此处展示匹配表达式;写入 JSON 时反斜杠需再次转义
example.com无前缀字符串按子串匹配范围可能比预期更宽,不适合精确例外
geosite:cn引用域名数据库中的分类分类内容由当前加载的数据文件决定

给单个站点加例外,优先选 full:;希望根域和所有子域一起走同一出口,选 domain:。只有主机名确实遵循固定模式时才用正则。不要在域名条目中填写 https://、路径或查询参数:路由判断的是目标主机,不是浏览器地址栏里的完整 URL。

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

这个数组里的三个条目是备选条件。访问 api12.example.com 可由正则匹配,访问 img.static.example.net 可由域名后缀匹配。JSON 中的 \\. 经过解析后才成为正则里的 \.,少写一层转义可能直接导致配置无法加载。

ip、geoip、geosite:网段与分类数据分开写

ip 数组用于目标 IP 条件,可写单个地址、CIDR 网段以及 geoip: 分类。geosite: 属于域名条件,应写在 domain 数组中。把两种分类前缀互换,不会得到预期的域名与地址联合分流。

{
  "type": "field",
  "ip": [
    "192.168.10.0/24",
    "10.0.0.8/32",
    "geoip:private"
  ],
  "outboundTag": "direct"
}

网站可能同时使用多个内容分发网络,同一域名在不同网络环境下也可能解析到不同地区的 IP。按域名分类与按地址分类得到不同出口,不一定是规则失效。先确认目标是“这个网站始终走代理”,还是“这些地址段走直连”,再决定使用哪种条件。

domainStrategy:什么时候为了路由解析域名

routing.domainStrategy 决定路由阶段如何处理域名与 IP 规则之间的关系,它不是 DNS 服务器地址,也不等同于出站连接时的地址选择策略。下面三种取值适用于 V2Ray/Xray 常见路由配置;具体行为仍应以正在运行的内核版本为准。

AsIs

推荐

对以域名形式进入的目标,不主动为路由匹配进行 IP 解析。以 IP 形式进入的目标仍可匹配 IP 规则。适合先把域名例外与规则顺序调通,减少排查变量。

适合:域名规则优先、初次验证自定义分流

IPIfNonMatch

域名在现有规则中没有匹配结果时,再尝试解析得到 IP 并参与后续规则匹配。若前面已有宽泛规则接住请求,就不会仅因后面存在 geoip 条目而必然触发解析。

适合:域名规则处理主要业务、IP 分类补充兜底

IPOnDemand

匹配过程中遇到需要目标 IP 的规则时,尝试解析域名。IP 规则放得很靠前时,可能更早触发 DNS 查询,也可能先于后面的域名例外决定出口。

适合:明确需要地址条件优先参与判断

结论:先调顺序,再改变解析策略

先用 AsIs 验证精确域名例外;确实需要 geoip 为域名请求补充判断时,再测试 IPIfNonMatch,并把前后两次日志中的目标地址与出站标签一起记录。

如果应用先自行解析域名,再向代理提交纯 IP,内核未必还能看到原始域名。流量嗅探在部分协议中可以补充域名信息,但并非对所有连接都有效;启用后也需区分“仅用于路由”与“改写目标”的配置效果。不要把打开嗅探当成域名规则必然生效的保证。

完整路由片段:精确例外放在分类前面

下面只展示可嵌入完整配置的 routing 部分,不是能独立启动的配置文件。示例假定已经有 direct 与 proxy 两个出站标签。顺序是局域网地址、精确域名例外、域名分类、IP 分类,最后才是 TCP/UDP 兜底。

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

这个例子有一个容易忽略的细节:最后的 network 规则会接住通常的 TCP/UDP 请求。在 IPIfNonMatch 下,域名请求如果已经被它匹配,就不会因为前面的 IP 分类尚未匹配而进入“完全无匹配后解析”的路径。因此,这里的 geoip:cn 主要处理已经带有目标 IP 的请求,不能把它理解成对所有剩余域名执行地址分类。

默认出站应在完整配置中明确核对,不能仅凭客户端界面上“当前选中的节点”推断。v2rayN 会生成运行配置,手动改动临时生成文件可能在切换节点或重启后被覆盖。长期规则应保存在客户端的路由配置中。

v2rayN 自定义路由:按单条规则验证

v2rayN 是桌面客户端,具体流量由所选内核运行。以下操作以包含「设置」→「路由设置」入口的桌面界面为准;不同版本的按钮位置与字段翻译可能调整。编辑前先记录当前路由配置名称,并保留原规则,避免把订阅节点问题和路由问题混在一起排查。

  1. 打开路由设置

    进入「设置」→「路由设置」,记录正在使用的路由配置。先导出或复制现有规则,再添加例外。

  2. 填写域名条件

    在规则编辑窗口的域名条件中填入 full:portal.example.com。图形界面字段通常只接收条目,不要把整个 routing JSON 粘贴进去。

  3. 选择目标出站

    按实际需求选择代理或直连。若编辑的是内核 JSON,则检查 outboundTag 与 outbounds 中的标签逐字一致。

  4. 上移并启用

    将例外移动到域名分类和宽泛兜底之前,保存后在主界面的路由选择处启用这份配置;不要只保存却仍使用原方案。

  5. 重建测试连接

    关闭原测试页面和旧连接,再发起新请求。查看内核日志中的目标主机、目标端口和出站标签,每次只修改一项条件。

验证时可先把真实测试主机写成 full: 例外,确认命中后再扩大为 domain: 或分类。浏览器连接复用会让旧连接继续使用原出口,仅刷新页面不一定建立新连接。使用命令行工具测试时,也要显式使用客户端界面显示的本地代理端口,不要假定每台机器都使用同一端口。

路由规则不生效:按现象定位原因

域名写对了,为什么还是走直连?

先把精确规则移到分类规则之前,再确认当前启用的是修改后的路由配置。若日志目标只有 IP,继续检查应用是否提前解析,以及内核能否取得域名信息。

为什么 geosite 保存后内核启动失败?

查看日志是否提示域名数据文件不存在或分类无法加载。确认 geosite.dat 的资源路径与分类名称,先用一条 full 域名规则验证基础配置,再恢复分类条目。

网页主站走代理,图片却没有走?

在浏览器网络面板查看图片请求的实际主机名。图片可能来自另一个根域,主站的 domain 条目不会覆盖它;核对用途后,为资源域名单独添加规则。

端口 443 已经匹配,为什么下载仍失败?

端口条件只决定分流,不保证目标可达。检查日志中的出站标签是否正确,再分别排查节点连通性、DNS 结果与 UDP 支持;443 端口既可能承载 TCP,也可能承载 UDP 流量。

重启客户端以后,自定义规则怎么没了?

确认改动是否只写入了临时生成的内核配置。回到「设置」→「路由设置」保存规则并启用对应方案;使用独立自定义配置时,则维护实际被加载的源文件。

最后用三个问题收尾:连接是否进入内核、内核看见的是域名还是 IP、第一条命中规则指向哪个出站。先回答这三个问题,通常比同时更换 DNS、切换内核和重建订阅更容易定位原因。更多字段解释可查阅协议与内核参考,不熟悉的术语可对照术语手册。

v2rayN下载