本文面向已经能通过节点联网、准备修改分流规则的 v2rayN 用户。以 Xray 内核的路由字段为基准,区分域名与 IP 的填写位置,给出直连、代理、阻断的排序示例,并说明如何用配置、日志和单次请求确认规则是否生效。
1. 先确认路由入口与实际内核
v2rayN 是配置与管理客户端,实际匹配连接的是运行中的内核。本文的 routing.rules、domainStrategy 和 outboundTag 都按 Xray 配置语义解释。使用不同配置格式时,不能仅凭菜单名称相近就直接粘贴同一份 JSON。
桌面端先打开「设置」→「路由设置」,选中准备修改的路由配置,再进入规则列表编辑。不同版本可能将编辑入口放在双击行或右键菜单中;应确认当前页面具有域名、IP、端口和出站等字段。保存后,还要在主界面的「路由」选择入口启用这份配置,不能只新增而不切换。
- 记录现状:记下当前路由名称、活动节点和内核类型,保留一份能正常工作的原配置。
- 复制配置:在副本中调整规则,避免直接覆盖日常使用的配置。
- 确认出站:核对直连、代理和阻断对应的实际标签;下文以
direct、proxy、block为例。 - 应用更改:保存并启用路由,观察核心日志是否出现启动失败或配置解析错误。
2. 匹配顺序:先命中的整条规则决定出站
对普通字段路由规则,内核按照列表从上到下检查,遇到首条满足条件的规则就采用其出站。不存在“精确域名天然压过域名集合”这样的自动优先级:即使下面写了 full:,上面的宽泛规则已经命中,下面也不会获得重新选择的机会。
同一个字段内的多个值通常是“或”,不同条件字段之间是“且”。例如域名列表有两个条目,匹配任意一个即可;若同一条规则还填写了端口 443,则必须同时满足域名和目标端口条件。把 domain 与 ip 填在同一条里,也不是“域名或 IP 任一符合”。
这些是协议端口与地址范围,不是测速结果。路由里的 port 指目标端口,不是本地代理监听端口。浏览器连到本地代理后访问 HTTPS 站点,规则通常需要判断远端的 443,而不是浏览器连接本地代理时使用的端口。
结论:例外规则放到宽泛集合之前
需要某个域名单独走代理,就把它的精确代理规则移到可能覆盖它的直连集合之前,再测试新连接;只改前缀而不改位置,无法解决被上层规则截获的问题。
3. domain、full、regexp、geosite 分别怎么写
这些前缀属于域名字段。填写时不带 https://、路径、查询参数和端口。浏览器地址 https://api.example.com/account 对应的域名是 api.example.com;路由域名规则不是按网页路径分流。
| 写法 | 匹配含义 | 使用边界 |
|---|---|---|
domain:example.com | 匹配 example.com 及其子域名 | 适合整站;不会匹配 notexample.com |
full:api.example.com | 仅匹配这个完整域名 | 不会覆盖其他子域名 |
regexp:^api[0-9]+\.example\.com$ | 用正则匹配 api1、api20 等域名 | 注意起止锚点、转义与内核正则语法 |
geosite:cn | 引用域名数据文件中的 cn 集合 | 集合内容取决于实际加载的数据文件 |
example.com | 未加前缀时按普通字符串包含匹配 | 范围比域名后缀匹配更宽,不宜当成精确匹配 |
domain: 适合一个服务及其子域名统一出站;full: 适合给单个接口设置例外。裸字符串可能把 example.com.other.test 这样的域名也纳入匹配,因此常规配置优先选择有明确边界的前缀。
{
"type": "field",
"domain": [
"full:api.example.com",
"domain:example.net",
"regexp:^api[0-9]+\\.example\\.org$"
],
"outboundTag": "proxy"
}
这里三个域名条件是“或”。代码采用 JSON,所以正则中的一个反斜杠必须写成两个;如果在 v2rayN 的域名文本框中直接输入规则,通常写 regexp:^api[0-9]+\.example\.org$,不需要额外做 JSON 字符串转义。正则语法以内核支持范围为准,不能直接照搬浏览器里的全部表达式特性。
- geosite 是域名集合:
geosite:cn不是“服务器位于中国”的实时判断,也不等于所有以.cn结尾的域名。 - 集合名称依赖数据文件:网上示例里的分类不一定存在于本地数据中。出现找不到列表的错误,应核对数据来源与实际分类名称。
- 数据更新会影响范围:不改规则文本,更新域名数据后也可能改变命中结果。排查异常时同时记录数据更新时间。
4. ip 字段、CIDR 与 geoip 的区别
ip 是规则字段名,不是需要写在地址前面的前缀。图形界面的 IP 栏可填写单个地址、CIDR 网段或 geoip: 集合。例如写 192.168.0.0/16,而不是 ip:192.168.0.0/16。IPv6 地址也应填在 IP 字段中。
{
"type": "field",
"ip": [
"10.0.0.0/8",
"172.16.0.0/12",
"192.168.0.0/16",
"fc00::/7"
],
"outboundTag": "direct"
}
这段规则覆盖常见私有地址范围,但不是所有本地、链路本地和保留地址的完整清单。若使用 geoip:private,应确认本地 IP 数据文件提供该集合,并了解其覆盖范围。访问局域网服务时,还要确认请求确实进入代理内核;被系统代理绕过的连接不会留下该路由的命中记录。
| IP 条目 | 含义 | 排查重点 |
|---|---|---|
192.168.1.10 | 单个 IPv4 地址 | 设备地址变化后规则需要调整 |
192.168.0.0/16 | 匹配该 IPv4 网段 | 网段越宽,影响的目标越多 |
geoip:cn | 按数据文件中的 IP 集合匹配 | 不是域名归属或服务运营方判断 |
geoip:private | 引用 private 地址集合 | 确认实际数据文件包含该集合 |
同一个网站可能使用多个 CDN 地址,DNS 返回结果也可能随网络变化。用一次解析得到的单个 IP 给整站分流,通常不如域名规则稳定。只有应用直接访问 IP、固定内网设备或明确网段时,才优先考虑 IP 条目。
5. 域名解析策略决定 IP 规则何时参与
请求携带域名时,内核是否先解析出 IP,再用 IP 条目参与路由判断,由 routing.domainStrategy 等配置决定。这个设置与“最终连接由哪台 DNS 解析”“是否启用流量嗅探”是不同层面的问题,不能只打开一个开关就认为全部解决。
| 策略值 | 路由阶段的行为 | 使用时注意 |
|---|---|---|
AsIs | 不为路由匹配主动把域名解析成 IP | 原本以 IP 为目标的请求仍可匹配 IP 规则 |
IPIfNonMatch | 域名未匹配规则时,尝试解析后再次匹配 | 宽泛域名兜底会让请求提前结束匹配 |
IPOnDemand | 匹配过程中遇到需要 IP 判断的条件时进行解析 | 靠前的 IP 规则可能先于后面的域名规则命中 |
例如把“所有 TCP、UDP 都走代理”放在列表末尾,在 IPIfNonMatch 下,一个域名请求即使没有命中具体域名条目,也可能先命中这条网络兜底;因为已有规则命中,不能再期待后续自动解析并交给 geoip:cn。这也是“配置了国内 IP 直连却看起来没作用”的常见原因。
- 以域名规则为主:先列明确的域名例外与集合,避免不必要的解析参与判断。
- 依赖 IP 分类:检查当前解析策略、DNS 是否可用,以及前面是否已有规则匹配。
- 应用只交出 IP:域名规则可能缺少匹配依据;嗅探能否补充域名取决于协议和配置,不能保证覆盖所有连接。
6. 直连、代理、阻断规则的排列示例
常见排列是“明确例外在前,宽泛集合在后,最终兜底最后”。但阻断与例外谁优先,必须由实际意图决定:如果某个域名必须阻断,就把阻断规则放在可能放行它的规则上方;如果需要放行阻断集合中的一个站点,就把精确放行规则放到该集合之前。
{
"routing": {
"domainStrategy": "AsIs",
"rules": [
{
"type": "field",
"domain": ["full:blocked.example.org"],
"outboundTag": "block"
},
{
"type": "field",
"domain": ["full:api.example.com"],
"outboundTag": "proxy"
},
{
"type": "field",
"ip": ["10.0.0.0/8", "192.168.0.0/16"],
"outboundTag": "direct"
},
{
"type": "field",
"domain": ["geosite:cn"],
"outboundTag": "direct"
},
{
"type": "field",
"network": "tcp,udp",
"outboundTag": "proxy"
}
]
}
}
示例中的域名用于说明语法,不是可用节点或真实测试服务。配置必须已经定义相应的出站标签:direct 对应直连出站,block 对应阻断出站,proxy 对应实际代理出站。标签只是引用名称,写一个 proxy 字符串不会自动创建节点。
- 明确阻断:先处理必须拒绝的精确目标。
- 域名例外:给特定接口或站点指定出站,防止被后面的集合覆盖。
- 私有 IP:处理以 IP 访问的内网目标;本例使用 AsIs,不会为域名主动解析匹配这一行。
- 集合直连:按实际 geosite 数据匹配其余域名。
- 最终代理:让尚未匹配的 TCP、UDP 流量走代理。
如果没有任何规则命中,Xray 通常使用配置中的第一个出站。不要把这个隐含行为当作“默认一定代理”:客户端生成配置的出站顺序可能不同。显式兜底更便于阅读,但也要同时考虑上一节所述的解析策略影响。
7. 规则不生效时的验证步骤与问答
先区分三种情况:请求没有进入内核、进入后命中了错误规则、命中正确出站但连接失败。第一种检查系统代理与应用设置;第二种检查规则顺序和匹配字段;第三种检查节点、DNS 与目标连通性。路由正确并不等于代理节点一定可用。
- 只改一条:选一个实际使用的域名,增加一条
full:规则,放到可能覆盖它的规则前面。 - 建立新连接:保存并启用路由后,关闭原有页面或应用连接,再重新发起请求。既有长连接不会因为编辑规则而自动重新选路。
- 查看日志:在 v2rayN 的日志区域核对目标、错误和出站标签。需要时临时提高日志级别;普通访问日志不一定标明命中的规则行号。
- 核对生成配置:确认当前内核实际加载的配置里包含新条目,标签拼写与 outbounds 一致。不要直接长期修改会被客户端重新生成的临时配置。
- 恢复设置:确认原因后撤销临时测试规则并恢复日志级别,避免记录不必要的访问细节。
写了 domain:example.com,为什么接口还是走直连?
先查看它上面是否已有直连规则命中,再确认接口真实域名是否属于 example.com。把该接口的 full: 代理规则临时移到相关直连规则之前,保存并重新建立连接;同时检查当前启用的路由是否就是刚编辑的配置。
geosite:cn 保存后内核启动失败,哪里写错了?
查看核心日志中的具体错误。若提示数据文件或列表不存在,检查实际使用的 geosite 数据文件和集合名称;若是 JSON 解析错误,则检查逗号、引号与正则转义。先撤回新增条目恢复连接,再单独修正。
域名和 IP 都填了,为什么命中反而变少?
同一条规则中的不同条件字段需要同时满足。如果原意是“域名符合,或者 IP 属于某网段”,应拆成两条规则并指定相同出站;不要把两种条件放进同一行后当作备选项。
改成代理后网页仍打不开,是路由没生效吗?
先看访问日志是否已经选择代理出站。如果已选中,继续检查当前节点连接错误、域名解析和目标服务状态;如果日志没有这次请求,检查应用是否遵循系统代理。不要仅凭网页能否打开推断规则命中结果。
保存排查记录时,只需保留规则顺序、目标类型、出站标签与错误信息。分享截图或配置前,隐藏订阅地址、节点凭据和不必要的访问域名。能复现一次明确的命中结果,比同时添加大量规则更容易定位问题。