本文适合已经能连接节点、准备调整直连与代理范围的用户。先认识域名与 IP 的匹配写法,再按“局部例外、分类规则、最终兜底”安排顺序,最后检查域名解析策略和实际出站。示例使用 V2Fly V2Ray 与 Xray 常见的 field 路由结构;客户端编辑界面不是完整内核配置,保存后还要核对生成结果。
路由规则基础:匹配条件与出站标签
路由分流决定一条连接交给哪个出站处理,不负责创建节点,也不改变节点使用的 VMess 或 VLESS 协议。V2Ray 是内核项目,Xray 是另一内核项目;v2rayN 是桌面图形客户端,负责把界面配置转换成所选内核能够读取的设置。
一条常见规则包含 type: "field"、匹配条件和 outboundTag。标签必须对应 outbounds 中已有的 tag。本文把代理、直连、阻断出站分别叫作 proxy、direct、block,这些只是示例名称,不能假定每份客户端配置都使用相同标签。
- 同一字段内通常是“或”:
domain数组中任意一个域名条件成立,就满足该字段。 - 不同字段之间是“且”:同一条规则同时填写
domain与port,需要域名和目标端口都满足。 - domain 与 ip 不等于二选一:把它们写进同一条规则,会要求两者共同满足;想表达“域名或 IP”,应拆成两条规则。
- 端口是目标端口:
port: "443"匹配远端服务端口,不是本机代理监听端口。
这些数值是示例参数,不是测速结果或客户端默认值承诺。实际监听端口应从本机设置读取;HTTPS 也可以运行在其他端口,不能只凭 443 判断所有加密流量。
domain 四种匹配方式:包含、正则、根域与完整域名
domain 字段的名称容易和 domain: 前缀混淆:前者是规则字段,后者是字段内某个字符串的匹配模式。四种常用写法中,普通字符串不带前缀,另外三种使用 regexp:、domain:、full:。不要为了对称而给普通字符串自行添加前缀。
| 写法 | 匹配范围 | 使用注意 |
|---|---|---|
example.com | 域名中包含这段字符串 | 可能命中 notexample.com,范围比根域匹配宽 |
domain:example.com | example.com 及其子域 | 匹配 www.example.com,不匹配 notexample.com |
full:api.example.com | 仅完整域名 api.example.com | 不包括 cdn.api.example.com |
regexp:^api[0-9]+\.example\.com$ | 符合正则的完整字符串 | JSON 内的反斜杠需要再次转义 |
日常按站点分流,优先用 domain:;只给一个接口设置例外时,用 full:。域名条件只接收域名,不要填写 https://、网页路径或查询参数,路由规则也不会按某个网页的文章路径进行分流。
{
"type": "field",
"domain": [
"full:api.example.com",
"domain:example.org",
"regexp:^api[0-9]+\\.example\\.com$"
],
"outboundTag": "proxy"
}
这里的正则会匹配 api12.example.com。开头的 ^ 和结尾的 $ 限定字符串边界,点号前的反斜杠让它表示真正的点。示例域名用于展示语法,实际配置应换成需要分流的业务域名。
ip、geoip 与 geosite:地址范围和数据文件
ip 字段可以填写单个地址、CIDR 网段或 geoip: 引用。192.168.1.10/32 只覆盖一个 IPv4 地址,192.168.1.0/24 覆盖该网段;IPv6 单地址可使用 /128。这里匹配的是目标地址,若要匹配请求来源,需要使用其他对应字段。
{
"type": "field",
"ip": [
"192.168.1.0/24",
"geoip:private"
],
"outboundTag": "direct"
}
geoip:private 用于引用数据文件中的私有地址分类,geoip:cn 则引用其中的中国 IP 分类。它们不是实时定位服务,实际范围取决于所加载的 geoip.dat。网络归属和数据更新时间可能影响判断,不能把分类命中直接理解为服务器的物理位置。
- geosite 放进 domain:例如
"domain": ["geosite:cn"],它读取域名分类,不是 IP 分类。 - geoip 放进 ip:例如
"ip": ["geoip:cn"],它读取地址范围,不能用来匹配网页域名文本。 - 分类必须存在:
geosite:category-ads-all是一些常用数据集提供的广告分类,但不是所有数据文件都包含它。 - 属性筛选依赖数据:
geosite:geolocation-!cn与带@的分类写法,需要核对当前文件是否提供相应分类或属性,不能仅凭名称猜测含义。
规则生效优先级:先匹配、先结束
规则按 rules 数组从上到下检查,命中第一条符合条件的规则后,连接就交给相应出站。不存在“完整域名天然优先于 geosite”或“IP 规则天然压过域名规则”的排序机制;精确条件也会被前面的宽泛规则遮住。
- 局部例外在前:指定某个完整域名必须代理,先放
full:规则。 - 业务分类随后:再放需要代理或阻断的域名分类,以及一般直连分类。
- IP 规则按目的排序:局域网地址通常单独直连,但它与域名规则的相对位置要结合解析策略决定。
- 兜底放最后:没有匹配规则时,通常使用
outbounds数组的第一个出站;如需明确结果,可在最后加入覆盖目标端口范围的规则。
下面是一段 routing 配置示例,不是可直接运行的完整文件。它要求已有 proxy、direct、block 三个出站,并要求数据文件包含所引用的分类。实际标签与客户端生成的名称不一致时,应先修改标签。
{
"routing": {
"domainStrategy": "IPOnDemand",
"rules": [
{
"type": "field",
"domain": ["full:api.example.com"],
"outboundTag": "proxy"
},
{
"type": "field",
"ip": ["geoip:private"],
"outboundTag": "direct"
},
{
"type": "field",
"domain": ["geosite:category-ads-all"],
"outboundTag": "block"
},
{
"type": "field",
"domain": ["geosite:cn"],
"outboundTag": "direct"
},
{
"type": "field",
"ip": ["geoip:cn"],
"outboundTag": "direct"
},
{
"type": "field",
"port": "1-65535",
"outboundTag": "proxy"
}
]
}
}
这份示例先处理完整域名例外,再处理私有地址。由于使用 IPOnDemand,检查前面的 IP 规则时可能发生解析。把广告分类放在私有地址规则之后,表示私有地址匹配具有更高优先级;若业务要求阻断分类优先,需要调整顺序,而不是期待内核自动判断规则的重要性。
domainStrategy:什么时候解析域名参与匹配
路由中的 domainStrategy 控制域名是否解析成 IP 来辅助路由判断,不等于 DNS 服务器设置,也不等于直连出站内的同名选项。连接最初提供的是域名还是 IP,同样会影响可以使用哪些条件。
AsIs
推荐路由阶段不主动把域名解析为 IP。域名目标主要依靠 domain、geosite 等规则;目标本来就是 IP 时,仍可匹配 IP 规则。适合先建立行为清晰的域名分流基线。
适合:以域名规则为主、首次排查匹配顺序
IPIfNonMatch
域名在首轮没有匹配规则时,尝试解析后再进行匹配。如果前面已有一条可命中的端口兜底规则,就可能直接结束首轮,不再进入解析后匹配。
适合:域名规则未命中后,再用 IP 分类判断
IPOnDemand
检查规则时遇到需要 IP 判断的条件,会按需解析域名。较靠前的 IP 规则可能影响后续域名分类能否被检查,因此要把 DNS 行为和规则顺序一起设计。
适合:明确需要 IP 分类参与域名目标分流
结论:先决定解析时机,再写兜底
若选择 IPIfNonMatch,不要同时放一条首轮必中的通用端口兜底并期待后续 geoip 生效;可以让第一个出站承担默认路径,或重新安排策略。需要在最终兜底之前进行 IP 判断时,再评估 IPOnDemand 和实际 DNS 配置。
如果应用直接连接 IP,内核最初没有可供 domain 匹配的域名。嗅探在支持的流量上可以提取域名,但并非所有协议都能提取,也不是完整的域名还原机制。DNS 查询自身从哪里发出,还要查看内核 DNS、出站和客户端模式,不能仅通过更改路由策略推断。
v2rayN 设置步骤:编辑后核对实际配置
v2rayN 的路由编辑界面会随版本调整。桌面版通常从「设置」→「路由设置」进入;若当前界面不同,应先记录「帮助」→「关于」中的版本信息,再以对应界面为准。不要把本文的内核 JSON 整段粘进仅接受域名列表的输入框。
-
记录基线
在「帮助」→「关于」记录客户端版本,在「设置」→「参数设置」核对正在使用的内核与本地监听端口。备份现有路由内容,确认当前模式确实使用自定义路由,而非直接切换为全局代理。
-
加入例外
进入「设置」→「路由设置」,编辑当前使用的路由规则集。先添加一个真实业务域名的
full:条件,选择目标出站,并把它放在宽泛分类规则之前。 -
检查策略
在路由配置中核对
domainStrategy,同时确认域名数组、IP 数组和出站标签。使用分类规则时,检查当前内核能否加载对应的 geosite、geoip 数据文件。 -
重启验证
保存并启用修改后的规则集,重启当前内核连接。核对实际生成配置中的规则顺序,然后发起新的请求并查看日志;已经建立的连接通常不会因改规则而重新选择出站。
v2rayNG 在安卓上使用 Xray 内核,v2flyNG 使用 V2Fly 内核。即使基础规则格式相近,客户端可编辑的字段、导入入口和数据文件管理也可能不同。迁移时应检查字段支持,不要把桌面客户端的整份设置文件当作通用内核配置。
路由未生效排查:请求入口、数据与日志
“网站能打开”只能证明连接成功,不能证明用了正确出站。验证时选一个完整域名、一个局域网目标和一个分类内目标,分别发起新连接。先确认流量进入内核,再看规则命中与出站标签,最后检查 DNS 和分类范围。
| 现象 | 优先检查 | 具体处理 |
|---|---|---|
| 完整域名例外仍走直连 | 前面是否已有 geosite 或端口规则命中 | 把该条 full 规则移到相关宽泛规则之前,并建立新连接 |
| geoip 对域名目标不起作用 | AsIs 或 IPIfNonMatch 的解析条件 | 核对策略;检查是否被首轮兜底提前匹配 |
| 启动后立刻报错 | JSON、分类名称、数据文件、出站标签 | 先移除新增分类引用,用一条 full 规则缩小问题范围 |
| 浏览器与命令行结果不同 | 是否进入相同代理入口、是否本地解析 | 显式指定同一 SOCKS 入口,对比域名与 IP 请求 |
| 改规则后结果没有变化 | 活动规则集、内核重启与连接复用 | 确认启用的是修改后的规则集,关闭旧连接再测试 |
若本机提供 SOCKS 入站,并且监听端口确实为示例中的 10808,可以使用下面的命令。socks5h 让 curl 把域名交给代理端,而不是先在本地解析;这能减少测试入口差异,但不代表内核不会按其 DNS 设置继续解析。
curl --proxy socks5h://127.0.0.1:10808 --head https://example.com/
- 先核对入口:未进入内核的请求不会受它的路由规则影响。系统代理也不保证所有程序都遵循该设置。
- 再核对日志:短时启用适当的访问日志或更详细日志,关注目标地址、入站和出站标签;排查结束后恢复日常日志级别。
- 最后缩小规则:保留一个域名条件和一个明确出站,验证成功后逐项恢复分类与 IP 条件,避免同时改变多个变量。
分享日志前应遮盖订阅地址、节点凭据和业务域名等敏感信息。需要理解客户端、内核与出站的区别,可查看术语表;需要从连接入口重新确认配置,可从快速上手开始。