Xray路由规则深度解析:JSON进阶配置与自定义实践

深入解析 Xray-core 路由引擎的匹配顺序、domainStrategy、geosite 与 geoip 规则,提供可直接粘贴运行的 JSON 配置示例。本文还涵盖分流设计、DNS 防泄露、规则集维护、日志调试及生产环境模块化管理,帮助技术用户构建稳定可维护的自定义路由方案。

路由是 Xray 配置中决定“哪一类连接走哪里”的核心部分。节点能够连接,只说明入站、出站和传输参数基本可用,并不代表国内网站一定直连、广告一定被拦截,或者 DNS 请求已经按照预期分流。真正的分流结果,取决于 routing 中的匹配顺序、域名与 IP 规则、domainStrategy 的解析策略,以及每条规则最终指向的 outboundTag

本文以 Xray JSON 配置为主线,逐层解释 routingrules、域名和地址匹配、DNS 分流、黑洞拦截与规则集调用。示例适用于需要手动维护配置的 Xray-core 场景,也可以帮助使用 v2rayN、v2rayNG、NekoBox 等客户端的用户理解图形界面背后生成的路由结构。不同客户端可能会重新组织字段,但最终仍需要由内核读取有效的 Xray 配置。

本文速览

本文解决 Xray 路由规则不会写、规则命中结果难判断、DNS 分流与业务流量混在一起等问题,适合已经能导入节点、准备进一步自定义直连、代理、拦截和规则集的读者。读完后可以独立搭建一份结构清晰、便于备份和排错的 routing 配置。

路由引擎如何决定出站

一个连接进入 Xray 后,内核会先获得目标域名、目标 IP、目标端口、来源入站、网络类型等信息。若启用了流量探测,还可能从 TLS 或 HTTP 握手中识别出实际域名。路由模块随后按照 rules 数组逐条匹配,命中后把连接交给规则指定的出站标签。常见的出站包括代理节点、自由直连和黑洞拦截,也可以是专门处理 DNS 请求的出站。

应用发起请求入站接收连接提取目标信息规则逐条匹配出站处理请求

路由只负责“选择出口”,不负责替你创建代理服务器。配置中必须存在与规则标签对应的 outbounds。例如规则写了 "outboundTag": "proxy",就必须有一个 "tag": "proxy" 的出站;如果标签拼写不一致,连接可能落入默认行为,或者在日志中出现找不到出站的错误。

routing.domainStrategy 决定域名目标如何参与地址规则判断。常用的 AsIs 会优先按原始域名匹配,不主动为了 IP 规则解析地址;IPIfNonMatch 会先尝试域名规则,未命中时再解析 IP;IPOnDemand 则会在路由判断需要地址时更积极地触发解析。对于“国内域名直连、国内 IP 直连、其他流量代理”的配置,IPIfNonMatch 通常比一开始使用 IPOnDemand 更容易观察和调试。

  • domain 规则适合按域名后缀、完整域名或正则表达式匹配。
  • ip 规则适合按 IPv4、IPv6、CIDR 网段或 geoip 数据匹配。
  • portnetworkprotocol 可进一步限制端口、TCP/UDP 或已识别的应用协议。
  • inboundTagusersource 可按入口、用户或来源地址区分连接。
  • outboundTag 指定固定出站,balancerTag 则把连接交给负载均衡器选择。

rules 字段与匹配优先级

最小可用的路由结构一般如下。这里的 directproxyblock 只是标签名称,可以按自己的出站定义修改。没有匹配到任何规则时,Xray 通常使用出站列表中的默认出站,因此不建议把“默认行为”完全交给配置顺序猜测,最好在最后加入一条明确的兜底规则。

{
  "routing": {
    "domainStrategy": "IPIfNonMatch",
    "rules": [
      {
        "type": "field",
        "domain": [
          "full:internal.example",
          "domain:lan.example"
        ],
        "outboundTag": "direct"
      },
      {
        "type": "field",
        "ip": [
          "geoip:private"
        ],
        "outboundTag": "direct"
      },
      {
        "type": "field",
        "domain": [
          "geosite:category-ads-all"
        ],
        "outboundTag": "block"
      },
      {
        "type": "field",
        "network": "tcp,udp",
        "outboundTag": "proxy"
      }
    ]
  }
}

type 常见值为 field,表示按照字段组合进行匹配。同一条规则中的多个字段通常表示“同时满足”;同一个字段数组中的多个项目则表示满足其中任意一个。例如一条规则同时写入 inboundTagdomain,就只会处理来自指定入站且目标域名符合条件的连接。

域名前缀的含义不能混用。full:example.com 只匹配完整的 example.comdomain:example.com 通常匹配该域名及其子域名;regexp: 用于正则匹配,但复杂正则会增加维护成本。直接写裸域名时,实际解释可能受内核版本和规则格式影响,手动配置时建议显式写出 full:domain:regexp:,让规则意图更清楚。

规则顺序应从窄到宽。例如,某个国内域名需要特殊代理,就必须放在一般的国内直连规则之前;广告域名需要拦截,就不能排在“所有国内域名直连”的规则之后。可以把优先级整理为:局域网和固定例外、必须拦截的目标、特定代理目标、国内域名与国内 IP、最后的代理兜底。

字段 典型写法 适用场景 排查重点
domain domain:example.com 按域名后缀分流 确认是否需要包含子域名
ip geoip:cn 按地址区域或网段分流 确认域名是否已被解析
port 80,443 限制目标端口 端口条件过窄会导致规则看似无效
network tcp,udp 区分连接类型 注意逗号分隔格式和客户端生成方式
protocol http,tls 按嗅探结果处理 未启用 sniffing 时可能无法命中

结论:先设计优先级,再填写规则

一条规则是否正确,不只取决于字段写法,还取决于它前面有没有更宽泛的规则抢先命中。遇到“自定义域名不生效”,第一检查项通常是规则顺序,而不是立刻修改正则表达式。

动手建立直连、代理与拦截体系

建议先复制当前配置并改名保存,例如 config-routing-test.json,不要直接覆盖订阅生成的原始文件。v2rayN 中可在当前配置的高级设置或自定义配置位置查看内核配置;v2rayNG 则应先导出或复制当前配置,再在可恢复的副本上修改。不同版本的菜单名称可能略有差异,核心原则是保留原文件、修改副本、验证 JSON、再载入内核。

  1. 准备出站标签

    先确认配置中存在 proxydirectblock 三个标签,分别对应代理节点、自由直连和黑洞出站。

  2. 设定解析策略

    routing 中加入 "domainStrategy": "IPIfNonMatch",让域名规则优先,未命中时再考虑 IP 规则。

  3. 添加局域网规则

    geoip:private 和内部域名放在前面,避免打印机、路由器管理页和局域网服务被送入代理。

  4. 加入拦截规则

    将确认无误的广告或追踪规则集指向 block,先少量启用,防止误拦截登录、支付或验证码域名。

  5. 最后设置兜底

    把需要代理的广泛规则放在末尾,重载配置后查看日志和实际访问结果,再逐步增加自定义域名。

对应的出站可以采用下面这种基础结构。代理出站中的服务器地址、端口和用户信息必须替换为服务端真实参数;示例只展示路由所依赖的标签关系。blackhole 出站用于主动拒绝连接,和直连失败不是同一种结果,因此不应把所有无法访问的域名都直接归类为拦截。

{
  "outbounds": [
    {
      "tag": "proxy",
      "protocol": "vmess",
      "settings": {
        "vnext": [
          {
            "address": "server.example",
            "port": 443,
            "users": [
              {
                "id": "00000000-0000-0000-0000-000000000000"
              }
            ]
          }
        ]
      }
    },
    {
      "tag": "direct",
      "protocol": "freedom"
    },
    {
      "tag": "block",
      "protocol": "blackhole"
    }
  ]
}

如果只想让一个域名走代理,可以使用更具体的规则;如果想拦截一个完整主机名,则使用 full: 限定范围。不要为了拦截一个域名直接写成过宽的 domain:,否则同一组织下的更新服务、静态资源或认证接口也可能被一并阻断。

国内直连

域名
geosite:cn
地址
geoip:cn
出站
direct

适合降低国内访问延迟,规则必须排在代理兜底前。

海外代理

匹配
未命中前序规则
网络
TCP、UDP
出站
proxy

适合作为最后的宽范围规则,避免覆盖局域网例外。

广告拦截

域名
geosite:category-ads-all
协议
域名请求
出站
block

启用前应准备白名单,误拦截时优先移除具体规则。

DNS 专用

端口
53
目标
DNS 请求
出站
dns-out

DNS 出站标签需与 dns 配置和路由规则同时存在。

DNS 分流与业务连接要分开看

DNS 分流最容易出现“解析走对了,但网页仍然走错出口”的误判。把 DNS 请求交给 dns-out,只代表查询行为使用了指定出站;之后应用访问解析结果得到的业务连接,仍然需要由普通路由规则决定走 direct 还是 proxy。因此,DNS 规则与业务规则应分别设计、分别验证。

当应用把域名直接交给入站时,Xray 可以先依据域名匹配 domaingeosite。如果目标已经是 IP,或者启用了需要地址参与判断的策略,内核才可能触发解析。若配置使用透明代理或 TUN,还需要留意应用是否在连接前自行解析、是否启用了流量探测,以及 IPv6 地址是否真正可达。

{
  "routing": {
    "domainStrategy": "IPIfNonMatch",
    "rules": [
      {
        "type": "field",
        "inboundTag": [
          "dns-in"
        ],
        "port": 53,
        "outboundTag": "dns-out"
      },
      {
        "type": "field",
        "domain": [
          "geosite:cn"
        ],
        "outboundTag": "direct"
      },
      {
        "type": "field",
        "ip": [
          "geoip:cn",
          "geoip:private"
        ],
        "outboundTag": "direct"
      },
      {
        "type": "field",
        "outboundTag": "proxy"
      }
    ]
  }
}

在实际配置中,不要把所有 UDP 流量简单送入代理后就认为 DNS 已经安全分流。某些应用可能使用加密 DNS、独立解析库或固定地址,常规的 53 端口规则不会覆盖这些请求。排查时可以先关闭复杂规则集,只保留一个 DNS 出站、一个直连规则和一个代理兜底,确认基础链路正常后再增加细分条件。

规则集调用与自定义维护

规则集适合承载数量较大的域名或 IP 列表,避免把几千条内容直接写进主配置。常见来源包括内核附带的 geosite.datgeoip.dat,以及 Xray 支持的本地或远程规则集格式。不同 Xray-core 版本对规则集字段、文件格式和下载方式可能存在差异,迁移配置时应以当前内核文档和启动日志为准,不要把其他代理内核的规则集语法直接复制过来。

使用内置分类时,常见写法是 geosite:cngeosite:category-ads-allgeoip:private。这类引用依赖对应的数据文件存在且版本匹配。若日志提示找不到 geosite 或 geoip 数据,不应先怀疑 routing 语法,应该检查 Xray-core 的运行目录、数据文件路径、客户端内核安装状态以及文件版本。

自定义规则建议按用途拆分。例如把公司域名放在“工作直连”集合,把需要固定代理的域名放在“指定代理”集合,把拦截目标放在“广告拦截”集合。每个集合只负责一类判断,主配置中的规则则负责表达优先级。这样修改一个域名时,不会同时改变 DNS、端口和默认代理逻辑,也便于在 v2rayN 或其他客户端中切换不同配置副本。

  • 域名规则尽量使用明确的完整域名或后缀,不要用过宽的正则替代所有分类。
  • 自定义规则加入后,至少测试首页、登录页、静态资源和接口请求。
  • 规则集更新失败时保留上一份可用数据,不要让启动过程依赖临时下载。
  • 修改规则集后记录日期、内核版本和变更原因,便于回滚到 2026 年当前使用的稳定版本。
  • 把订阅自动生成部分与手写覆盖部分分开,避免下一次更新订阅时丢失自定义内容。

为什么写了域名规则却没有命中?

先确认应用提交的是域名而不是已经解析出的 IP,再检查 domainStrategy、规则顺序和域名前缀。若依赖流量探测,还要确认入站启用了 sniffing 并且目标协议能够被识别。

把国内规则放前面就一定直连吗?

不一定。还要确认直连出站标签确实存在、DNS 结果没有异常、目标没有被更早的特殊代理规则命中,并检查实际连接是否使用 IPv6 或独立解析地址。

广告拦截后某个网站无法登录怎么办?

先暂时移除对应分类规则,确认登录恢复,再从日志中找到被拦截的完整域名,增加一条更具体的直连或代理例外,并将例外放在拦截规则之前。

规则集加载失败会影响所有节点吗?

取决于配置是否要求启动时必须加载该规则集。建议先用内置 geositegeoip 分类验证路由,再检查文件路径、数据格式与 Xray-core 版本,避免在未知状态下继续叠加规则。

日志验证、回滚与长期维护

路由调试不能只看浏览器最终能否打开网页。应先启用适度的 Xray 日志,观察连接目标、命中的出站和错误原因。测试时固定一个节点、一个应用和一个目标域名,先验证直连目标,再验证代理目标,最后验证拦截目标。一次修改多个规则会让结果难以归因,尤其是同时改变 DNS、嗅探和 domainStrategy 时。

可以把配置拆成几个可读区段:入站、出站、DNS、路由和日志。JSON 本身不支持注释,因此可在配置管理目录中使用外部变更记录,写明“新增规则、预期出站、测试结果和回滚文件名”。保存前使用客户端提供的配置检查功能,或用可靠的 JSON 校验工具检查括号、逗号、引号和数组层级。格式合法只代表 JSON 能解析,不代表标签、字段和规则语义正确。

推荐保留三个版本:最近一次可用配置、当前测试配置和最小应急配置。最小应急配置只保留一个代理出站、一个直连出站和一条代理兜底规则,出现全局无法联网时可以快速替换。升级 Xray-core、v2rayN 或 v2rayNG 后,先用最小配置确认内核能启动,再恢复规则集和复杂分流,能明显减少版本变化带来的排查范围。

可执行判断:先让最小规则跑通

复杂路由不是越多越可靠。先用“局域网直连、一个明确代理目标、一个代理兜底”验证链路,再逐步加入国内分类、DNS 分流和拦截规则;每增加一组规则都保留测试结果,出现异常时才能快速回到上一份稳定配置。

下载v2rayN