本文适合已经导入节点、需要调整直连与代理分流的用户。先区分域名匹配与 IP 匹配,再用配置片段说明规则顺序、解析策略和默认出站。特别注意:关键词匹配通常直接写字符串,不能把说明中的 keyword 当作通用 JSON 前缀。文中使用示例域名,不包含可连接的代理节点。
一、路由先决定出站,不负责创建节点
V2Ray 路由读取连接的目标地址、端口、网络类型等信息,再把连接交给某个出站。它不负责把订阅转换成节点,也不会因为写了 outboundTag: "proxy" 就自动生成代理服务器。标签只是引用,必须能在当前配置的 outbounds 中找到对应的 tag。
域名规则能否生效,还取决于内核是否拿到了域名。应用通过 SOCKS 传递域名时,内核可以直接匹配;应用先自行解析再提交 IP 时,域名信息可能已经丢失。流量嗅探可以从部分协议中识别主机名,但不是所有加密流量都能恢复域名,也不能把它当作 DNS 的替代品。
routing.rules:按数组顺序评估的规则列表。type: "field":本文使用的字段匹配规则类型。outboundTag:匹配后选择的出站标签,区分大小写。domainStrategy:路由阶段何时为域名补充 IP 信息,不等于 DNS 服务器地址。
二、domain 的四种写法:精确、子域名、关键词与正则
domain 是一个字符串数组。同一数组中的多个条目是“或”关系,任意条目命中即可。下面以 example.com 为例区分边界;不要把完整网址、路径或查询参数放进域名条目,路由匹配的不是浏览器地址栏中的整条 URL。
| 写法 | 匹配范围 | 边界说明 |
|---|---|---|
full:example.com | 仅 example.com | 不含 www.example.com |
domain:example.com | 根域及其子域 | 不匹配 notexample.com |
example | 域名中包含 example 的字符串 | 可能同时命中 notexample.net |
regexp:^api[0-9]+\.example\.com$ | api 后接数字的指定子域 | 需在 JSON 中转义反斜杠 |
{
"type": "field",
"domain": [
"full:login.example.com",
"domain:static.example.com",
"regexp:^api[0-9]+\\.example\\.com$"
],
"outboundTag": "proxy"
}
上面的正则是 JSON 字符串,所以正则里的一个反斜杠要写成两个。^ 和 $ 限定首尾,避免只匹配域名的一小段。只需要整站分流时,优先使用 domain:,比宽泛的关键词和复杂正则更容易检查。
三、geosite 与 geoip:分类数据不是自动推断
geosite 引用域名分类,放在 domain 数组里;geoip 引用 IP 分类,放在 ip 数组里。两者依赖内核可读取的数据文件和其中实际存在的分类。写下分类名并不会触发在线搜索,也不会自动下载缺失的数据。
域名分类规则
- 规则字段
domain- 示例条目
geosite:cn- 常见数据文件
geosite.dat- 匹配依据
- 数据集中列出的域名规则
分类内容由数据文件决定,不等同于服务器所在地。
IP 分类规则
- 规则字段
ip- 示例条目
geoip:private- 常见数据文件
geoip.dat- 匹配依据
- 数据集收录的地址网段
示例分类必须在当前数据文件中存在,加载报错时先检查文件与分类名。
域名属于某个分类,不代表它所有 CDN 地址都属于相同的 IP 地区。反过来,某个 IP 被收录到地区分类,也不能说明使用该地址的所有域名都应该直连。需要明确控制的业务域名,应写成独立规则,放在宽泛分类之前。
- 内核启动时报“文件不存在”:检查实际运行目录、资源路径和客户端的数据文件设置。
- 提示分类不存在:核对当前文件收录的标签,不要根据其他数据包的文档猜分类名。
- 更新后结果改变:先比较分类内容,再判断是否为规则顺序变化。
四、ip、CIDR 与端口:同字段取或,不同字段取且
ip 可以填写单个地址、CIDR 网段或受支持的数据集引用。CIDR 的斜杠后数字是前缀长度,不是端口。下面三个数字是语法边界,用于核对输入,不是网络测速结果。
{
"type": "field",
"ip": [
"192.168.0.0/16",
"10.0.0.0/8",
"fc00::/7"
],
"port": "443",
"network": "tcp",
"outboundTag": "direct"
}
这条规则只让“目标 IP 属于三个网段之一,并且目标端口是 443,并且网络类型为 TCP”的连接直连。它不是把所有内网流量都直连;访问内网设备的 80 端口或 UDP 服务仍要继续匹配后续规则。
同一规则里再加入 domain,并不会变成“域名或 IP 任一符合即可”,而是新增必须同时满足的条件。尤其在目标最初只有域名、解析尚未触发时,这种组合容易与预期不一致。需要“指定域名直连,或者指定 IP 直连”,应拆成两条规则。
结论:先拆规则,再合并条件
把域名例外与网段例外分别写成单条规则,确认各自命中后,再考虑是否确实需要端口或网络类型的交集限制。
五、规则从上到下匹配,不按“越具体越优先”排序
在一次规则扫描中,先匹配的规则决定出站,后面的规则不再替它改判。内核不会自动把 full: 提到 geosite: 之前,也不会给更长的域名更高权重。具体例外、业务规则、宽泛分类、最终兜底,应由配置者明确排列。
{
"routing": {
"domainStrategy": "IPIfNonMatch",
"rules": [
{
"type": "field",
"domain": ["full:login.example.com"],
"outboundTag": "proxy"
},
{
"type": "field",
"domain": ["domain:example.com"],
"outboundTag": "direct"
},
{
"type": "field",
"ip": ["geoip:private"],
"outboundTag": "direct"
},
{
"type": "field",
"network": "tcp,udp",
"outboundTag": "proxy"
}
]
}
}
这是用于合并的 routing 片段,不是完整客户端配置。它要求已有 proxy 与 direct 出站,其中 direct 通常使用 freedom 协议。第一条让登录域名走代理,第二条让其余根域和子域直连。若交换两条规则,登录域名会先被第二条覆盖。
- 要求域名优先、未命中后再尝试 IP 规则:使用
IPIfNonMatch,并避免提前匹配所有流量的兜底规则。 - 需要扫描到 IP 规则时主动尝试解析:研究
IPOnDemand,同时评估新增 DNS 请求和等待时间。 - 不写全匹配兜底时:核对
outbounds的第一项。未匹配任何规则的流量默认使用第一个出站,标签名本身没有默认魔法。
六、domainStrategy 与 DNS:先确认目标是什么
同一组规则可能在浏览器里正常,在另一个程序里却表现不同。关键不一定是规则被忽略,而是两个程序提交的目标不同:一个提交域名,另一个提交已经解析的 IP。路由解析策略只控制路由判断所需的解析行为,不保证应用、系统与内核采用相同 DNS。
| 策略 | 触发方式 | 检查重点 |
|---|---|---|
AsIs | 路由不为域名主动补充 IP | 原始目标为域名时,不能依赖 IP 分类分流 |
IPIfNonMatch | 域名在第一轮未匹配规则后尝试解析,再匹配 | 过早的全匹配规则会阻止第二轮 |
IPOnDemand | 域名请求匹配到需要 IP 判断的规则时尝试解析 | IP 规则的位置和 DNS 可达性都会影响结果 |
更改路由后,已有的长连接通常不会重新选择出站。应关闭测试程序的旧连接,再发起新请求;必要时重启内核。若同时修改 DNS、嗅探与路由顺序,就很难确定是哪一项改变了结果。每轮只改一个变量,并保留可恢复的配置副本。
七、在客户端落地与排查规则未生效
v2rayN 是桌面客户端,v2rayNG 使用 Xray 内核,v2flyNG 使用 v2fly 内核。本文片段使用两类内核常见的原生路由字段,但不能据此推断所有扩展语法、数据文件和界面导入格式完全相同。客户端保存的规则条目与最终生成的内核 JSON 也可能不是同一种文件格式。
- 备份当前方案。在 v2rayN 的「设置」→「路由设置」中检查当前启用的路由方案;不同界面版本的入口文字可能略有变化。先复制方案,再添加一条明确的
full:例外。 - 核对生成结果。检查实际运行配置中的
routing.rules顺序、outbounds标签,以及是否被全局代理或全局直连模式替换。 - 区分规则表单与完整配置。v2rayNG 的「设置」→「路由设置」可检查常用域名和 IP 分流项;这些表单不等同于原生 JSON 编辑器。复杂有序规则应采用当前版本明确支持的自定义配置方式。
- 重新建立连接。应用设置并重启服务,再查看运行日志;只刷新页面可能继续使用旧连接。日志级别若不足以显示路由细节,可临时提高,测试完恢复。
域名已经填了,为什么还是走代理?
先确认这条规则在代理兜底之前,再把它临时改成单一 full: 测试。检查内核收到的是域名还是 IP;只有 IP 时,单纯增加域名条目无法解决信息缺失。
加了 geosite 后服务启动失败怎么办?
先恢复上一份配置,在日志中定位具体分类名和文件路径。确认数据文件可读取、分类存在,再添加该条规则;不要连续更换多个分类名碰运气。
规则显示保存成功,怎么一点变化都没有?
检查当前启用的路由方案是否就是编辑的那份,并确认不是全局模式覆盖。重新启动内核后建立新连接,再核对实际配置中的出站标签,而不只看表单提示。
能不能把所有条件塞进一条规则?
只有需要条件同时成立时才这样写。域名、IP、端口和网络类型一起填写是交集;想表达多个独立例外,就拆成多条,并按明确例外优先的顺序排列。
最后用三个新连接验证方案:一个精确例外域名、一个普通子域名、一个已知内网 IP。分别记录目标形式、命中规则和出站标签。这样能把“语法能加载”“规则确实命中”“出站本身可连接”分开检查,避免把节点故障误判为路由失效。更多概念可查阅术语表,配置边界可对照进阶配置。