V2Ray config.json 结构详解:inbounds、outbounds 与 routing 逐段拆解

按 log、inbounds、outbounds、routing、dns 的顺序逐段讲解配置文件字段含义,并说明 outboundTag 怎样把规则与出口串起来。

本文速览

本文适合需要阅读客户端生成配置、定位端口与分流问题的用户。先用一份只含本地入站、直连和阻断出口的完整配置建立字段对应关系,再解释远端代理、规则顺序与 DNS 的边界。示例用于验证配置结构,不包含可连接的远端代理节点;读完可以判断请求从哪里进入、匹配哪条规则、最终使用哪个出口。

1. config.json 顶层结构与请求路径

config.json 是常见的配置文件名,不是固定名称。真正决定加载哪个文件的是内核启动参数。本文使用 V2Ray 的传统 JSON 配置结构;V2Ray 与 Xray 有共同的字段基础,但扩展功能和版本支持并不完全相同,不能把某个内核的新字段直接复制给另一内核。

应用请求 本地入站 规则匹配 出站处理 目标连接

inbounds 接收应用流量,outbounds 定义连接方式,routing 决定使用哪一个出口。log 负责记录运行信息,dns 配置内置解析器。JSON 对象中这些顶层键的书写先后通常不影响执行,但路由规则数组的先后顺序会影响结果。

顶层字段数据类型先确认的问题
log对象是否能看到启动错误与访问记录
inbounds数组应用连接的协议、地址和端口是否一致
outbounds数组出口协议及其参数是否完整
routing对象规则顺序与出口标签是否对应
dns对象哪些环节实际调用内置解析器

下面的配置可作为独立内核的结构测试文件。它监听本机两个端口,阻断 example.org 及其子域名,其他请求默认直连。它不会把流量发送到远端代理服务器,也不会自动开启系统代理。

{
  "log": {
    "loglevel": "warning"
  },
  "inbounds": [
    {
      "tag": "socks-in",
      "listen": "127.0.0.1",
      "port": 10808,
      "protocol": "socks",
      "settings": {
        "auth": "noauth",
        "udp": false
      }
    },
    {
      "tag": "http-in",
      "listen": "127.0.0.1",
      "port": 10809,
      "protocol": "http",
      "settings": {}
    }
  ],
  "outbounds": [
    {
      "tag": "direct",
      "protocol": "freedom",
      "settings": {}
    },
    {
      "tag": "block",
      "protocol": "blackhole",
      "settings": {}
    }
  ],
  "routing": {
    "domainStrategy": "AsIs",
    "rules": [
      {
        "type": "field",
        "domain": ["domain:example.org"],
        "outboundTag": "block"
      },
      {
        "type": "field",
        "ip": ["geoip:private"],
        "outboundTag": "direct"
      }
    ]
  },
  "dns": {
    "servers": ["1.1.1.1"]
  }
}

2. log:先让配置错误可定位

loglevel 常用值有 debug、info、warning、error 和 none。示例使用 warning,适合减少日常输出。排查启动或连接问题时,可临时改为 info;需要更细的内部记录时再用 debug。

{
  "log": {
    "access": "access.log",
    "error": "error.log",
    "loglevel": "info"
  }
}

这是顶层片段,应替换完整配置中的 log,不是另起一个重复键。相对日志路径按进程工作目录解释,不一定落在配置文件旁边。由客户端启动内核时,工作目录、文件写入权限和日志展示方式可能不同,优先查看客户端提供的运行日志。

3. inbounds:监听地址、端口与代理协议

inbounds 是数组,可以同时提供多个入口。每个入口的 protocol 决定如何理解应用发来的数据。SOCKS 与 HTTP 代理不是同一种协议;即使都监听在本机,应用选择错误类型也可能连接失败。

10808
本文 SOCKS 入站端口
10809
本文 HTTP 入站端口
2
本文配置的本地入站数

这些端口是本文明确指定的示例值,不代表所有版本客户端的默认值。应用配置 HTTP 代理时,应填写地址 127.0.0.1、端口 10809;应用配置 SOCKS5 代理时,则填写 127.0.0.1:10808。

SOCKS 本地入口

标签
socks-in
监听
127.0.0.1:10808
协议
socks
认证
noauth
UDP
false

本文仅演示本机 TCP 请求,不启用 SOCKS UDP 转发。

HTTP 本地入口

标签
http-in
监听
127.0.0.1:10809
协议
http
设置
{}

供支持 HTTP 代理的应用使用,HTTPS 请求通常通过 CONNECT 建立隧道。

listen 设置为回环地址意味着仅本机可连接。改成 0.0.0.0 会监听全部 IPv4 接口,可能让局域网其他设备访问入口。需要共享时,应同时设计认证、防火墙与访问范围,不能只改监听地址。

4. outbounds:出口协议与标签对应关系

outbounds 定义流量如何离开内核。示例里的 freedom 是直连出口,blackhole 是阻断出口。direct 和 block 只是人为指定的标签;标签本身不会赋予出口能力,真正行为由 protocol 和相关设置决定。

出口标签协议本文中的行为
directfreedom直接连接目标,且作为未匹配规则的默认出口
blockblackhole阻断匹配请求,不连接远端代理
proxy由实际节点确定本文未定义;只有加入完整代理出口后才能引用

在这类配置中,未命中路由规则的请求默认使用 outbounds 数组的第一个出口。本文把 direct 放在首位,因此默认直连。若把首位改为真实代理出口,未匹配流量的走向也会随之改变。

VMess 或 VLESS 出站需要真实服务器地址、端口、用户标识,以及与服务端一致的传输和安全参数。WebSocket 路径、TLS 服务名等参数不能只凭协议名称推断。涉及 Xray 扩展的配置还要确认内核支持范围,不能把所有 VLESS 配置都视为通用 V2Ray 配置。

结论:先核对标签,再调整节点参数

将每条规则的 outboundTag 与出口的 tag 逐字对照,并确认第一个出口符合默认流量策略;只有这两步正确后,才继续排查服务器和传输设置。

5. routing:规则顺序与 outboundTag

routing.rules 按数组顺序逐条检查,命中后使用该规则指定的出口。把范围过大的规则放在前面,可能让后面的精细规则没有机会执行。同一规则中不同条件字段通常需要同时满足,同一字段数组中的多个候选则通常按任一匹配处理。

{
  "type": "field",
  "inboundTag": ["http-in"],
  "domain": ["domain:example.org"],
  "outboundTag": "block"
}

上面的片段演示组合条件:请求必须来自 http-in,且目标域名匹配 example.org 或其子域名,才会走 block。如果只想限制一个精确域名,应使用 full:example.org,而不是域名后缀匹配。

  1. 先列出实际出口标签,例如本文的 direct、block。
  2. 把需要优先处理的精确规则放在前面,再放范围较广的规则。
  3. 逐条核对 outboundTag;拼写、大小写和连字符都必须与出口标签一致。
  4. 检查入口拿到的是域名还是 IP。目标信息不同,能命中的规则也可能不同。
  5. 明确未匹配流量走第一个出口,不要把“没有命中”理解成自动阻断。
domainStrategy路由处理方式使用时的注意点
AsIs使用现有目标信息,不为路由匹配主动解析域名目标原本是 IP 时仍可匹配 IP 规则
IPIfNonMatch域名未匹配规则时,尝试解析后再匹配 IP 规则可能增加解析步骤,结果受 DNS 返回地址影响
IPOnDemand遇到需要 IP 判断的规则时触发解析要结合规则顺序理解解析时机

本文使用 AsIs。因此,应用提交私网 IP 时可以命中 geoip:private;应用提交一个最终解析到私网地址的域名时,这条 IP 规则不一定命中。路由层不主动解析,不等于实际建立连接时完全不需要解析。

6. dns:内置解析器不等于系统 DNS

dns.servers 为内核的内置解析器指定服务器。本文的 1.1.1.1 是传统 DNS 地址示例,不表示启用了加密 DNS,也不保证当前网络可达。应按实际网络环境选择解析方式,并确认查询请求能够到达目标解析器。

例如,要让直连出口主动通过内置 DNS 获取 IPv4 地址,可以在确认内核支持的前提下,把该出口的设置改为下面的片段。这是出站设置,不是路由设置;两处都叫 domainStrategy,但作用范围不同。

{
  "tag": "direct",
  "protocol": "freedom",
  "settings": {
    "domainStrategy": "UseIPv4"
  }
}

7. 配置验证与客户端使用边界

先验证语法,再启动监听,最后验证请求路径。普通 JSON 不允许注释和尾随逗号;复制片段时应替换对应对象,不要留下两份同名顶层键。某些加载器容忍扩展语法,不代表其他内核或客户端也能处理。

  1. 保存一份原配置备份,确认正在操作的是实际加载文件。
  2. 使用当前内核的配置测试命令,先处理字段错误和资源文件错误。
  3. 停止占用 10808、10809 的进程,再启动测试内核。
  4. 明确指定代理端口发起请求,不依赖系统代理是否已开启。
  5. 检查阻断域名和正常目标的结果,再逐项加入真实代理出口与复杂规则。

V2Ray 5 系列常用以下命令测试传统 JSON 配置。不同发行包的可执行文件位置可能不同;先运行 v2ray help 确认子命令。旧版使用的 -test -config 参数形式不要与新子命令混用。

v2ray test -c config.json
v2ray run -c config.json

内核正常启动后,可以用支持代理的请求工具检查路径。下面两条命令都会请求本文设定的阻断域名,预期请求失败或连接被关闭;这用于确认规则生效,不是连通性成功测试。第二条命令中的 socks5h 会把域名交给代理端处理,有助于保留域名匹配条件。

curl --max-time 10 --proxy http://127.0.0.1:10809 http://example.org/
curl --max-time 10 --proxy socks5h://127.0.0.1:10808 http://example.org/

v2rayN 是桌面客户端,会根据节点、路由与设置生成内核运行配置;生成文件可能在切换节点或重启时被覆盖。v2rayNG 使用 Xray 内核,v2flyNG 使用 V2Fly 内核。阅读它们的运行配置有助于理解同类字段,但导入自定义 JSON 是否可用、如何与界面设置共存,应以具体客户端版本为准。

修改 config.json 后,为什么客户端流量没有变化?

先确认修改的是当前进程加载的文件,而不是历史导出文件。再检查客户端是否重新生成了配置、内核是否重启,以及应用是否经过对应入站。订阅中的节点参数、客户端路由预设和完整内核配置属于不同层,修改其中一层不一定改变其他层。

配置测试通过,是否说明代理节点一定能用?

配置测试主要验证能否加载,不会证明远端服务器在线,也不能保证用户标识、传输路径和 TLS 参数与服务端一致。本文示例没有远端代理出口;真正验证节点需要加入完整出站,并用实际请求检查连接结果。

只有域名分流失效,应该从哪里查起?

先查看应用交给入站的是域名还是已解析的 IP,再核对 domain: 与 full: 的匹配范围,最后检查规则顺序与 domainStrategy。不要在尚未确认目标信息时,同时修改 DNS、嗅探和所有出口参数。

下载v2rayN