2026-11-02 · 配置详解 · 约 12 分钟

V2Ray 配置文件 JSON 结构解析:inbounds、outbounds 与 routing 逐段读懂

按 log、inbounds、outbounds、routing、dns 的顺序拆解一份完整配置,解释各字段含义与它们之间的引用关系,帮助读懂客户端导出的配置文件。

本文速览

读配置先找入口、出口和连接它们的标签,再看路由与 DNS。本文以一份不含远端服务器凭据的 V2Ray 传统 JSON 配置为样本,逐段解释字段、匹配顺序和检查方法。适合已经导入订阅、希望理解 v2rayN 导出文件的用户;示例只演示本地 SOCKS 接入、直连和阻断,不提供远端代理能力。

一、先分清客户端配置与内核运行配置

v2rayN 是管理界面,V2Ray 与 Xray 是实际处理连接的内核。订阅保存的是服务器信息或配置来源,界面还会保存分组、当前选择、路由预设等状态;内核启动时读取的 JSON 则描述监听端口、出站协议和路由规则。这几类文件不能仅凭扩展名相同就互相替换。

本文使用 V2Ray 的传统 JSON 配置结构,不覆盖所有内核的专有字段。v2rayNG 使用 Xray 内核,v2flyNG 使用 v2fly 内核;即使都能看到 inbounds 和 outbounds,也不代表每个协议选项都兼容。尤其是 REALITY、流控与传输相关字段,应按实际运行内核的文档判断。

应用连接 入站接收 路由匹配 出站处理 目标服务

阅读文件时沿这条链找引用关系即可。log 负责观察过程,dns 提供解析能力,它们不是必须按书写位置依次执行的网络节点。JSON 对象中五个模块的先后排列不决定处理顺序,但数组中的路由规则顺序会影响结果。

二、完整示例:本地 SOCKS 入站与两种出站

下面是一份用于理解结构的完整配置。它仅监听本机回环地址,接收 SOCKS 请求;目的端口为 25 的 TCP 连接被阻断,其余未被规则选中的连接默认直连。它不会让应用自动使用代理,也不会建立通往远端代理服务器的连接。

{
  "log": {
    "loglevel": "warning"
  },
  "inbounds": [
    {
      "tag": "local-socks",
      "listen": "127.0.0.1",
      "port": 10808,
      "protocol": "socks",
      "settings": {
        "auth": "noauth",
        "udp": false
      }
    }
  ],
  "outbounds": [
    {
      "tag": "direct",
      "protocol": "freedom",
      "settings": {}
    },
    {
      "tag": "block",
      "protocol": "blackhole",
      "settings": {}
    }
  ],
  "routing": {
    "domainStrategy": "AsIs",
    "rules": [
      {
        "type": "field",
        "inboundTag": ["local-socks"],
        "network": "tcp",
        "port": "25",
        "outboundTag": "block"
      },
      {
        "type": "field",
        "ip": [
          "127.0.0.0/8",
          "10.0.0.0/8",
          "172.16.0.0/12",
          "192.168.0.0/16"
        ],
        "outboundTag": "direct"
      },
      {
        "type": "field",
        "domain": ["full:localhost"],
        "outboundTag": "direct"
      }
    ]
  },
  "dns": {
    "servers": ["localhost"],
    "queryStrategy": "UseIP"
  }
}
10808
示例 SOCKS 监听端口
2
出站:direct 与 block
25
示例阻断的 TCP 目的端口

这些数字都是示例配置的确定值,不是客户端所有版本的默认值。若本机已有程序占用 10808,应换一个空闲端口,并同步修改应用里的 SOCKS 地址。示例中的私网直连规则用于展示写法,并不构成完整的本地网络地址清单。

三、log 与 inbounds:先确认请求能否进入内核

log.loglevel 决定日志详细程度。示例使用 warning,适合关注告警和错误;排障时可临时改为 info,必要时再用 debug。没有写 access 或 error 文件路径,不等于日志一定消失,输出仍可能被启动它的客户端接收并展示。

inbounds 是入口数组。示例只接收发往 127.0.0.1:10808 的 SOCKS 连接,所以应用必须显式使用这个地址。把浏览器设置为 HTTP 代理却指向仅提供 SOCKS 的端口,会出现协议不匹配;单纯启动内核也不会改变系统代理。

日志观察项

loglevel
warning
临时排障
info 或 debug
输出位置
由路径配置与启动方式决定

定位问题后降低详细程度,避免长期记录过多连接信息。

本地入口项

listen
127.0.0.1
port
10808
protocol
socks
tag
local-socks

tag 是路由引用名,不是监听地址,也不是远端节点名称。

auth: "noauth" 表示此 SOCKS 入站不要求认证,因此示例将监听范围限制在本机。不要为了让其他设备连接,直接把监听地址改成所有接口而忽略访问控制。udp: false 表示该入站没有启用 SOCKS UDP 转发,不能用它验证 UDP 应用是否正常。

端口占用属于入口启动问题,连接超时属于后续链路问题。先确认日志中没有监听失败,再判断路由、DNS 或远端服务器,能减少无效修改。

四、outbounds:协议负责连接,tag 负责被引用

outbounds 数组定义连接怎样离开内核。示例中的 freedom 直接连接目标,blackhole 丢弃匹配流量。direct 与 block 只是人为指定的标签;把标签改成其他名字不会改变协议行为,但所有引用它的规则都必须一起修改。

字段示例值读取重点
outbounds[0].tagdirect路由引用名;此处也是默认出站
outbounds[0].protocolfreedom直接访问目标,不经过远端代理
outbounds[1].protocolblackhole阻断被路由选中的连接
settings空对象本例使用默认行为;代理协议通常需要更多参数

在这里使用的传统配置模型中,没有匹配任何规则的连接会交给第一个出站。因此调整数组顺序可能改变默认行为。若把 block 放到第一项,原来默认直连的请求就可能被阻断;不要把排序当成单纯的界面整理。

实际 VMess 或 VLESS 出站还会包含服务器地址、端口、认证信息,以及可能存在的 streamSettings。其中 protocol 指定代理协议,传输与安全层参数另有位置。不能只把 freedom 改成 vless 就期待建立连接,也不能将不同协议的 settings 原样互换。

判断默认行为:先看第一项,再查标签引用

修改配置前记录第一个出站的 tag,并搜索全部 outboundTag。只有同时确认默认路径和显式路径,才能判断一条连接最终会直连、代理还是被阻断。

五、routing:按顺序匹配,不按规则长度猜优先级

routing.rules 从上到下检查,命中后采用对应的出站。它不会自动认为更长的域名或更窄的 IP 网段优先。同一条规则内不同条件通常需要同时满足;同一个条件数组里的多个值则通常是任选其一。配置前应先把“同时满足”与“任一满足”分清。

  1. 第一条规则:入口标签必须是 local-socks,网络必须是 TCP,目的端口必须是 25。三个条件同时满足才交给 block。
  2. 第二条规则:目标 IP 落入列出的任一网段时交给 direct。即使目标是私网地址,若先命中上一条 TCP 25 规则,也仍然会被阻断。
  3. 第三条规则:full:localhost 表示精确匹配该域名,不是匹配所有包含 localhost 字样的名称。
  4. 全部未命中:使用第一个出站,即本例的 direct。第二、三条在本例中结果与默认出站相同,保留它们是为了展示规则写法。

inboundTag 要引用入站的 tag;outboundTag 要引用出站的 tag。大小写和拼写都应一致。它们不是内核自动识别的中文分组名称,也不会自动跟随客户端里节点显示名的变化。

domainStrategy: "AsIs" 表示路由阶段不为了 IP 规则主动把域名解析成地址。如果应用提交的是域名,第二条 IP 规则未必能据此匹配;如果提交的本来就是 IP,则可以直接检查网段。改为 IPIfNonMatch 会在域名阶段未匹配时尝试解析后再匹配,不能把它理解成所有 DNS 请求都改走远端。

六、dns:区分解析策略与流量出口

示例的 dns.servers 仅有 "localhost",表示使用本机系统解析能力,不是在监听本机的 DNS 端口。queryStrategy: "UseIP" 允许查询 IPv4 与 IPv6 地址,实际返回结果仍受域名记录、解析器和网络条件影响。

写了 dns 模块不代表所有应用的 DNS 都进入了内核。应用可能已经自行解析,再把 IP 交给 SOCKS;也可能把域名交给内核处理。前者可能失去直接按域名分流所需的信息,后者才保留了目标域名。入口如何接收请求与 DNS 模块如何解析,是两个不同问题。

配置位置控制内容不应混淆为
dns.servers内置 DNS 模块可用的解析来源操作系统所有程序的 DNS 设置
dns.queryStrategy查询地址族的策略选择直连或代理的路由规则
routing.domainStrategy路由匹配时是否借助解析结果强制全部解析请求走同一出口
出站中的解析策略该出站如何处理目标域名所有内核共享的统一字段

需要按域名选择解析器时,可以进一步研究 DNS 服务器对象中的 domains 等字段,但还要核对查询流量怎样到达解析器。只换一个 DNS 地址,并不能证明解析请求经过了预期的代理路径。排障时应同时观察请求带入的是域名还是 IP,以及最终选中的出站。

七、导出文件怎么检查:从语法到实际连接

先复制一份配置再编辑,避免直接覆盖客户端自动生成的运行文件。v2rayN 可能在切换节点、更新订阅或重启内核时重新生成配置;如果修改只存在于临时运行文件中,下次启动就可能消失。长期变更应保存到客户端对应的路由、DNS 设置或自定义配置入口,具体入口以当前版本界面为准。

  1. 检查 JSON 语法:确认双引号、括号和逗号配对。若本机装有 Python,可用下面的命令检查基本语法;通过不代表内核支持所有字段。
  2. 确认实际内核:在客户端的内核选择与启动日志中核对名称、版本和所读取的配置文件路径,不要只看客户端名称。
  3. 检查引用关系:逐个搜索 inboundTag 与 outboundTag,确保都能找到对应定义,并核对第一个出站。
  4. 检查监听与请求:确认 127.0.0.1:10808 能启动,应用也使用 SOCKS 协议和同一端口。
  5. 单项验证:一次只修改一个模块;先验证普通 TCP 请求,再测试域名规则和阻断规则,避免把多个变量混在一起。
python -m json.tool config.json

若语法通过但内核拒绝启动,继续看日志里的字段路径和错误类型。未知字段、协议选项不兼容、端口占用属于不同问题,不能用更换 DNS 统一解决。分享日志或配置前,应删去服务器认证信息、订阅链接与不必要的个人路径。

JSON 检查通过,为什么还是启动失败?

语法检查只确认文件能被解析。打开客户端启动日志,定位第一个错误,核对协议名称、字段类型和实际内核;若提示地址占用,先停用占用 10808 的程序或同步更换监听端口。

改了 outboundTag,为什么原来的节点不走了?

先检查新标签是否与某个出站的 tag 完全一致,再检查规则顺序。不要只改路由引用而漏改出站定义;也要确认请求是否提前命中了更靠上的规则。

复制这份配置,为什么没有连到订阅里的服务器?

本文只有 freedom 和 blackhole 两种出站。需要使用远端代理时,应由客户端根据有效订阅生成相应出站,再检查路由如何引用它;不要在这份样本中猜填认证参数。

重启 v2rayN 后,手改内容为什么不见了?

通常是运行配置被客户端重新生成。保留修改前后的副本,把需要长期保留的路由或 DNS 调整写入客户端持久化设置,再重启并核对新生成文件,而不是反复修改临时文件。

V2Ray客户端下载