深度解析 预计阅读 13 分钟

V2Ray 配置文件 JSON 结构逐段解析:inboundsoutboundsrouting 各管什么

以一份真实结构的配置为样本,逐段拆解 inbounds 入站、outbounds 出站与 routing 路由三大区块的字段含义与相互关系,帮助读者看懂并手动微调自己的配置。

一份 V2Ray JSON 配置不是按执行顺序排列的脚本,而是一张链路声明表。应用流量先进入某个入站,由路由规则读取域名、目标地址、端口或入站标签,再选择一个出站发送。DNS、日志和策略区块为这条主链提供解析、观测与行为控制。读配置时如果只盯着服务器地址,很容易漏掉真正决定流量走向的标签关系。

本文速览

适合已经能导入订阅、但看不懂生成配置的读者;全文从顶层骨架开始,依次检查入站监听、代理与直连出站、路由匹配顺序、DNS 配合方式,并给出可直接用于审阅配置的字段清单。

先建立整条链路:JSON 区块不是彼此独立

V2Ray 核心读取配置后,会创建监听端口、出站处理器和路由器。以本机浏览器为例,浏览器把请求交给本地 SOCKS 或 HTTP 代理端口;入站接收连接并识别目标;routing 从上到下匹配规则;命中的 outboundTag 指向代理、直连或阻断出站。没有命中规则时,通常落到 outbounds 数组中的第一个出站,因此数组顺序本身也有含义。

应用请求 本地入站 目标识别 规则匹配 选定出站
10808
样例 SOCKS 端口
10809
样例 HTTP 端口
3 个
基础出站标签
从上到下
路由规则顺序

下面的骨架省略了服务器身份字段,但保留了区块之间的连接点。重点观察 inbound 的 tag、routing.rules 中的 inboundTag 与 outboundTag,以及 outbounds 中对应的 tag。标签只是配置内部名称,可以自定义;引用处必须逐字一致,并且大小写不能混用。

{
  "log": {
    "loglevel": "warning"
  },
  "inbounds": [
    {
      "tag": "socks-in",
      "listen": "127.0.0.1",
      "port": 10808,
      "protocol": "socks",
      "settings": {
        "udp": true
      },
      "sniffing": {
        "enabled": true,
        "destOverride": ["http", "tls", "quic"]
      }
    }
  ],
  "outbounds": [
    {
      "tag": "proxy",
      "protocol": "vmess",
      "settings": {}
    },
    {
      "tag": "direct",
      "protocol": "freedom"
    },
    {
      "tag": "block",
      "protocol": "blackhole"
    }
  ],
  "routing": {
    "domainStrategy": "IPIfNonMatch",
    "rules": [
      {
        "type": "field",
        "ip": ["geoip:private"],
        "outboundTag": "direct"
      },
      {
        "type": "field",
        "network": "tcp,udp",
        "outboundTag": "proxy"
      }
    ]
  }
}

结论:先追标签,再读协议细节

遇到“规则写了但没有分流”时,先核对 inboundTag、outboundTag 与实际 tag 是否闭合,再检查域名和 IP 条件;这比先改传输参数更容易定位问题。

inbounds:谁在监听,哪些流量能够进入核心

inbounds 是入站数组,每个对象代表一个接收入口。桌面代理最常见的是 SOCKS、HTTP 或由客户端组合管理的本地入口。listen 决定监听地址,port 决定端口,protocol 决定入口怎样解释连接,settings 保存协议专属选项。若 listen 为 127.0.0.1,只有本机程序能够访问;改为 0.0.0.0 会监听全部网络接口,配置前需要明确局域网访问范围和系统防火墙规则。

SOCKS 入站

tag
socks-in
listen
127.0.0.1
port
10808
protocol
socks
udp
true

适合浏览器、终端工具或支持 SOCKS5 的应用显式连接。

HTTP 入站

tag
http-in
listen
127.0.0.1
port
10809
protocol
http
timeout
300

适合读取系统 HTTP 代理设置的桌面程序。

tag 不负责改变协议,它只为 routing 和日志提供稳定引用。一个配置可以同时定义多个入站,并让不同入口执行不同策略。例如 socks-in 默认走代理,http-in 只访问内网;此时路由规则可通过 inboundTag 区分两类连接,而不必根据来源程序猜测。

sniffing 用于从连接初期的数据中恢复目标域名。浏览器先把域名解析为 IP 后再连接时,路由器可能只能看到 IP;启用 sniffing 并设置 destOverride 后,核心有机会从 HTTP 请求或 TLS 握手中取得域名,使 domain 规则参与匹配。它不是 DNS 解析器,也不会自动修复所有域名分流问题。应用采用无法识别的封装时,路由仍可能只看到地址。

{
  "tag": "http-in",
  "listen": "127.0.0.1",
  "port": 10809,
  "protocol": "http",
  "settings": {
    "timeout": 300
  },
  "sniffing": {
    "enabled": true,
    "destOverride": ["http", "tls"]
  }
}
  • 端口占用:启动失败并出现监听错误时,先确认 10808 或 10809 是否已被另一个进程占用。
  • 代理类型:应用填写的 SOCKS5、HTTP 类型必须与对应入站协议一致,不能只看端口数字。
  • UDP 开关:SOCKS 入站需要处理 UDP 时,将 settings.udp 设为 true,同时确认出站与传输链路支持目标流量。
  • 局域网共享:不要只修改 listen;还要检查客户端中的局域网连接选项、系统防火墙和访问控制范围。

outbounds:代理、直连与阻断如何定义

outbounds 是出口数组。代理出站负责把流量封装到远端链路,freedom 出站让核心直接访问目标,blackhole 出站用于终止命中的连接。routing 并不保存服务器连接参数,它只返回一个 outboundTag;真正的地址、端口、用户身份、传输方式与安全层都在对应出站内。

VMess 代理出站

tag
proxy
protocol
vmess
address
节点域名
port
443
network
ws
security
tls

用户参数位于 settings,传输与安全层位于 streamSettings。

本地控制出站

direct
freedom
block
blackhole
引用方式
outboundTag
默认出口
数组首项

私有地址通常直连,明确需要终止的目标可交给 block。

以 VMess 为例,settings.vnext 是服务器列表,users 保存 id、alterId 与 security 等用户参数;streamSettings 则描述 TCP、WebSocket 等承载方式以及 TLS 设置。服务器端要求的传输方式、路径、主机名和端口必须成组一致。只把 network 从 tcp 改成 ws,而没有同步 path 与服务端入口,不会得到兼容链路。

{
  "tag": "proxy",
  "protocol": "vmess",
  "settings": {
    "vnext": [
      {
        "address": "server.example",
        "port": 443,
        "users": [
          {
            "id": "订阅提供的用户标识",
            "alterId": 0,
            "security": "auto"
          }
        ]
      }
    ]
  },
  "streamSettings": {
    "network": "ws",
    "security": "tls",
    "wsSettings": {
      "path": "/gateway"
    },
    "tlsSettings": {
      "serverName": "server.example"
    }
  }
}

VLESS 常见于 Xray 内核配置,外层仍能看到 tag、protocol、settings 和 streamSettings,但 flow、Reality 等字段属于对应内核和链路能力,不能机械复制进任意 V2Ray 配置。v2rayN 使用的核心可由客户端设置决定,v2rayNG 使用 Xray 内核,v2flyNG 使用 v2fly 内核。阅读订阅生成内容时,先确认当前核心,再查该核心支持的字段边界。

  1. 先确认 outbounds 中代理项的 tag 是否为 routing 实际引用的名称。
  2. 再核对 address、port 与用户身份字段,避免把本地监听端口误当远端端口。
  3. 随后核对 network、security、path、serverName 等传输层字段是否成组对应。
  4. 最后查看日志中的握手、超时或连接拒绝信息,不用连续随机切换参数。

结论:连通性错误按层处理

本地端口无法连接先查 inbound;远端超时先查 outbound 地址与网络;单类域名走错出口再查 routing。按层定位可以避免一次改动多个变量。

routing:匹配条件、规则顺序与默认出口

routing.rules 是有顺序的规则数组。常用 type 为 field,条件可以包含 domain、ip、port、network、inboundTag 和 protocol 等。一个规则内部写入多个不同类型条件时,通常需要同时满足;同一字段中的多个值则作为候选集合。规则按声明顺序检查,先命中的规则决定 outboundTag,后续规则不再覆盖它。

{
  "routing": {
    "domainStrategy": "IPIfNonMatch",
    "rules": [
      {
        "type": "field",
        "ip": ["geoip:private"],
        "outboundTag": "direct"
      },
      {
        "type": "field",
        "domain": ["domain:intranet.example"],
        "outboundTag": "direct"
      },
      {
        "type": "field",
        "domain": ["geosite:category-ads-all"],
        "outboundTag": "block"
      },
      {
        "type": "field",
        "network": "tcp,udp",
        "outboundTag": "proxy"
      }
    ]
  }
}

这组规则先放行私有地址,再放行指定内部域名,然后终止命中的目标,最后用 tcp,udp 作为兜底代理。若把兜底代理放到第一条,它会先捕获绝大多数连接,后面的直连和阻断规则便失去执行机会。审查分流配置时,不仅要问“有没有这条规则”,还要问“它前面是否已有更宽的条件”。

字段 匹配对象 典型写法 检查重点
domain 目标域名 domain:example.com 是否能取得域名,是否被前置规则截获
ip 目标地址 geoip:private domainStrategy 是否触发解析
port 目标端口 53 或 80-443 这里不是本地入站端口
network 传输类型 tcp,udp 宽条件应靠后作为兜底
inboundTag 流量入口 socks-in 必须与 inbounds 的 tag 一致

domainStrategy 决定路由阶段怎样处理域名与 IP 条件。AsIs 尽量按原始目标匹配,不为 IP 规则主动解析域名;IPIfNonMatch 会先尝试域名规则,在没有命中时解析地址并继续匹配 IP 规则;IPOnDemand 在可能需要 IP 匹配时更积极地解析。选择它不是速度开关,而是规则语义选择。配置包含 geoip:private 等 IP 规则,同时入口经常提供域名时,IPIfNonMatch 是较容易理解的起点。

DNS 与路由怎样配合:解析结果不等于最终出口

dns 区块定义核心可使用的解析服务器、静态 hosts 和查询策略,routing 决定连接交给哪个出站。两者有关联,但不是同一个步骤。应用如果自行发出 DNS 查询,查询会先作为普通网络流量进入核心;应用如果已经给出目标 IP,域名规则能否参与匹配还取决于 sniffing 和连接中是否存在可识别的域名信息。

{
  "dns": {
    "hosts": {
      "domain:internal.example": "192.168.10.20"
    },
    "servers": [
      {
        "address": "223.5.5.5",
        "port": 53,
        "domains": ["geosite:cn"]
      },
      "1.1.1.1"
    ],
    "queryStrategy": "UseIP"
  },
  "routing": {
    "domainStrategy": "IPIfNonMatch",
    "rules": [
      {
        "type": "field",
        "port": 53,
        "network": "udp",
        "outboundTag": "proxy"
      }
    ]
  }
}

样例把 UDP 53 端口流量交给 proxy,但它并不覆盖所有解析形态:应用可能使用 TCP 53,也可能使用加密的 HTTPS 连接完成解析。更稳妥的排查方式是先确认请求究竟由系统解析器、应用自身还是核心 DNS 发出,再决定路由规则需要匹配端口、域名还是特定入站。仅增加一个 DNS 地址,无法自动保证全部请求采用同一出口。

  • 域名规则完全不命中时,检查入站是否启用 sniffing,以及日志中目标显示为域名还是 IP。
  • 私有域名应直连但被代理时,把明确的内部域名与 geoip:private 规则放在宽泛代理规则之前。
  • 修改 DNS 后结果没有变化时,重启相关应用并清理系统解析缓存,再进行单一目标测试。
  • 出现解析成功但连接超时时,DNS 已完成工作,下一步应检查 routing 选择和 outbound 链路。
53
传统 DNS 目标端口
443
常见加密解析端口
3 层
应用、核心、系统解析

手动微调前的检查顺序:避免改完被覆盖

客户端通常把订阅节点、全局参数和路由设置合成为运行配置。v2rayN 7.13.x 的通用参数可从「设置」→「参数设置」进入,先记录本地端口、核心类型、系统代理模式与 DNS 相关选项;路由调整应在客户端提供的路由设置中完成。v2rayNG 1.10.x 可从「设置」检查本地代理、DNS 与分流相关项目。版本界面可能调整文字,但审查顺序不变:先确认配置来源,再确认生成结果。

  1. 保留可恢复副本:导出当前客户端配置或复制准备修改的独立 JSON,记录原有模式和生效范围。
  2. 验证 JSON 语法:检查逗号、引号、方括号与花括号。JSON 不接受行尾注释,也不能在数组最后一项后保留多余逗号。
  3. 检查标签闭环:列出全部 inbound tag、outbound tag 和规则引用,确认不存在拼写差异。
  4. 一次只改一层:端口问题只改入站,节点问题只改出站,分流问题只改规则顺序和条件。
  5. 建立最小测试集:分别测试一个应直连目标、一个应代理目标和一个明确阻断目标,并记录三次结果。
  6. 回到客户端持久设置:确认临时修改有效后,把等价设置写回 v2rayN、v2rayNG 或 v2flyNG 的正式配置入口。

JSON 能启动,但所有网站都走代理,哪里最可能写错?

先看 routing.rules 的第一条是否已经用 network: tcp,udp 或过宽的 domain 条件捕获全部连接。把私有地址、内部域名和明确直连规则移到兜底代理规则之前,再重启核心测试。

改了 outbounds 的服务器地址,切换节点后为什么恢复了?

当前文件很可能由订阅节点动态生成。应编辑客户端保存的节点资料,或在节点列表中更新对应服务器字段;不要把运行目录中的临时 JSON 当作长期配置源。

规则写了 domain,日志里却只有 IP,怎么处理?

检查对应 inbound 的 sniffing.enabled 是否为 true,并确认 destOverride 包含实际流量类型。仍只有 IP 时,再检查应用是否提前解析且连接中没有可恢复的域名。

10808 能连接,10809 连接失败,是节点坏了吗?

先核对 inbounds 是否同时声明两个端口,以及 10809 对应的 protocol 是否为 http。单个本地端口失败通常属于监听或端口占用问题,不能直接归因于远端节点。

配置中同时有 proxy、direct、block,怎样确认实际用了哪一个?

把日志级别临时设为 info,分别访问预设的代理、直连和阻断目标,结合目标地址与报错结果检查规则。完成后恢复 warning,并保留三类测试目标供后续回归。

读懂 V2Ray 配置的关键不是记住所有字段,而是把每次连接还原为“从哪个入站进入、携带什么目标、命中哪条规则、落到哪个出站”。inbounds 解决接收问题,outbounds 解决发送问题,routing 解决选择问题,DNS 与日志补充解析和观测。沿着这条链检查,即使配置由订阅和客户端自动生成,也能快速找到端口冲突、标签断链、规则遮挡和传输参数不一致的位置。

下载 v2rayN