适合已经导入订阅、需要给特定网站或网段单独分流的用户。先区分域名条件与 IP 条件,再看规则顺序和 DNS 解析时机。读完可以写出一组小范围例外规则,并用日志判断它为什么命中、为什么没有命中。
路由匹配优先级:先命中的规则生效
V2Ray 与 Xray 的常规路由规则按 routing.rules 数组从上到下检查。一旦某条规则匹配,就使用它指定的出站,不会继续寻找“更精确”的下一条。因此,精确域名写在大范围分类之后,并不会自动覆盖分类;需要主动把例外放到前面。
同一条规则里,domain 数组的多个条目通常是“或”的关系,任意一个匹配即可。不同条件字段通常是“且”的关系:同时写 domain 和 port,表示域名与目标端口都要符合。把域名和 IP 填进同一条规则,不等于“域名或 IP 任一匹配就生效”。
下面是一条“仅让指定主机的 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"
}
- 单个设备:
10.0.0.8/32只匹配这个 IPv4 地址;单个 IPv6 地址可使用/128。 - 整个网段:
192.168.10.0/24覆盖这一段 IPv4 地址,适合明确的局域网目标。 - 地址分类:
geoip:cn依赖地址数据库,不能保证与某个网站的业务归属一致。 - 域名分类:
geosite:cn依赖域名数据库;未收录的新域名不会因为站点使用中文就自动匹配。
网站可能同时使用多个内容分发网络,同一域名在不同网络环境下也可能解析到不同地区的 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 的请求,不能把它理解成对所有剩余域名执行地址分类。
- 希望保留这个显式兜底:接受域名请求主要按域名规则分流,IP 请求主要按 IP 规则分流。
- 希望域名未匹配时再做 IP 分类:可去掉提前接住所有连接的规则,并核对默认出站;常规默认行为使用第一个出站。
- 希望遇到 IP 条件就解析:可以评估
IPOnDemand,但必须重测前置 IP 规则与精确域名例外之间的关系。
默认出站应在完整配置中明确核对,不能仅凭客户端界面上“当前选中的节点”推断。v2rayN 会生成运行配置,手动改动临时生成文件可能在切换节点或重启后被覆盖。长期规则应保存在客户端的路由配置中。
v2rayN 自定义路由:按单条规则验证
v2rayN 是桌面客户端,具体流量由所选内核运行。以下操作以包含「设置」→「路由设置」入口的桌面界面为准;不同版本的按钮位置与字段翻译可能调整。编辑前先记录当前路由配置名称,并保留原规则,避免把订阅节点问题和路由问题混在一起排查。
-
打开路由设置
进入「设置」→「路由设置」,记录正在使用的路由配置。先导出或复制现有规则,再添加例外。
-
填写域名条件
在规则编辑窗口的域名条件中填入
full:portal.example.com。图形界面字段通常只接收条目,不要把整个 routing JSON 粘贴进去。 -
选择目标出站
按实际需求选择代理或直连。若编辑的是内核 JSON,则检查
outboundTag与outbounds中的标签逐字一致。 -
上移并启用
将例外移动到域名分类和宽泛兜底之前,保存后在主界面的路由选择处启用这份配置;不要只保存却仍使用原方案。
-
重建测试连接
关闭原测试页面和旧连接,再发起新请求。查看内核日志中的目标主机、目标端口和出站标签,每次只修改一项条件。
验证时可先把真实测试主机写成 full: 例外,确认命中后再扩大为 domain: 或分类。浏览器连接复用会让旧连接继续使用原出口,仅刷新页面不一定建立新连接。使用命令行工具测试时,也要显式使用客户端界面显示的本地代理端口,不要假定每台机器都使用同一端口。
路由规则不生效:按现象定位原因
域名写对了,为什么还是走直连?
先把精确规则移到分类规则之前,再确认当前启用的是修改后的路由配置。若日志目标只有 IP,继续检查应用是否提前解析,以及内核能否取得域名信息。
为什么 geosite 保存后内核启动失败?
查看日志是否提示域名数据文件不存在或分类无法加载。确认 geosite.dat 的资源路径与分类名称,先用一条 full 域名规则验证基础配置,再恢复分类条目。
网页主站走代理,图片却没有走?
在浏览器网络面板查看图片请求的实际主机名。图片可能来自另一个根域,主站的 domain 条目不会覆盖它;核对用途后,为资源域名单独添加规则。
端口 443 已经匹配,为什么下载仍失败?
端口条件只决定分流,不保证目标可达。检查日志中的出站标签是否正确,再分别排查节点连通性、DNS 结果与 UDP 支持;443 端口既可能承载 TCP,也可能承载 UDP 流量。
重启客户端以后,自定义规则怎么没了?
确认改动是否只写入了临时生成的内核配置。回到「设置」→「路由设置」保存规则并启用对应方案;使用独立自定义配置时,则维护实际被加载的源文件。
最后用三个问题收尾:连接是否进入内核、内核看见的是域名还是 IP、第一条命中规则指向哪个出站。先回答这三个问题,通常比同时更换 DNS、切换内核和重建订阅更容易定位原因。更多字段解释可查阅协议与内核参考,不熟悉的术语可对照术语手册。