本文适合已经导入订阅、希望读懂核心配置的用户。先用一份只含本地 SOCKS 入口、直连与阻断出站的 JSON 建立结构,再逐段核对日志、DNS、端口、标签和规则顺序;读完可以定位“核心启动失败”“本地端口连不上”“规则没有命中”分别应该检查哪里。
先区分客户端设置与核心配置
v2rayN 是桌面客户端,负责管理订阅、服务器条目、路由预设及核心进程;V2Ray 或 Xray 才是读取核心配置并处理连接的程序。客户端保存的界面偏好、订阅分组数据,不等于交给核心的运行时 JSON。排查时应找本次启动实际加载的文件,而不是看到扩展名为 .json 就直接修改。
Android 上的 v2rayNG 使用 Xray 内核,v2flyNG 使用 V2Fly 内核。本文解释的是 V2Ray 常见配置结构,不能由此推断两个内核的全部字段通用。例如 REALITY 属于 Xray 的相关能力,不能把对应配置直接交给 V2Fly。即使同叫 streamSettings,具体传输名称与可用选项也应按当前内核确认。
这条流程是阅读主线,DNS 会在需要域名解析的环节参与,日志则记录整个过程。系统代理只影响遵循该设置的应用;配置中存在 SOCKS 入站,不代表所有应用的流量已经进入核心。入口未接通时,继续修改路由通常不会改变结果。
- 确认核心:从启动日志确认正在运行 V2Ray 还是 Xray,不只看客户端名称。
- 确认文件:查看启动日志或进程启动参数里的配置文件路径;路径和文件名可能随客户端版本变化。
- 保留原件:先复制运行配置供阅读;订阅更新、切换节点或重启核心都可能重新生成文件。
完整 JSON 示例:一个入口、两个出站、两条规则
下面是结构教学配置,不含远端代理服务器。它在 127.0.0.1:10808 提供 SOCKS 服务,阻断对 example.org 的精确域名请求及 TCP 25 端口请求,其余连接默认直连。不要把它当作现有订阅配置的替代品,否则原有代理出站会丢失。
{
"log": {
"loglevel": "warning"
},
"dns": {
"servers": [
"1.1.1.1"
]
},
"inbounds": [
{
"tag": "socks-local",
"listen": "127.0.0.1",
"port": 10808,
"protocol": "socks",
"settings": {
"auth": "noauth",
"udp": true
}
}
],
"outbounds": [
{
"tag": "direct",
"protocol": "freedom",
"settings": {
"domainStrategy": "UseIP"
}
},
{
"tag": "block",
"protocol": "blackhole",
"settings": {}
}
],
"routing": {
"domainStrategy": "AsIs",
"rules": [
{
"type": "field",
"inboundTag": [
"socks-local"
],
"domain": [
"full:example.org"
],
"outboundTag": "block"
},
{
"type": "field",
"network": "tcp",
"port": "25",
"outboundTag": "block"
}
]
}
}
顶层对象的键排列顺序通常不决定处理顺序,本文只是按阅读需要排列;但数组中的顺序可能直接影响行为,尤其是 outbounds 的首项与 routing.rules 的先后。不要为了“整理格式”随意给这两个数组排序。
log:先用日志区分启动错误与连接错误
log 控制日志输出,不负责选择节点。示例只设置 loglevel,没有指定日志文件;实际输出位置取决于核心启动方式,客户端可能把输出收集到自己的日志面板。排障时先看启动后的第一条错误,再看触发访问时新增的记录。
| 字段或现象 | 具体含义 | 下一步 |
|---|---|---|
loglevel: warning | 保留警告和错误,适合正常使用时减少输出。 | 需要更多连接信息时临时改为 info。 |
loglevel: debug | 输出更多调试细节,日志增长更快。 | 复现一次问题后恢复原级别,分享前删除敏感信息。 |
address already in use | 监听地址与端口被其他进程占用。 | 检查 10808 是否已由另一核心实例监听。 |
| 字段解析或配置加载错误 | 核心尚未进入正常处理连接的阶段。 | 检查字段拼写、数据类型及当前核心是否支持该选项。 |
如果核心启动即退出,先修复配置或端口冲突,不要先换 DNS。如果核心正常运行,只有某个请求失败,再检查对应目标、路由结果与连接错误。日志中可能包含访问域名、服务器地址及本地路径,不应把完整运行配置和日志直接发布到公开页面。
dns:解析服务器与路由策略不是同一个开关
dns.servers 指定核心内置 DNS 使用的解析服务器。示例中的 1.1.1.1 是普通 DNS 服务器地址,通常通过 UDP 53 查询;这里没有配置加密 DNS,也不意味着查询自动经过代理。解析服务器是否可达,需要在实际网络中验证。
最容易混淆的是两个同名字段:routing.domainStrategy 决定路由匹配阶段如何对待域名,freedom 出站里的 settings.domainStrategy 则决定直连建立连接时如何解析目标。它们处在不同对象内,枚举值和作用也不同。
路由匹配阶段
- 位置
routing.domainStrategy- 示例值
AsIs- 作用
- 不为路由匹配主动解析目标域名。
- 其他常见值
IPIfNonMatch、IPOnDemand
AsIs 不表示整个连接过程都不会发生 DNS 查询。
直连出站阶段
- 位置
freedom.settings.domainStrategy- 示例值
UseIP- 作用
- 通过内置 DNS 将目标域名解析为 IP 后连接。
- 解析来源
- 本例的
dns.servers
不要把路由的 IPIfNonMatch 填进这个位置。
IPIfNonMatch 会在域名未匹配到规则时尝试解析,再检查 IP 规则;IPOnDemand 会在匹配过程需要 IP 时触发解析。两者都不是“强制全部流量走代理”的设置。若配置没有 IP 规则,先保持策略简单,避免为解释一个域名规则而引入额外解析行为。
- 浏览器自己完成的域名解析,不会因为核心出现
dns对象就自动全部交给核心。 - 应用若只向 SOCKS 入口提交 IP,核心可能拿不到原始域名;域名规则因而可能无法命中。
- 内置 DNS 的配置不等同于修改操作系统 DNS,二者应分别检查。
inbounds:确认应用连接到了哪个入口
inbounds 是数组,每一项描述一个接收连接的入口。本例的 listen 限定为本机回环地址,port 是数字 10808,protocol 是 socks。三个字段共同决定应用该连接到哪里、用什么协议连接。
- 核对监听地址:
127.0.0.1只供本机访问。将其改成0.0.0.0会扩大监听范围,不应为了排障直接暴露无认证入口。 - 核对协议:SOCKS 端口不等于 HTTP 代理端口。把只支持 HTTP 代理的程序指向本例 10808,不能据此判断节点是否可用。
- 核对实际端口:10808 是本文指定值,不是所有客户端的固定值。v2rayN 可在「设置」→「参数设置」中核对本地监听相关选项,最终以运行配置和日志为准。
- 核对 UDP:
udp: true允许此 SOCKS 入站处理 UDP,但应用仍需使用 SOCKS UDP 机制,后续出站和网络也必须支持对应流量。
tag: socks-local 是入口的内部名称,不是域名,也不是节点订阅名。它不改变监听协议,而是让其他配置可以引用这个入口。本例第一条规则的 inboundTag 写成数组,是因为一条规则可以接受多个入口标签。
"inboundTag": [
"socks-local"
]
更改入口标签后,引用它的规则也要同步更改。只把入站的 socks-local 改成 local-socks,却保留原规则,会导致该规则无法匹配这个入口的流量。
outbounds:标签、协议与默认出站
outbounds 定义连接下一步如何发出。本例的 freedom 表示直连,blackhole 表示阻断;它们不是远端代理协议。真实订阅生成的配置可能额外出现 VMess 或 VLESS 出站,并携带服务器地址、端口、用户标识及传输参数。
| 项目 | 本文示例 | 阅读要点 |
|---|---|---|
tag | direct、block | 由规则引用的名称,大小写与拼写必须一致。 |
protocol: freedom | 直连出站 | 从运行核心的设备直接连接目标。 |
protocol: blackhole | 阻断出站 | 用于拒绝指定流量,不会自动改走其他出站。 |
| VMess、VLESS | 本例未配置 | 需有效服务器与认证参数,不能仅更改协议名称。 |
streamSettings | 本例不需要 | 描述传输与安全层,需和服务端对应设置一致。 |
在本例这种未设置其他默认分派机制的配置中,未命中路由规则的连接使用 outbounds 的第一项,因此默认直连。把 block 移到第一项会改变兜底行为;把标签改名则不会自动改变数组顺序。
结论:先确认默认出站,再分析例外规则
打开运行配置后先记录 outbounds 第一项的 tag,再逐条检查 routing.rules 的 outboundTag;这比只搜索“proxy”更可靠,因为标签名称由配置生成方定义。
如果真实配置使用 proxy 作为代理出站标签,那么路由中的 outboundTag: proxy 必须能找到对应出站。给本例新增一条指向 proxy 的规则,并不会凭空创建代理连接;应先保留并核对客户端生成的有效代理出站。
routing:规则从上到下,条件分清“且”与“或”
routing.rules 通常按从上到下的顺序检查,命中一条规则后使用它指定的出站,不再继续寻找后面的普通规则。因此,具体规则应放在覆盖面更广的规则前面。配置中写了某条规则,不等于它一定有机会被执行。
同一条规则里的不同条件字段通常是“且”的关系,而同一字段数组内的多个候选值通常是“或”的关系。本例第一条同时要求入口为 socks-local,目标域名为 example.org,二者都满足才交给 block。
full:example.org:精确匹配这个域名,不包含www.example.org。domain:example.org:匹配该域名及其子域名,适合明确需要覆盖整组域名的场景。network: tcp与port: "25":本例第二条同时匹配 TCP 网络和目标 25 端口;这里不是本地监听端口。outboundTag: block:结果指向阻断出站,不是继续尝试下一条规则。
| 送入本地 SOCKS 的请求 | 匹配过程 | 结果 |
|---|---|---|
| 域名 example.org,TCP 443 | 第一条的入口与精确域名均满足。 | block |
| 域名 www.example.org,TCP 443 | 不满足精确域名,也不是目标 25 端口。 | 默认 direct |
| 其他域名,TCP 25 | 第一条不匹配,第二条匹配。 | block |
| 其他域名,TCP 443 | 两条规则都不匹配。 | 默认 direct |
上述推演以应用确实向 SOCKS 入站提交域名为前提。如果应用提前解析并只提交 IP,第一条域名规则可能无法使用。嗅探可以在部分协议中识别域名信息,但它不是必定恢复原始域名的工具;本例没有启用嗅探,应先用明确的域名请求测试规则。
配置检查步骤与常见问答
读配置时一次只改一个变量,并记录修改前后的日志。先验证核心能启动,再验证入口可达,最后确认规则与出站;把端口、DNS、标签和传输参数同时更改,会让一次成功或失败都难以解释。
- 检查语法与类型:端口
10808是数字,udp是布尔值true,inbounds与outbounds是数组。 - 核对所有引用:逐个查找
inboundTag、outboundTag,确认在对应入口或出站中存在同名tag。 - 确认应用使用入口:测试本例时显式指定 SOCKS 地址,避免浏览器系统代理设置干扰判断。
- 推演路由:从第一条规则开始,对照目标域名、目标端口、网络类型与入口标签检查。
- 恢复客户端管理:确认原理后,把长期修改落实到客户端支持的路由或配置选项,再重新生成运行配置验证。
如果设备安装了支持 SOCKS 的 curl,可以在核心加载本例且端口未被占用的前提下运行以下命令。socks5h 要求把目标域名交给 SOCKS 服务处理;本例会因精确域名规则阻断该请求,失败是这项测试的预期结果,而不是远端代理故障。
curl --proxy socks5h://127.0.0.1:10808 --connect-timeout 10 https://example.org/
改了 JSON,重启 v2rayN 后怎么又变回去了?
运行文件可能由客户端重新生成。先保留修改记录,再到「设置」→「路由设置」检查对应规则,或使用当前版本明确支持的自定义配置入口;不要把临时运行文件当成永久设置源。
outboundTag 写了 proxy,为什么还是启动报错?
在 outbounds 数组里查找 tag 为 proxy 的项,确认没有拼写或大小写差异。如果不存在,应恢复有效的代理出站配置,而不是只给 freedom 改一个名称。
DNS 改成 1.1.1.1,为什么域名规则仍然没命中?
先检查应用是否提交了域名,再确认规则顺序与 full、domain 前缀。更换解析服务器不会自动补回应用已经丢失的域名信息,也不会改变规则优先级。
VLESS 出站能直接替换 VMess 的 protocol 字段吗?
不能。两类协议的认证字段和协议参数不同,传输与安全层也必须符合服务端配置。应重新导入正确的订阅或连接资料,再核对实际运行核心支持的字段。
阅读更多配置概念可查阅路由分流技术参考;需要从客户端界面核对解析设置时,按教程中的 DNS 设置步骤操作。核心结构读懂后,再逐项对照客户端界面,能减少把订阅、入口和路由当成同一个设置的误判。