本文速览

本文适合已经导入节点、希望读懂运行配置的用户。先沿着本地端口找到入站,再根据路由中的标签找到出站,最后区分节点参数、传输参数与客户端设置。读完后,可以判断连接在哪一层失败,也能识别“配置能加载”和“节点能连接”之间的差别。

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

config.json 通常指交给内核读取的 JSON 文件,文件名本身并不决定内容。v2rayN 保存的服务器列表、订阅分组和界面偏好,属于客户端管理的数据;启动内核时,客户端再根据活动服务器与路由设置生成运行配置。只导出一条分享链接,得到的不是包含入站和路由的完整配置。

阅读时应以实际运行文件为准。v2rayN 不同版本的导出入口与生成文件位置可能变化,应先确认导出对象是完整配置而不是服务器分享内容。安卓端的 v2rayNG 使用 Xray 内核,v2flyNG 使用 V2Fly 内核;两者有相近的基础结构,但扩展字段不能据此认定为通用。

应用请求本地入站路由匹配选定出站目标服务

二、一份脱敏后的完整 config.json 样本

下面按客户端完整导出配置的结构整理为阅读样本,保留两个本地入站、三个出站与两条路由,地址和身份参数已改成示例值。它是完整的 JSON 文档,但不是可连接的节点:example.com:443 不代表存在对应的 VMess 服务,不能直接拿它测试网络。

{
  "log": {
    "loglevel": "warning"
  },
  "dns": {
    "servers": ["localhost"]
  },
  "inbounds": [
    {
      "tag": "socks-in",
      "listen": "127.0.0.1",
      "port": 10808,
      "protocol": "socks",
      "settings": {
        "auth": "noauth",
        "udp": true
      }
    },
    {
      "tag": "http-in",
      "listen": "127.0.0.1",
      "port": 10809,
      "protocol": "http",
      "settings": {}
    }
  ],
  "outbounds": [
    {
      "tag": "proxy",
      "protocol": "vmess",
      "settings": {
        "vnext": [
          {
            "address": "example.com",
            "port": 443,
            "users": [
              {
                "id": "11111111-1111-4111-8111-111111111111",
                "alterId": 0,
                "security": "auto"
              }
            ]
          }
        ]
      },
      "streamSettings": {
        "network": "tcp",
        "security": "tls",
        "tlsSettings": {
          "serverName": "example.com"
        }
      }
    },
    {
      "tag": "direct",
      "protocol": "freedom",
      "settings": {}
    },
    {
      "tag": "block",
      "protocol": "blackhole",
      "settings": {}
    }
  ],
  "routing": {
    "domainStrategy": "AsIs",
    "rules": [
      {
        "type": "field",
        "domain": ["full:example.org"],
        "outboundTag": "direct"
      },
      {
        "type": "field",
        "ip": ["geoip:private"],
        "outboundTag": "direct"
      }
    ]
  }
}

三、inbounds:监听地址、端口与应用代理类型

第一个入站在 127.0.0.1:10808 接收 SOCKS 请求,第二个在 127.0.0.1:10809 接收 HTTP 代理请求。两个端口是本文样本的明确取值,不保证与你的客户端一致。应用需要填写哪一个,取决于应用选择的代理类型,而不是目标网站使用 HTTP 还是 HTTPS。

SOCKS 入站

标识
socks-in
监听
127.0.0.1
端口
10808
协议
socks

应用选择 SOCKS5 时填写此入口;UDP 还需要应用与后续链路共同支持。

HTTP 入站

标识
http-in
监听
127.0.0.1
端口
10809
协议
http

应用选择 HTTP 代理时填写此入口;HTTPS 目标通常通过 CONNECT 建立隧道。

listen 为回环地址时,仅本机可以连接。若为了局域网共享改成 0.0.0.0,监听范围会扩大,还需要同时考虑身份认证与防火墙,不能只把地址改掉。本例 SOCKS 入站的 auth: "noauth" 表示不要求认证,应维持本机使用的范围。

udp: true 只打开 SOCKS 入站的 UDP 能力,不会把整个系统的 UDP 自动送进代理,也不代表 HTTP 入站具备相同能力。若应用没有使用这个入口,即使内核启动成功,也不会出现预期的代理连接。

四、outbounds:节点身份、传输与出口标签

outbounds 是数组,可以同时列出多个出口。本例第一个出口标为 proxy,协议为 VMess;vnext 中的 address 和 port 是远端服务器地址与端口,users 中的 id 是用户身份参数。这里的 443 是远端端口,与本地 10808、10809 没有替代关系。

字段本例值阅读重点
protocolvmess决定代理协议及其 settings 结构。
users[].securityautoVMess 用户层的加密选项,不是 TLS 开关。
users[].alterId0使用 VMess AEAD 的常见设置,应与服务端要求一致。
streamSettings.networktcp本例的传输方式;名称与可用值受内核版本影响。
streamSettings.securitytls启用传输层 TLS,与用户层 security 各司其职。
tlsSettings.serverNameexample.com用于 TLS 的服务器名称与证书名称校验。

direct 使用 freedom 直接访问目标,block 使用 blackhole 拒绝流量。它们只是标签名称,真正的行为由 protocol 决定;把 freedom 的标签改成“proxy”,也不会让它变成远端代理。本例没有规则引用 block,所以仅仅声明这个出站并不会自动拦截任何请求。

判断配置兼容性:先看协议,再看内核字段

不要把 VMess 的 protocol 改成 VLESS 后直接运行。两者的身份与加密字段结构不同;涉及 REALITY 等扩展时,还必须确认当前运行的是支持该字段的 Xray 内核,而不能仅根据文件名判断。

五、routing:规则顺序、tag 引用与默认出口

路由规则从上往下检查,命中后按该规则选择出口。本例第一条只把完整域名 example.org 交给 direct。full: 表示完整匹配,不会顺带匹配它的子域名。第二条把匹配私有地址范围的目标交给同一个出口;其余连接没有命中时,使用 outbounds 中的第一个出站,也就是 proxy。

  1. 连接目标为域名 example.org:第一条命中,寻找 tag: "direct" 的出站。
  2. 连接目标为地址 192.168.1.20:第二条命中私有地址规则,直接访问局域网目标。
  3. 连接目标为其他未命中的域名:落到第一个出站 proxy,尝试连接示例 VMess 服务器。

outboundTag 必须与出站的 tag 精确对应,包括大小写。入站标签则可以通过规则的 inboundTag 数组参与匹配,例如只处理 ["socks-in"] 的连接。入站标签与出站标签不是自动配对关系,也不要求名称相同。

本例采用 domainStrategy: "AsIs",路由阶段不会为了 IP 规则主动把域名解析成地址。因此,连接若仍以域名形式进入,第二条私有 IP 规则不一定能识别它最终指向的局域网地址。需要这类行为时,应先理解 IPIfNonMatch 或 IPOnDemand 的解析时机,再结合 DNS 设置调整,而不是假定每条域名请求都已具备目标 IP。

修改路由前,先记录第一个出站

将 direct 移到数组第一位,会改变所有未命中规则连接的默认出口。调整规则和调整出站顺序应分开进行,每次只改一项,避免把默认直连误认为规则失效。

六、dns 与 log:能加载不等于能连接

本例 dns.servers 使用 localhost,表示内置 DNS 在需要解析时可以调用系统解析能力。这并不是在本地开放一个 DNS 服务端口,也不会自动接管应用发往其他 DNS 服务器的请求。路由解析、出站解析和应用自身解析发生在不同位置,必须结合实际入站方式判断。

loglevel: "warning" 会减少普通连接信息。排查时可临时改为 info,重启内核后复现一次失败请求;排查完成后再恢复。日志可能包含访问域名、目标地址与配置路径,公开求助前应删去订阅链接、用户身份参数及个人路径。

七、config.json 常见问题

文件能打开,为什么内核还是说配置有错?

文本编辑器能打开文件,不代表它是合法 JSON。先检查末尾逗号、双引号和括号,再根据日志定位字段。语法正确后,还要确认字段属于当前内核支持的结构;例如不能把出站对象误放到 inbounds 数组中。

把 10808 填进 HTTP 代理设置,为什么连接失败?

本例 10808 接收 SOCKS,10809 才接收 HTTP 代理请求。在应用里把类型改为 SOCKS5 并使用 10808,或者保留 HTTP 类型并改用 10809;实际操作前仍要核对你自己的运行配置端口。

配置里写了 proxy,为什么流量还是直连?

先确认应用确实连接本地入站,再检查命中的规则是否指向 direct。proxy 只是标签,不会自动开启系统代理;客户端的系统代理开关与内核的路由配置需要分别核对。

能把桌面的完整配置直接导入安卓客户端吗?

先确认目标客户端支持的内核字段和导入方式。桌面监听端口、日志路径及路由数据依赖未必适合安卓环境。只需要同步服务器时,优先导入订阅或节点分享内容,再在目标客户端设置本地监听与路由,不要整份覆盖运行配置。