Skip to content

Routing — Xray-core ​

routing 块是决定连接走哪个出站的引擎。它承载一份按顺序匹配(先命中先赢)的规则列表、一个全局 domainStrategy,以及可被规则引用的命名负载均衡器 balancers。

顶层选项 ​

字段类型默认值允许值描述
rules[]json.RawMessage[]<rule object array>路由规则,按声明顺序逐条求值,命中第一条即停。
domainStrategy*stringAsIsAsIs | IpIfNonMatch | IpOnDemand目的域名在规则匹配中如何处理。AsIs 把域名当作字符串(只有 domain 规则匹配);IpIfNonMatch 在没有 domain 规则命中时再解析为 IP;IpOnDemand 只要存在 IP 规则就提前把每个域名解析为 IP。
balancers[]*BalancingRule[][BalancingRule]命名的负载均衡器,可在规则目标中通过 balancerTag 引用。

源码: infra/conf/router.go:71-75 · 锚定版本 v26.9.9 (52a412d)

rules[] —— 规则对象 ​

每条规则都是一个 JSON 对象:匹配键 选出一组连接,目标键 决定它们的去向。结构是多态的;解析器会根据出现的匹配键自行判断。

匹配键(全部可选,AND 组合):

字段类型描述
typestring必须为 "field" —— Xray 唯一支持的规则类型。
domain / domains[]string按目的域名匹配。支持前缀:full:example.com、domain:example.com、regexp:.+\\.com$、keyword:google、geosite:cn。
ip[]string按目的 IP 匹配。支持裸 IP、CIDR、geoip:cn。
source[]string按来源 IP 匹配(语法同 ip)。
sourceIP[]string与 source 相同(语法同 ip);两者同时设置时使用 sourceIP。
portstring按目的端口匹配。80、80-90、80,443,8080-8090。
sourcePortstring按来源端口匹配(语法同上)。
localIP[]string按连接到达的本地地址(入站自身的 IP)匹配。语法同 ip。
localPortstring按连接到达的本地端口(入站端口)匹配。语法同 port。
networkstring按传输协议匹配。tcp、udp、tcp,udp。
user[]string按入站用户的 email 标签匹配。
vlessRoutestring仅 VLESS 入站:按客户端所发 UUID 的第 7–8 字节匹配 —— 即 UUID 第三组按十六进制读取的数值(如 …-01bb-… = 443)。使用端口列表语法("443"、"1-100,443")。可让同一服务端按嵌在客户端 UUID 中的值分流。
inboundTag[]string按入站 tag 匹配。
protocol[]string按嗅探出的应用协议匹配。http、tls、bittorrent、quic。要求入站启用了嗅探。
attrsmap[string]string按嗅探出的属性(如 Host)匹配。
process[]string按发起连接的本地进程匹配:进程名(curl;末尾的 .exe 会被忽略)、绝对路径(/usr/bin/curl)、以 / 结尾的目录(前缀匹配)、self/(Xray 自身进程)或 xray/(Xray 可执行文件路径)。只匹配来自本机的 TCP / UDP 连接;支持 Linux、Android、Windows 与 macOS。
localOS[]string按 Xray 自身运行的操作系统匹配(Go 的 runtime.GOOS:linux、windows、darwin、android、ios、freebsd 等;不区分大小写)。在构建规则时一次性求值 —— 适合多台设备共用同一份配置。
domainMatcherstring域名匹配器实现。hybrid(默认,更快)或 linear。

目标键(二选一):

字段描述
outboundTag把匹配到的流量送到该出站。
balancerTag把匹配到的流量送到负载均衡器(再由其在池内挑选出站)。

以及元数据字段:

字段描述
ruleTag规则的可读名称。会出现在 API 与日志中。
webhook{ url, deduplication, headers }。规则命中时,向 url POST 一个 JSON 事件(入站 / 出站 tag、来源、目的地、用户 email、协议、时间戳等;超时 5 秒;也接受 Unix 套接字形式的 URL)。deduplication 在该秒数内抑制同一用户 email 的重复事件(0 = 关闭);headers 会附加到请求上。不影响路由。

balancers[] ​

字段类型默认值允许值描述
tagstring(required)<string>负载均衡器名。被路由规则的 balancerTag 字段引用。
selectorStringList(required)[<outbound-tag prefix>]出站 tag 前缀列表。tag 以其中任一前缀开头的出站会进入该均衡器的池中。
strategyStrategyConfig{type: "random"}{type: "random|leastLoad|leastPing|roundRobin", settings?: {...}}选择策略。random 在池中任选;roundRobin 轮询;leastPing 选延迟最低的(需要启用 observatory);leastLoad 选负载最低的。
fallbackTagstring(unset)<outbound tag>当均衡池为空或所有成员失败时使用的出站。

源码: infra/conf/router.go:21-26 · 锚定版本 v26.9.9 (52a412d)

策略变体 ​

  • random —— 均匀随机挑选。
  • roundRobin —— 按池中顺序轮换。
  • leastPing —— 选延迟最低的成员。需要启用 observatory 或 burstObservatory,以便每个出站都有已知延迟。
  • leastLoad —— 选负载最低的成员。配套有 strategyLeastLoadConfig(见 infra/conf/router_strategy.go),含健康检查调优字段。

示例 ​

国内直连(典型「在中国大陆」模式):

json
{
  "routing": {
    "domainStrategy": "IpIfNonMatch",
    "rules": [
      { "type": "field", "ip": ["geoip:private"], "outboundTag": "direct" },
      { "type": "field", "domain": ["geosite:cn"], "outboundTag": "direct" },
      { "type": "field", "ip": ["geoip:cn"], "outboundTag": "direct" },
      { "type": "field", "outboundTag": "proxy" }
    ]
  }
}

带延迟感知的负载均衡路由:

json
{
  "routing": {
    "rules": [
      { "type": "field", "outboundTag": "direct", "domain": ["geosite:cn"] },
      { "type": "field", "balancerTag": "proxy-balance" }
    ],
    "balancers": [
      {
        "tag": "proxy-balance",
        "selector": ["proxy-"],
        "strategy": { "type": "leastPing" },
        "fallbackTag": "direct"
      }
    ]
  },
  "observatory": {
    "subjectSelector": ["proxy-"],
    "probeURL": "http://cp.cloudflare.com/generate_204",
    "probeInterval": "30s"
  }
}

按应用协议匹配(要求入站开启嗅探):

json
{
  "inbounds": [{
    "port": 1080,
    "protocol": "socks",
    "sniffing": { "enabled": true, "destOverride": ["http", "tls"] }
  }],
  "routing": {
    "rules": [
      { "type": "field", "protocol": ["bittorrent"], "outboundTag": "block" }
    ]
  }
}

说明 ​

  • 规则 按声明顺序 求值,命中第一条即停;后续规则只能看到未命中的流量。
  • 只存在 IP 规则时,domainStrategy 决定行为:
    • AsIs —— 域名目的地跳过 IP 规则。最廉价。
    • IpIfNonMatch —— 没有 domain 规则命中时再把域名解析为 IP,折中选项。
    • IpOnDemand —— 只要存在 IP 规则,就提前把每个域名解析为 IP。最精确,开销也最大。
  • 域名前缀(full:、domain:、regexp:、keyword:、geosite:)在匹配器内部解析。不加前缀时默认按 domain:(后缀匹配)。
  • geoip: 与 geosite: 规则从外部数据文件读取(geoip.dat / geosite.dat),通常放在 Xray 二进制旁边。类目名(cn、private、apple、google 等)由这些文件定义。
  • 这些数据文件可以 自动更新:顶层 geodata 块会按 cron 计划、经选定的出站下载新的 geoip.dat / geosite.dat。参见 Geodata。
  • 入站 嗅探 为 protocol 与 attrs 匹配键提供输入。入站 sniffing 块接受 destOverride,外加排除列表 domainsExcluded 与 ipsExcluded,对匹配的域名 / IP 跳过目的地覆盖(连同 metadataOnly 与 routeOnly)。
  • 策略为 leastPing 的均衡器只在配置了对应的 observatory 或 burst-observatory 时才工作。
  • ruleTag 启用通过 gRPC RoutingService 的运行时规则操作(见 API)。

跨内核说明 ​

  • sing-box 使用 snake_case 的结构化规则,按条件分字段(domain_suffix、ip_cidr、process_name 等)。规则可携带 action(route、direct、reject、hijack-dns、sniff、resolve、route-options)而不仅是出站 tag。参见 Routing — sing-box。
  • mihomo 使用紧凑字符串形式的规则(DOMAIN-SUFFIX,example.com,proxy),按顺序求值;另有独立的 rule-providers: 机制承接远端规则列表。参见 Routing — mihomo。

源码: infra/conf/router.go:21-75 · v26.9.9 (52a412d)

由 Argsment 出品的 Core Tutorial