路由是 Xray 配置中决定“哪一类连接走哪里”的核心部分。节点能够连接,只说明入站、出站和传输参数基本可用,并不代表国内网站一定直连、广告一定被拦截,或者 DNS 请求已经按照预期分流。真正的分流结果,取决于 routing 中的匹配顺序、域名与 IP 规则、domainStrategy 的解析策略,以及每条规则最终指向的 outboundTag。
本文以 Xray JSON 配置为主线,逐层解释 routing、rules、域名和地址匹配、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数据匹配。port、network和protocol可进一步限制端口、TCP/UDP 或已识别的应用协议。inboundTag、user和source可按入口、用户或来源地址区分连接。outboundTag指定固定出站,balancerTag则把连接交给负载均衡器选择。
rules 字段与匹配优先级
最小可用的路由结构一般如下。这里的 direct、proxy 和 block 只是标签名称,可以按自己的出站定义修改。没有匹配到任何规则时,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,表示按照字段组合进行匹配。同一条规则中的多个字段通常表示“同时满足”;同一个字段数组中的多个项目则表示满足其中任意一个。例如一条规则同时写入 inboundTag 与 domain,就只会处理来自指定入站且目标域名符合条件的连接。
域名前缀的含义不能混用。full:example.com 只匹配完整的 example.com;domain: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、再载入内核。
准备出站标签
先确认配置中存在
proxy、direct和block三个标签,分别对应代理节点、自由直连和黑洞出站。设定解析策略
在
routing中加入"domainStrategy": "IPIfNonMatch",让域名规则优先,未命中时再考虑 IP 规则。添加局域网规则
把
geoip:private和内部域名放在前面,避免打印机、路由器管理页和局域网服务被送入代理。加入拦截规则
将确认无误的广告或追踪规则集指向
block,先少量启用,防止误拦截登录、支付或验证码域名。最后设置兜底
把需要代理的广泛规则放在末尾,重载配置后查看日志和实际访问结果,再逐步增加自定义域名。
对应的出站可以采用下面这种基础结构。代理出站中的服务器地址、端口和用户信息必须替换为服务端真实参数;示例只展示路由所依赖的标签关系。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 可以先依据域名匹配 domain 或 geosite。如果目标已经是 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.dat、geoip.dat,以及 Xray 支持的本地或远程规则集格式。不同 Xray-core 版本对规则集字段、文件格式和下载方式可能存在差异,迁移配置时应以当前内核文档和启动日志为准,不要把其他代理内核的规则集语法直接复制过来。
使用内置分类时,常见写法是 geosite:cn、geosite:category-ads-all 和 geoip:private。这类引用依赖对应的数据文件存在且版本匹配。若日志提示找不到 geosite 或 geoip 数据,不应先怀疑 routing 语法,应该检查 Xray-core 的运行目录、数据文件路径、客户端内核安装状态以及文件版本。
自定义规则建议按用途拆分。例如把公司域名放在“工作直连”集合,把需要固定代理的域名放在“指定代理”集合,把拦截目标放在“广告拦截”集合。每个集合只负责一类判断,主配置中的规则则负责表达优先级。这样修改一个域名时,不会同时改变 DNS、端口和默认代理逻辑,也便于在 v2rayN 或其他客户端中切换不同配置副本。
- 域名规则尽量使用明确的完整域名或后缀,不要用过宽的正则替代所有分类。
- 自定义规则加入后,至少测试首页、登录页、静态资源和接口请求。
- 规则集更新失败时保留上一份可用数据,不要让启动过程依赖临时下载。
- 修改规则集后记录日期、内核版本和变更原因,便于回滚到 2026 年当前使用的稳定版本。
- 把订阅自动生成部分与手写覆盖部分分开,避免下一次更新订阅时丢失自定义内容。
为什么写了域名规则却没有命中?
先确认应用提交的是域名而不是已经解析出的 IP,再检查 domainStrategy、规则顺序和域名前缀。若依赖流量探测,还要确认入站启用了 sniffing 并且目标协议能够被识别。
把国内规则放前面就一定直连吗?
不一定。还要确认直连出站标签确实存在、DNS 结果没有异常、目标没有被更早的特殊代理规则命中,并检查实际连接是否使用 IPv6 或独立解析地址。
广告拦截后某个网站无法登录怎么办?
先暂时移除对应分类规则,确认登录恢复,再从日志中找到被拦截的完整域名,增加一条更具体的直连或代理例外,并将例外放在拦截规则之前。
规则集加载失败会影响所有节点吗?
取决于配置是否要求启动时必须加载该规则集。建议先用内置 geosite、geoip 分类验证路由,再检查文件路径、数据格式与 Xray-core 版本,避免在未知状态下继续叠加规则。
日志验证、回滚与长期维护
路由调试不能只看浏览器最终能否打开网页。应先启用适度的 Xray 日志,观察连接目标、命中的出站和错误原因。测试时固定一个节点、一个应用和一个目标域名,先验证直连目标,再验证代理目标,最后验证拦截目标。一次修改多个规则会让结果难以归因,尤其是同时改变 DNS、嗅探和 domainStrategy 时。
可以把配置拆成几个可读区段:入站、出站、DNS、路由和日志。JSON 本身不支持注释,因此可在配置管理目录中使用外部变更记录,写明“新增规则、预期出站、测试结果和回滚文件名”。保存前使用客户端提供的配置检查功能,或用可靠的 JSON 校验工具检查括号、逗号、引号和数组层级。格式合法只代表 JSON 能解析,不代表标签、字段和规则语义正确。
推荐保留三个版本:最近一次可用配置、当前测试配置和最小应急配置。最小应急配置只保留一个代理出站、一个直连出站和一条代理兜底规则,出现全局无法联网时可以快速替换。升级 Xray-core、v2rayN 或 v2rayNG 后,先用最小配置确认内核能启动,再恢复规则集和复杂分流,能明显减少版本变化带来的排查范围。
可执行判断:先让最小规则跑通
复杂路由不是越多越可靠。先用“局域网直连、一个明确代理目标、一个代理兜底”验证链路,再逐步加入国内分类、DNS 分流和拦截规则;每增加一组规则都保留测试结果,出现异常时才能快速回到上一份稳定配置。