2026-10-15 · 配置解析 · 约 12 分钟

V2Ray config.json 逐段拆解:inbounds、outbounds 与 routing 怎么写

从顶层结构入手,逐段拆解入站监听、出站代理与路由规则的字段含义和常见写法,附可对照的 JSON 片段,帮助看懂客户端生成的配置。

本文速览

适合已经导入节点、但还看不懂客户端生成配置的读者。先用本机 10808 端口和直连出站验证配置结构,再对照 VMess 出站与域名路由片段理解字段关系。读完可以区分本地监听、远端连接、规则匹配与客户端设置,不再把订阅链接当成完整 config.json。

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

config.json 是内核读取的配置文件名之一,不是固定的存储位置。v2rayN 等客户端可能生成临时运行配置;手动修改生成文件,下一次切换节点时可能被覆盖。先确认当前运行的是 Xray 还是 V2Fly,再查看实际加载的配置文件与启动日志。

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

inbounds 与 outbounds 都是数组,分别允许配置多个入口和出口。routing 是对象,其中的 rules 才是规则数组。tag 是配置内部引用的名字,不是服务器地址;规则通过 outboundTag 指向某个出站。

下面是仅用于本地直连测试的完整基础配置。它在回环地址开放 SOCKS 服务,所有未被规则处理的请求使用第一个出站 direct。这份配置没有远端代理节点,也不会自动修改系统代理。

{
  "log": {
    "loglevel": "warning"
  },
  "inbounds": [
    {
      "tag": "local-socks",
      "listen": "127.0.0.1",
      "port": 10808,
      "protocol": "socks",
      "settings": {
        "auth": "noauth",
        "udp": true
      }
    }
  ],
  "outbounds": [
    {
      "tag": "direct",
      "protocol": "freedom",
      "settings": {}
    },
    {
      "tag": "block",
      "protocol": "blackhole",
      "settings": {}
    }
  ],
  "routing": {
    "domainStrategy": "AsIs",
    "rules": []
  }
}

2. inbounds:监听地址、端口与本地协议

入站决定“应用怎样把流量交给内核”。上例中的 127.0.0.1:10808 是本机 SOCKS 入口,不是远端节点端口。浏览器、命令行工具或其他支持 SOCKS 的程序,需要明确使用这个入口,流量才会进入内核。

本地 SOCKS 入站

tag
local-socks
listen
127.0.0.1
port
10808
protocol
socks

只接收本机连接;应用端须选择 SOCKS 协议。

可选 HTTP 入站

tag
local-http
listen
127.0.0.1
port
10809
protocol
http

需要单独加入 inbounds;不会随 SOCKS 入站自动出现。

10808 和 10809 是本文选用的示例值,不是每个版本的固定默认值。将应用中的 HTTP 代理直接指向 SOCKS 端口,会造成协议不匹配。客户端如果提供混合入口,应以该入口的实际协议能力为准,不要由端口号猜测。

用下面的命令检查应用是否能通过示例入口发起 HTTPS 请求。Windows 可使用 curl.exe,macOS 与 Linux 可使用 curl。其中 socks5h 表示把目标域名交给代理端处理;代理端最终怎样解析,还取决于配置。

curl --proxy socks5h://127.0.0.1:10808 --connect-timeout 10 -I https://example.com

3. outbounds:远端节点与传输参数

出站决定“内核从哪里连接目标”。freedom 表示直连,blackhole 用于阻断,vmess 则需要远端服务端配合。入站可以是 SOCKS,出站可以是 VMess;它们不需要同名,因为服务的是连接链路的不同位置。

下面是替换顶层 outbounds 的演示片段。192.0.2.10 是文档示例地址,UUID 与域名也仅用于解释结构,不能直接连接。实际使用时,地址、端口、用户标识、传输与 TLS 参数必须取自已获授权的服务端配置,不能只替换其中一个字段。

{
  "outbounds": [
    {
      "tag": "proxy",
      "protocol": "vmess",
      "settings": {
        "vnext": [
          {
            "address": "192.0.2.10",
            "port": 443,
            "users": [
              {
                "id": "b43b4b90-a710-4ee4-883d-b8c574099d11",
                "alterId": 0,
                "security": "auto"
              }
            ]
          }
        ]
      },
      "streamSettings": {
        "network": "tcp",
        "security": "tls",
        "tlsSettings": {
          "serverName": "proxy.example.net"
        }
      }
    },
    {
      "tag": "direct",
      "protocol": "freedom",
      "settings": {}
    },
    {
      "tag": "block",
      "protocol": "blackhole",
      "settings": {}
    }
  ]
}
字段位置示例值核对内容
settings.vnext[].address192.0.2.10远端连接地址,不是本地监听地址。
settings.vnext[].port443服务端接收连接的端口,不是 10808。
users[].securityautoVMess 用户加密选项,不是 TLS 开关。
streamSettings.networktcp本例使用 TCP 传输;其他传输需要对应配置。
streamSettings.securitytls传输层安全方式,与协议内的 security 含义不同。
tlsSettings.serverNameproxy.example.netTLS 服务名称,须与服务端部署和证书匹配。

结论:先核对协议,再核对传输

把 VMess 改成 VLESS 不能只改 protocol。先按所用内核的配置规范核对 settings,再核对 streamSettings;遇到 TLS 失败,应检查域名、证书与系统时间,不要把关闭证书验证作为常规修复。

v2rayNG 使用 Xray 内核,v2flyNG 使用 V2Fly 内核;v2rayN 的可用内核以实际安装与选择为准。相似的顶层结构不代表扩展字段完全兼容,尤其是 VLESS 的特定安全组合。本文的 TCP 字段写法用于解释常见配置,实际字段名称与兼容性应结合所装内核版本核对。

4. routing:规则顺序、标签引用与默认出口

路由不是把几个域名分组后自动生效,而是按顺序检查规则。通常先命中的规则决定出口;一条规则中的不同条件需要同时满足,同一条件数组内的多个值则表示可选匹配项。outboundTag 必须与现有出站的 tag 精确一致。

下面的片段依赖上一节的 proxy、direct、block 三个出站。它先阻断一个演示域名,再让私有地址直连,最后将其余流量交给代理。两个域名都只是规则示例,不代表实际访问建议。

{
  "routing": {
    "domainStrategy": "AsIs",
    "rules": [
      {
        "type": "field",
        "domain": ["full:blocked.example.org"],
        "outboundTag": "block"
      },
      {
        "type": "field",
        "ip": ["10.0.0.0/8", "172.16.0.0/12", "192.168.0.0/16"],
        "outboundTag": "direct"
      },
      {
        "type": "field",
        "domain": ["domain:example.org"],
        "outboundTag": "direct"
      },
      {
        "type": "field",
        "network": "tcp,udp",
        "outboundTag": "proxy"
      }
    ]
  }
}
  1. full:blocked.example.org 只匹配该完整域名。它虽然也属于 example.org 的子域名,但阻断规则靠前,因此优先阻断。
  2. 私有网段规则处理目标 IP 落入相应范围的请求。它不是一份完整的特殊地址清单,也不自动涵盖 IPv6 本地地址。
  3. domain:example.org 匹配该域名及其子域名,不等同于任意字符串包含。
  4. 最后的 network: "tcp,udp" 是本例的兜底规则,必须放在具体规则之后,否则前面的分流意图可能被提前截走。

如果没有任何规则命中,通常使用 outbounds 数组的第一个出站。第一节的第一个出站是 direct,第三节改成了 proxy,因此仅调整数组顺序也可能改变默认行为。不要用“数组里有代理节点”来判断所有请求都经过代理。

5. dns、日志与客户端生成配置的边界

routing.domainStrategy 控制路由匹配阶段如何处理域名,不是 DNS 服务器地址,也不是完整的 DNS 分流策略。AsIs 尽量保留原目标进行匹配;IPIfNonMatch 在域名规则未匹配时尝试解析后继续检查 IP 规则;IPOnDemand 则可能在检查 IP 规则时触发解析。

下面的片段仅增加内置 DNS 设置,不会自动修改操作系统 DNS,也不保证每个应用的查询都进入内核。若应用在连接前已完成本地解析,内核可能只收到 IP;若使用代理协议传递域名,最终解析位置还可能由出站和服务端决定。

{
  "dns": {
    "servers": ["localhost"]
  }
}

阅读客户端导出的配置时,先定位 inbounds[].port、outbounds[].tag 和 routing.rules,再追踪 DNS 与传输细节。不要直接删除不认识的管理入口或附加字段;它们可能服务于客户端统计、控制接口或运行时功能。分享日志前也应移除用户标识、订阅地址和服务器资料。

6. 配置修改后的检查顺序与常见问题

修改前保留一份可恢复的配置,每次只改一个层面。先验证 JSON 和内核字段,再确认端口监听,最后测试远端连接与规则命中。下面的检查命令适用于提供相应命令行接口的较新内核;实际参数以已安装程序的帮助输出为准,客户端托管配置应使用它实际加载的文件路径。

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

测试命令通过,不代表节点可用。它主要检查配置能否被当前内核接受,不会替代远端认证、TLS 握手和目标访问测试。若内核能启动但应用仍连接失败,应沿“本地入口、远端出口、路由结果”的顺序缩小范围。

提示 address already in use,先改哪个端口?

先查被占用的是哪个入站端口。若日志指向 10808,关闭重复运行的内核,或把 inbounds 中的端口改为 10810,并同步修改应用代理地址。不要因此修改远端节点的 443 端口。

能启动,但 curl 仍然连不上?

先用第一节的直连配置和 socks5h 测试命令确认入口。若连接本机端口就失败,检查监听地址、端口和代理协议;若连接已进入内核再超时,继续检查远端地址、认证与 TLS 日志。

写了 direct 规则,为什么仍然走 proxy?

核对规则顺序、outboundTag 拼写以及内核实际收到的是域名还是 IP。检查兜底规则是否被放在前面,再确认修改的文件确实被当前进程加载,而不是客户端已经重新生成了另一份配置。

订阅更新后,手改的 JSON 为什么消失了?

客户端可能按节点与全局设置重新生成运行配置。持久调整应放在客户端提供的路由、入站或自定义配置功能中;如果选择独立管理完整 JSON,就同时明确文件路径和内核启动方式,避免两套配置互相覆盖。

结论:用一条请求验证一个修改

先固定本地入口 127.0.0.1:10808 和同一测试目标,再分别验证直连、代理与路由。每次重新加载后观察一次日志,比同时修改端口、DNS 和传输参数更容易找到故障层。

下载客户端