CONFIGURATION REFERENCE · JSON

V2Ray 配置文件参考大全

从顶层对象进入,逐段查阅 inboundsoutboundsroutingdnspolicy 与传输层字段。

本页用于系统查阅字段、对象层级与匹配顺序。若目标是完成第一次订阅导入、选择模式与连接测试,请先沿着入门指南操作;需要选择安装包时,转到客户端页面。两页解决操作主线,本页负责解释配置为何如此组织。

01 / structure 02 / inbound 03 / outbound 04 / routing 05 / dns 06 / policy 07 / stream 08 / diagnosis
TABLE OF CONTENTS

示例采用标准 JSON。复制时应保留双引号、逗号与括号层级,不要把正文中的解释文字写入配置文件。

01
ROOT OBJECT

JSON 结构总览与配置读取顺序

V2Ray 与 Xray 的主配置可以理解为一个描述流量处理管线的 JSON 对象:入站接收连接,路由判断去向,出站执行连接,DNS 与策略对象为这条管线补充解析和资源约束。

顶层对象不是执行步骤清单

配置文件最外层由一个 JSON 对象构成,常见键包括 logdnsinboundsoutboundsroutingpolicystats。这些键在文本中的先后位置通常不决定执行顺序,因为 JSON 对象按键名表达结构,而不是按书写位置表达流程。真正具有顺序语义的地方主要是数组,例如 routing.rules 会从前向后匹配,先命中的规则先决定出站;多个入站与出站也通过各自的 tag 被其他对象引用。

阅读配置时,较稳妥的方法是先记录所有标签,再沿引用关系检查。一个入站标签可能被路由规则的 inboundTag 使用,一个出站标签会被 outboundTag 指向,DNS 服务器又可能通过 tag 与路由规则连接。标签本身只是配置内部的标识符,不会自动产生分流效果。若规则写了一个并不存在的标签,配置可能在启动阶段报错,也可能在运行到相关路径时表现为流量没有可用去向,具体取决于内核及字段位置。

{
  "log": {
    "loglevel": "warning"
  },
  "dns": {
    "servers": ["1.1.1.1", "localhost"]
  },
  "inbounds": [
    {
      "tag": "socks-in",
      "listen": "127.0.0.1",
      "port": 10808,
      "protocol": "socks",
      "settings": {
        "udp": true
      }
    }
  ],
  "outbounds": [
    {
      "tag": "direct",
      "protocol": "freedom"
    },
    {
      "tag": "blocked",
      "protocol": "blackhole"
    }
  ],
  "routing": {
    "domainStrategy": "AsIs",
    "rules": [
      {
        "type": "field",
        "ip": ["geoip:private"],
        "outboundTag": "direct"
      }
    ]
  }
}

数组、对象与值类型

inboundsoutboundsrouting.rules 都是数组,因此使用方括号;单个入站、出站或规则则是对象,使用花括号。端口是数字,不应写成带单位的字符串;布尔值只能写为 truefalse;缺省字段与值为 null 并不等价。缺省表示让内核采用默认行为,而显式的空值只有在字段定义允许时才有意义。许多启动失败都不是协议问题,而是括号闭合错误、对象之间缺逗号、字符串误用中文引号,或把本应为数组的字段写成单个字符串。

标准 JSON 不允许注释,也不允许最后一个成员后保留尾随逗号。网上示例为了讲解常写 // 注释,但复制到客户端核心配置前必须删除。v2rayN、v2rayNG 与 v2flyNG 可能在图形界面之外维护自己的配置层,界面中的节点、订阅和路由设置经过转换后才交给内核。因此,手工编辑前应先确认正在修改的是客户端管理文件、生成后的运行配置,还是独立核心读取的配置;三者不能根据文件名相似就视为同一对象。

从最小配置逐步增加复杂度

排查配置时应先保留一个本地入站、一个明确可用的出站和最少量路由,再逐步加入 DNS、嗅探、多个传输以及统计策略。一次加入多个模块会让错误来源互相遮蔽。例如连接失败既可能来自远端参数,也可能是域名先被错误 DNS 路径解析,或前置规则把连接送到了 blocked。最小化不是删除必要安全字段,而是缩短变量链:保持服务端要求的地址、端口、用户标识、传输和安全参数不变,只暂时移除不影响连通性的附加规则。

保存前还应确认文本编码为 UTF-8、文件内容只有一个根对象、键名大小写与字段定义一致。outboundTagoutboundtag 是不同名称,协议名也不应凭界面译名推测。完成结构检查后,再进入入站、出站与路由三部分逐段验证,这比直接在一份大型配置中反复改动端口更容易得到可解释的结果。

02
INBOUND HANDLERS

inbounds 入站、监听范围与协议设置

入站定义内核从哪里接收连接、使用什么协议理解连接,以及是否对目的地址进行嗅探。桌面客户端常建立本地 SOCKS 与 HTTP 入站,移动端则可能由 VPN 服务把流量送入内核。

listen、port 与本地暴露范围

每个入站至少需要明确协议及其设置,常见字段包括 taglistenportprotocolsettingssniffingstreamSettings。当 listen 写为 127.0.0.1 时,只有本机程序能够连接该端口,适合作为浏览器、系统代理或本机工具的入口。若监听所有网络接口,同一局域网中的其他设备也可能尝试访问,因此必须同时考虑操作系统防火墙、身份验证和实际共享需求。没有明确的局域网共享目的时,本地回环地址通常是更清晰的边界。

port 必须未被其他程序占用。同一个地址与端口组合不能被两个同时运行的入站重复监听。图形客户端常为 SOCKS、HTTP 或混合入口分配相邻端口,但这些端口不是协议固定值;将教程里的端口照搬到另一台设备,可能正好与开发服务器、旧客户端进程或其他网络工具冲突。出现“地址已在使用”一类错误时,应先关闭重复实例,或在客户端设置中修改监听端口,再同步更新系统代理指向。

{
  "inbounds": [
    {
      "tag": "socks-in",
      "listen": "127.0.0.1",
      "port": 10808,
      "protocol": "socks",
      "settings": {
        "auth": "noauth",
        "udp": true
      },
      "sniffing": {
        "enabled": true,
        "destOverride": ["http", "tls"]
      }
    },
    {
      "tag": "http-in",
      "listen": "127.0.0.1",
      "port": 10809,
      "protocol": "http",
      "settings": {}
    }
  ]
}

SOCKS、HTTP 与透明入口的边界

SOCKS 入站能够承载由应用主动发起的代理连接,启用 udp 后还可接收符合 SOCKS UDP 转发流程的请求;这不表示任意系统 UDP 都会自动进入该端口。HTTP 入站主要处理支持 HTTP 代理设置的应用。系统代理通常只影响主动读取系统设置的软件,不等于抓取设备上的全部流量。透明代理或基于虚拟网络接口的接入方式需要操作系统网络规则与客户端协作,字段和权限条件更复杂,不应仅把普通 SOCKS 入站的协议名替换后使用。

在 v2rayN 中,界面负责创建本地入口并设置 Windows、macOS 或 Linux 的系统代理状态;在 v2rayNG 与 v2flyNG 中,Android VPN 服务负责把所选应用的流量送入内核。由此可见,同一份节点出站参数可以跨客户端迁移,但入站部分往往与平台集成方式绑定。迁移时应保留服务器参数,重新让目标客户端生成本地入口,而不是完整覆盖其运行配置。平台安装与客户端定位可在客户端下载页核对。

sniffing 的作用与误判边界

嗅探用于从连接早期数据中恢复域名,以便域名路由规则能够处理原本只携带 IP 目的地址的请求。destOverride 中常见的 httptls 分别对应可识别的 HTTP 主机信息和 TLS 握手域名。嗅探不会解密应用内容,也不能保证每条连接都能恢复域名;加密握手变化、非标准协议、连接复用或直接使用 IP 的应用都可能无法提供可用域名。

如果启用嗅探后某个应用的目的地址被重写并导致连接异常,可先把该应用流量放入独立入站,或限制覆盖类型,比较启用与关闭时的日志。不要把嗅探当成 DNS 的替代品:DNS 决定域名如何解析,嗅探是在连接进入后尝试识别原始域名,两者发生在不同阶段。路由规则若同时包含域名和 IP 条件,还要结合 domainStrategy 判断内核是否会为路由目的额外解析域名。

字段 常见值 检查重点
listen 127.0.0.1 是否确实需要允许其他设备访问
port 有效端口数字 是否与其他程序或入站重复
protocol sockshttp settings 是否属于对应协议
tag 自定义唯一名称 路由中的引用是否完全一致
03
OUTBOUND HANDLERS

outbounds 出站、节点参数与链式关系

出站负责把经过路由选择的连接发送到目标位置。它既可以连接远端协议服务器,也可以直接访问目标、拒绝连接,或把流量交给另一个出站继续处理。

协议字段必须作为一个整体核对

远端出站通常由 protocolsettingsstreamSettings 共同定义。以 VLESS 为例,服务器地址与端口位于 vnext 项,用户标识位于 users;传输方式、安全层与服务器名称则在 streamSettings 中。只核对地址、端口和用户标识并不足以证明配置一致,客户端与服务端的网络传输、TLS 类安全设置、路径、主机名以及相关扩展参数也必须相互对应。

配置界面常把这些字段分散在“地址”“用户”“传输”“安全”等页面中,而 JSON 将它们放在相邻对象。订阅导入异常时,先在客户端详情页逐项查看,不要仅根据节点显示名称判断。节点名称通常只是本地备注,不参与协议握手;真正影响连接的是结构化字段。若手工迁移参数,应避免把 URI 中经过编码的文本直接当作 JSON 原值,也不要把界面中表示“默认”的空白项擅自改成字符串 "default"

{
  "outbounds": [
    {
      "tag": "remote-vless",
      "protocol": "vless",
      "settings": {
        "vnext": [
          {
            "address": "server.example.com",
            "port": 443,
            "users": [
              {
                "id": "11111111-1111-4111-8111-111111111111",
                "encryption": "none"
              }
            ]
          }
        ]
      },
      "streamSettings": {
        "network": "ws",
        "security": "tls",
        "tlsSettings": {
          "serverName": "server.example.com"
        },
        "wsSettings": {
          "path": "/example-path",
          "headers": {
            "Host": "server.example.com"
          }
        }
      }
    },
    {
      "tag": "direct",
      "protocol": "freedom"
    },
    {
      "tag": "blocked",
      "protocol": "blackhole"
    }
  ]
}

direct 与 blocked 是明确的处理路径

freedom 出站通常用于直接连接目标,常被标记为 directblackhole 用于终止被规则选中的连接,常标记为 blocked。这些标签只是约定俗成的名称,可以更改,但路由引用必须同步。把 freedom 放在出站数组中不会自动让本地地址直连,仍需路由规则把相应流量指向它。类似地,定义 blackhole 也不会自动拦截任何域名,只有匹配规则引用后才会生效。

当没有规则命中时,内核通常会选择默认出站,具体行为与配置结构和内核实现有关。为了避免配置阅读者依赖隐含顺序,大型配置宜为关键流量写出明确规则,并保持出站标签具有可读含义。远端出站、直连出站与阻断出站的名称应体现用途,而不是使用容易混淆的连续数字。名称清晰后,日志中的出站标识也更容易对应到配置。

出站链、代理设置与循环

部分内核允许通过 proxySettings 或其他机制让一个出站经由另一个出站建立连接。这适用于明确设计的链式出口,但也增加了 DNS、握手与故障定位的层数。链条中的每一段都要有唯一标签,且不能形成 A 指向 B、B 又指向 A 的循环。远端服务器域名如何解析也需要单独考虑:如果用于建立第一段连接的 DNS 查询反过来依赖尚未建立的出站,就可能出现启动后持续超时的闭环。

排查链式配置时,应先让最后承担物理连接的单个出站独立可用,再逐段向前加入。日志中若只有“连接被关闭”,需要结合出站标签判断失败发生在哪一层。远端拒绝、域名解析失败、TLS 服务器名称不符与本地路由提前选择错误出站,都会在表面上表现为应用打不开页面。逐层验证比同时替换所有协议参数更能保留证据。

桌面端优先使用 v2rayN 管理节点与核心配置,Android 可根据内核需求选择 v2rayNG 或 v2flyNG。若需要比较 Xray 与 V2Fly 的定位,可继续阅读Xray 与 V2Fly 内核区别梳理;内核分支的字段支持范围可能不同,迁移复杂配置前应确认目标客户端实际启用的内核。

04
ROUTING RULES

routing 路由规则、匹配条件与优先级

路由对象不负责产生连接,它接收入站已经识别出的目标信息,并按照规则数组选择出站。理解“从前到后、首个命中”是维护分流配置的核心。

规则数组的匹配模型

routing.rules 中常见的规则类型为 field,可按 domainipportnetworkprotocolinboundTaguser 等条件筛选连接,并通过 outboundTag 指定去向。同一条规则内出现多个不同类别的条件时,通常需要同时满足;同一字段数组中的多个值则通常表达任一值命中。维护时不要只看某一个域名列表,还要检查同条规则是否附带了端口或入站标签限制。

规则从数组第一项向后检查。较具体的例外应放在较宽泛的规则之前,例如一个需要走远端出站的内部测试域名,应置于覆盖范围更大的直连域名集合前。若宽规则先命中,后面的例外永远没有机会执行。最后可以设置一个覆盖剩余连接的规则,也可以依赖默认出站,但前者通常更便于审阅。调整规则时应一次只移动一组,并记录移动前后的命中标签,避免把“规则没匹配”和“出站不可用”混为一谈。

{
  "routing": {
    "domainStrategy": "IPIfNonMatch",
    "domainMatcher": "hybrid",
    "rules": [
      {
        "type": "field",
        "domain": [
          "full:intranet.example",
          "domain:local.example"
        ],
        "outboundTag": "direct"
      },
      {
        "type": "field",
        "ip": [
          "geoip:private"
        ],
        "outboundTag": "direct"
      },
      {
        "type": "field",
        "protocol": [
          "bittorrent"
        ],
        "outboundTag": "blocked"
      },
      {
        "type": "field",
        "network": "tcp,udp",
        "outboundTag": "remote-vless"
      }
    ]
  }
}

domain 语法与 IP 条件

full: 表示完整域名匹配,适合只处理一个确定主机名;domain: 通常匹配指定域名及其子域范围;regexp: 提供正则表达式能力,但复杂表达式会增加维护成本,且容易把点号、边界或转义写错。没有前缀的写法如何解释应以内核定义为准。规则集标识如 geosite:geoip: 依赖内核可读取的规则数据,名称存在并不等于本地数据一定包含对应条目。

IP 规则既可写单个地址,也可写 CIDR 网段。geoip:private 常用于覆盖私有地址范围,使局域网设备与本机服务不经过远端出站。但域名最终解析到私有地址时,是否进入 IP 规则还受 domainStrategy 影响。如果策略保持 AsIs,路由阶段不会为了匹配 IP 规则主动解析域名;当使用 IPIfNonMatch 时,域名规则未命中后可能继续解析并进行 IP 匹配;更积极的策略则可能更早解析。策略越积极,路由与 DNS 的耦合越明显。

按入站、网络与协议分流

inboundTag 适合把不同本地入口送往不同出站,例如测试入口固定使用一个远端出站,而普通系统代理继续按域名规则处理。它也适合隔离临时实验:新增独立端口和标签,不改动主入口即可验证一组规则。network 可区分 TCP 与 UDP,但远端协议和传输是否完整承载相应网络仍需单独确认。protocol 条件依赖内核识别结果,往往与入站嗅探相关,不应假定所有连接都能被可靠分类。

分流结果与客户端界面中的“全局”“规则”或“直连”等模式有关。界面模式可能切换不同路由模板,也可能改变默认出站,而不是简单修改单条规则。关于三类常见模式的作用范围,可参阅系统代理、全局模式与绕过大陆模式区别详解。调试自定义规则时应固定客户端模式,否则界面切换可能重新生成配置,使手工改动看似无效。

条件 适合表达 常见误区
domain 完整域名、后缀范围、规则集 忽略前缀语义或规则顺序
ip 单个地址、CIDR、IP 规则集 未考虑域名是否会在路由阶段解析
inboundTag 按本地入口隔离路径 引用了不存在或拼写不同的标签
network 区分 TCP 与 UDP 把网络类型当作应用协议类别
05
NAME RESOLUTION

dns 配置、服务器选择与路由联动

DNS 配置决定内核在需要解析域名时向哪些服务器查询,以及特定域名应优先进入哪组解析路径。它与操作系统 DNS、应用自身解析和路由阶段解析并非同一个层面。

先区分查询由谁发起

应用可能先在系统层完成解析,然后只把目标 IP 交给代理;应用也可能把域名原样交给 SOCKS 或 HTTP 入站;部分应用还会使用自己的加密 DNS 机制。只有进入内核并由内核执行的查询,才会直接受顶层 dns 对象控制。因此,修改配置后若观察不到预期变化,应先确认入站接收到的是域名还是 IP,并检查嗅探是否恢复了域名。仅更换 dns.servers 不能强制所有系统程序放弃自己的解析路径。

servers 可以包含简单地址,也可以包含带 addressdomainsexpectIPsskipFallback 等属性的对象。简单数组适合单一路径;对象形式适合按域名选择服务器。服务器列表并非始终按“第一个失败才使用第二个”的传统备用概念工作,域名筛选、回退设置与内核实现会共同决定查询对象。设计复杂 DNS 前,先用两个职责清晰的服务器验证,再加入域名范围和回退限制。

{
  "dns": {
    "hosts": {
      "router.example": "192.168.1.1"
    },
    "servers": [
      {
        "address": "localhost",
        "domains": [
          "full:router.example",
          "domain:internal.example"
        ],
        "skipFallback": true
      },
      {
        "address": "1.1.1.1",
        "domains": [
          "domain:public.example"
        ]
      },
      "8.8.8.8"
    ],
    "queryStrategy": "UseIP"
  }
}

hosts、domains 与预期结果

hosts 用于给明确名称提供静态映射,适合少量稳定的本地服务名称,不适合作为大型动态域名表。静态映射优先级较高,地址变化后若忘记更新,会造成“只有某个名称持续指向旧地址”的现象。排查时应同时检查操作系统 hosts 文件、客户端界面中的主机覆盖项与核心配置中的 dns.hosts,避免多层覆盖彼此冲突。

服务器对象中的 domains 用于筛选交给该服务器的域名,语法与路由域名条件相近,但用途不同:前者选择解析器,后者选择连接出站。expectIPs 可约束期望返回地址的范围,用于判定结果是否符合预设;它不是把任意响应改写成目标范围。约束写得过窄时,正常响应也可能被排除并进入回退。skipFallback 则影响该服务器参与回退的方式,组合使用前应先画出“域名选择—服务器查询—结果检查—连接路由”四步关系。

DNS 查询如何选择出站

DNS 服务器地址本身也需要建立连接。若服务器写为域名,首先还存在解析解析器域名的问题;若写为 IP,则省去这一层,但仍要由路由选择网络出站。较复杂的配置会给 DNS 流量分配标签,再在路由中按该标签或协议送往特定出站。此时必须避免闭环:远端出站依赖域名解析,而该域名解析又被要求通过尚未建立的远端出站完成。

建立可解释路径的方法是先让远端服务器地址具备稳定的基础解析路径,再决定普通目标域名如何分流。若配置中同时使用 domainStrategy 与 DNS 规则,路由为了判断 IP 条件而触发的解析也会进入 DNS 模块。于是一个表面上的路由问题,可能实际由 DNS 服务器筛选或回退结果引起。排查日志时应按时间顺序观察查询、获得地址、选择出站和连接目标,而不是只截取最后一条超时信息。

缓存、IPv4 与 IPv6 选择

queryStrategy 用来限制或偏向查询返回的地址族,支持范围随内核而异。强制只使用一种地址族可能绕开本地网络不完整的问题,但也可能排除本来可达的目标。应先确认操作系统是否具备对应网络连通性,再决定是否限制查询。客户端、内核与系统解析器都可能缓存结果,修改 DNS 后立即重试不一定触发新查询;可以重启相关客户端进程并重新建立连接,但不应把清空缓存当作长期配置方案。

针对“域名无法访问而直接 IP 可以访问”的情况,先核对查询是否返回地址,再检查返回地址是否被路由规则送到预期出站。针对“部分域名偶发失败”,则需要比较失败与成功时选择的 DNS 服务器、地址族和出站标签。更换服务器只能验证解析器路径,不能代替对规则条件的检查。关于常见客户端连接主线与验证方法,可回到入门指南逐步确认。

06
POLICY AND STATS

policy 策略、连接时限与统计开关

policy 不决定流量走哪个节点,而是为用户等级与系统级行为设置连接超时、空闲时间和统计开关。它位于路由选择之外,却会影响长连接的生命周期与可观察性。

level 与 levels 的引用关系

policy.levels 是以用户等级为键的对象。协议用户配置中的 level 数字会引用对应策略;若用户没有显式设置,则通常使用默认等级。等级不是速度评分,也不是权限高低的自动排序,它只是把一组用户连接映射到一组策略参数。把等级从 0 改为 1 不会自动提高性能,只有同时定义 levels["1"] 并设置不同字段时才有实际差异。

客户端作为本地连接发起端时,多数用户只需要默认等级。多等级更常见于需要区分不同入站用户的服务端配置。即使如此,也应以实际管理需求为依据,而不是为每个用户创建一套几乎相同的策略。策略越多,迁移时越容易遗漏引用。检查时先搜索所有 level,再确认 policy.levels 中存在对应键,并注意 JSON 对象键在文本中写成字符串形式。

{
  "policy": {
    "levels": {
      "0": {
        "handshake": 4,
        "connIdle": 300,
        "uplinkOnly": 2,
        "downlinkOnly": 5,
        "statsUserUplink": false,
        "statsUserDownlink": false
      }
    },
    "system": {
      "statsInboundUplink": true,
      "statsInboundDownlink": true,
      "statsOutboundUplink": true,
      "statsOutboundDownlink": true
    }
  },
  "stats": {}
}

握手、空闲与单向连接时限

handshake 控制建立连接初期可等待的时间范围。设置过短会使高负载设备、慢速网络或需要多层握手的连接尚未完成就被关闭;设置过长则会让失败连接占用资源更久。connIdle 用于判断连接在没有活动时保留多久。即时通信、推送、远程终端与流媒体可能具有不同的空闲行为,不能只根据网页浏览测试决定所有长连接的值。

uplinkOnlydownlinkOnly 处理连接只剩单向传输后的生命周期。它们不是上传或下载速率限制,也不会给某一方向分配带宽。如果应用在一段单向传输后被提前断开,应结合这些值检查;若连接在双向均无数据后断开,则更可能与 connIdle 有关。远端服务器、中间网络设备和应用自身也可能主动关闭连接,因此本地 policy 只是排查链的一部分。

统计字段需要完整启用链

statsUserUplinkstatsUserDownlink 控制用户级统计,policy.system 中的字段控制入站和出站方向统计。仅把布尔值设为 true 并不必然让客户端界面显示数据,还需要顶层 stats 对象、相应 API 或客户端读取逻辑配合。反过来,界面没有展示也不能直接推断内核没有统计。应区分“计数器未启用”“计数器存在但没有读取”“读取接口与客户端展示不匹配”三种状态。

统计会带来额外的状态维护,是否启用应根据诊断与管理需求决定。个人桌面配置若不读取统计结果,可以保持简化;需要分析某个入站或出站是否有流量时,可临时启用系统级计数器,并结合日志验证标签。不要把统计值当作连接质量判断的唯一依据:它只能说明经过对应处理器的数据量变化,不能直接解释握手耗时、应用响应或 DNS 选择。

策略修改的验证方式

修改连接时限后,应使用能够稳定复现问题的场景验证。例如保持一条长连接空闲超过原阈值,再发送数据,观察连接是否重建;不要通过快速刷新网页推断空闲策略。若仅某个协议或应用异常,先确认其连接是否真的映射到修改过的用户等级。客户端生成配置时还可能覆盖手工 policy,因此应在运行时配置或日志中核对最终值。

policy 适合解决明确的生命周期与统计需求,不适合用来修正错误路由、错误传输或远端参数。若连接从一开始就无法建立,应回到出站和传输层;若只有特定域名不通,应检查路由与 DNS;若连接建立后在固定空闲阶段断开,再进入策略对象。按照这一顺序可以避免通过放宽超时掩盖真正的握手失败。

07
TRANSPORT LAYER

streamSettings、传输方式与安全参数

远端协议定义身份与请求格式,streamSettings 定义这些数据如何承载在网络连接上。两端协议参数正确但传输层不一致,连接仍无法完成。

network 决定后续设置对象

streamSettings.network 指定传输类型,常见配置可能涉及 TCP、WebSocket、gRPC 或 mKCP。选择某种网络后,应使用与之对应的设置对象,例如 WebSocket 使用 wsSettings,gRPC 使用对应服务名称设置。把另一个传输的字段保留在配置中通常不会把两者自动组合,反而会造成阅读误判。迁移节点时应先确认界面显示的传输类型,再展开其专属字段逐项核对。

传输类型不是可以由客户端单方面优化的选项。服务端监听什么传输、使用什么路径或服务名称,客户端就必须按相同结构连接。遇到错误时频繁在 TCP、WebSocket 与 gRPC 之间切换,通常只会增加变量。较稳妥的做法是根据来源配置固定传输类型,检查地址是否可解析、端口是否可达,然后再检查路径、主机字段与安全层。

{
  "streamSettings": {
    "network": "grpc",
    "security": "tls",
    "tlsSettings": {
      "serverName": "edge.example.com",
      "allowInsecure": false,
      "alpn": ["h2"]
    },
    "grpcSettings": {
      "serviceName": "example-service",
      "multiMode": false
    },
    "sockopt": {
      "tcpKeepAliveIdle": 100
    }
  }
}

WebSocket 路径、Host 与 TLS 名称

WebSocket 配置中的 path 是 HTTP 握手路径,是否带前导斜线、是否包含查询部分,都应与服务端入口一致。headers.Host 属于 WebSocket 握手头,而 tlsSettings.serverName 用于 TLS 服务器名称验证,两者可能相同,也可能因部署结构而不同。将它们视为一个字段同步替换,可能让其中一层通过而另一层失败。

服务器地址 address 决定最初连接到哪个主机,TLS 名称决定证书与握手所针对的名称,WebSocket Host 则由 HTTP 层处理。排查时应按连接建立顺序理解这三者。若地址可以建立 TCP 连接但 TLS 失败,重点检查系统时间、服务器名称和安全参数;若 TLS 成功后 WebSocket 被拒绝,则继续检查路径和 Host。单纯把证书验证选项改为宽松值会降低错误可见性,不应作为常规修复。

gRPC、mKCP 与传输专属字段

gRPC 配置通常需要准确的 serviceName,并依赖 HTTP/2 相关协商。服务名称是配置值,不是节点备注,也不应自行添加 URL 形式的斜线。若中间层不支持所需连接方式,表现可能是握手后立即关闭。mKCP 属于基于 UDP 的传输,除双方参数外,还依赖当前网络是否能稳定承载 UDP;TCP 可达不能证明 UDP 路径也可达。

传输专属参数数量较多时,应优先使用客户端按节点信息生成的结构,再针对明确需求修改。互联网上跨内核、跨时期的示例可能包含已经调整的字段名称。v2rayN 通常搭配桌面端核心管理,v2rayNG 使用 Xray 内核路径,v2flyNG 则面向 V2Fly 内核;同名传输的基础概念相近,但扩展字段未必完全一致。无法确认支持范围时,先删除非必要扩展并保留服务端要求的核心字段。

security、TLS 与 Reality 的层级

security 决定启用的安全层,对应设置对象必须与其一致。TLS 参数放在 tlsSettings,Reality 参数使用内核规定的独立设置对象。两类配置不能仅替换 security 字符串而沿用全部旧字段。服务器名称、公钥类参数、短标识及指纹类选择都属于特定安全方式的握手条件,必须来自同一份有效配置。

安全层错误与用户标识错误在界面上都可能表现为连接测试失败,因此日志阶段需要区分 DNS、TCP、TLS 或协议认证发生在哪一步。若连服务器端口都无法建立连接,继续修改服务器名称没有意义;若 TCP 已建立但安全握手失败,则不要先改路由规则。把故障定位到层级之后再改参数,可以防止一项改动暂时改变报错形式,却没有解决根因。

层级 代表字段 需要与远端一致的内容
目标连接 addressport 主机与监听端口
传输 network 传输类型、路径或服务名称
安全层 security 服务器名称及对应握手参数
应用协议 protocolsettings 用户标识与协议属性
08
VALIDATION WORKFLOW

配置验证与故障排查的分层方法

有效排错不是连续更换参数,而是确认连接经过了哪一层、在哪一层停止。结构、监听、解析、路由、出站与应用设置应按固定顺序检查。

第一层:确认 JSON 能被读取

启动失败时先查看客户端或核心日志的第一条结构错误,记录行号与字段路径。常见问题包括缺少逗号、括号类型不匹配、字符串未闭合、字段放错对象、数字写成字符串,以及标准 JSON 中出现注释。编辑器提示的错误位置有时位于真正错误的下一行,因为解析器直到读到后续字符才确定前一项不完整。因此,应同时检查报错行之前的对象结尾。

结构合法并不表示字段语义合法。一个拼写正确的 JSON 可以包含内核不认识的字段、错误协议设置或不存在的标签。此时应根据日志中的对象路径回到对应章节,核对该字段属于入站、出站还是传输设置。若客户端每次启动都会重写配置,说明编辑的是生成产物;应回到客户端界面或其自定义配置入口修改源设置。第一次使用客户端的完整操作顺序见入门指南

{
  "log": {
    "access": "",
    "error": "",
    "loglevel": "warning"
  }
}

第二层:确认连接进入正确入站

配置加载后,检查本地监听地址和端口是否出现。应用代理地址必须与入站一致,SOCKS 与 HTTP 类型也不能混用。系统代理已开启但应用仍直连时,应确认该应用是否读取系统设置;反过来,客户端已经关闭系统代理但浏览器扩展仍保留独立代理时,流量仍可能进入旧端口。排错期间只保留一种入口方式,能显著减少重复代理与路径不明的问题。

若端口没有监听,先检查是否被占用、客户端核心是否启动、配置是否被另一个进程读取。若端口存在但日志完全没有访问记录,问题通常在应用到入站之间。若日志已经记录目标地址,则入口成立,可以继续看路由和出站。移动端还要确认 VPN 服务状态与分应用代理范围;被排除的应用不会经过 v2rayNG 或 v2flyNG 的内核路径。

第三层:沿 DNS、路由和出站标签追踪

对一个固定测试域名发起请求,依次记录内核是否拿到域名、是否触发解析、命中了哪条路由、选择了哪个出站。只有域名失败而 IP 成功时,重点查看 DNS 与域名规则;所有目标都进入错误出站时,重点查看宽泛规则和默认路径;特定应用失败时,比较其入站标签、网络类型和嗅探结果。不要同时使用多个不断变化的测试网站,否则缓存、地址族和域名规则差异会引入额外变量。

若路由命中正确而远端出站失败,再检查地址解析、端口可达性、协议用户参数、传输类型与安全层。日志级别可在排错期间适度提高,但记录完成后应恢复到适合日常使用的级别,避免大量日志掩盖关键事件。日志内容可能包含目标域名、内部地址与本地路径,分享片段前应删去与问题无关的个人配置数据。

第四层:区分客户端状态与核心状态

v2rayN、v2rayNG 与 v2flyNG 都包含客户端管理层,核心只是其中负责处理连接的一部分。订阅更新成功说明客户端获取并解析了订阅,不说明其中每个节点都能连接;延迟测试失败也不一定等同于所有应用连接失败,因为测试方法、目标地址和实际应用协议可能不同。应把“订阅是否更新”“节点是否被选中”“核心是否启动”“系统或 VPN 入口是否启用”“实际请求是否通过”分开判断。

v2rayN 的 Avalonia 桌面版覆盖 Windows、macOS 与 Linux,WPF 版仅用于 Windows,两条发行线的界面与系统集成存在差异。需要选择桌面版本时,可参考v2rayN 桌面版与 WPF 版对照。Linux 的安装与登录会话启动设置则可查阅Linux 安装 v2rayN 步骤。平台差异主要影响客户端外层操作,不应据此随意改变节点协议参数。

建立可回退的修改记录

每轮只改变一个逻辑层,并保存修改前的可用副本。可按“结构整理、入站、DNS、路由、出站、传输、策略”的顺序命名本地记录,同时写下预期结果与实际日志。若一次修改包含多个字段,即使连接恢复,也无法确认哪个字段是真正原因,后续迁移容易再次出现同类问题。恢复配置时应整体恢复同一轮版本,避免把旧路由与新标签混合。

对于订阅管理的节点,应优先在客户端提供的编辑入口中调整,并了解订阅更新是否会覆盖本地修改。需要长期保留的路由和 DNS 规则宜放入客户端支持的自定义配置层,而不是反复修改临时运行文件。配置规模增大后,还应定期删除未被引用的标签、重复规则与过期实验入站,使日志中的每个路径都能对应到当前用途。

01解析JSON 与字段位置
02监听地址、端口与入口
03解析域名DNS 与地址族
04命中规则顺序与标签引用
05建立出站协议、传输与安全层

从参考配置回到客户端操作

当最小配置能够工作后,再依次恢复域名规则、DNS 分流、多个出站与策略设置,每恢复一组就重复固定测试。若问题只在恢复某组后出现,检查范围便收敛到该组及其引用对象。需要重新安装或切换客户端时,请从客户端下载页按 Windows、macOS、Android、Linux 选择对应入口;下载页中的常见问题区也整理了安装包选择、处理器架构与版本切换说明。

配置文件是一组彼此引用的声明,不是孤立参数集合。入站标签影响路由条件,路由策略可能触发 DNS,DNS 查询又需要出站,传输安全层最终决定远端连接能否建立。按依赖链阅读,能够把“无法连接”拆成可验证的结构问题、入口问题、解析问题、规则问题或握手问题。完成一次有记录的分层排查后,同样的方法可以复用于后续节点迁移与客户端升级,而不必重新从随机改动开始。