config.json · Xray / V2Fly 内核

V2Ray 配置文件参考

一份 config.json 的逐段说明:顶层结构、入站与出站、路由规则、DNS 解析、策略调优,以及这些字段在 v2rayN 与 v2rayNG 里是怎么生成的。片段可直接作为查阅对照。

  • 适用客户端:v2rayN / v2rayNG / v2flyNG
  • 覆盖:结构 · 入站 · 出站 · 路由 · DNS · 策略
  • 最后更新:2026-09

使用说明与阅读路径

本页与教程页的分工

本页是 V2Ray 配置文件的系统查阅手册,按字段讲解一份 config.json 从顶层结构到各功能段该怎么写。站内另有快速上手教程,那条主线只做一件事:把订阅导入客户端、选好模式、连上、确认可用。两者分工明确——教程页回答「下一步点哪里」,本页回答「这个字段是什么含义、写成什么值合法、写错会怎样」。已经能正常连接、只想日常使用的用户,不需要读完本页。

配置文件在链路里的位置

三款客户端都是图形外壳,真正建立连接的是它们内置的内核。v2rayN 桌面版内置 Xray 内核,v2rayNG 使用 Xray,v2flyNG 使用 V2Fly 内核。图形界面上勾选的每一项——传输方式、TLS、多路复用、分流开关——最终都会被翻译成一份 JSON 配置,内核启动时读取这份 JSON,按里面的 inbounds 监听本地端口,按 outbounds 把流量发出去。理解这层翻译关系以后,排查问题时就能先判断:是界面上的选项没选对,还是生成的配置本身有问题。

三款客户端对手改配置的支持

v2rayN 在节点编辑窗口里提供完整 JSON 编辑入口,订阅导入的节点会先被解析成内部结构,再由客户端按当前设置重新生成配置;v2rayNG 支持自定义配置与订阅导入,但在移动端编辑长 JSON 不方便,更常见的做法是在桌面端整理好再导入;v2flyNG 与 v2rayNG 的配置格式同源,差别在内核家族。三款客户端的下载入口都在获取客户端页面,横向差别见横向评测

建议的阅读顺序

第一次接触配置文件的用户,先读第二章的结构总览,建立「顶层有哪些段、哪两段必需」的整体印象;之后按需要跳到具体章节。日常使用中出现频率最高的三段是 outbounds、routing 和 dns:出站决定流量怎么出去,路由决定哪些流量走哪个出站,DNS 决定域名在哪里解析。policy 属于调优项,默认值对多数场景够用,只在需要控制内存占用或连接回收时间时才细看。

字段与内核版本的关系

配置格式在不同内核版本之间有小幅演进,新传输方式和新安全类型通常先在 Xray 侧落地,V2Fly 侧跟进。本页示例以通用字段为主,不绑定具体版本号。判断某个字段在当前客户端里是否可用,可靠做法是看运行日志:内核不认识的字段会在启动日志里报错或给出忽略提示,而不是静默生效。

关于示例值

本页所有配置片段里的域名、UUID、公钥都使用明显可替换的示例写法,不要直接照抄进实际配置。节点参数以服务提供方给出的信息为准。页面顶部的章节条可以跳到任意一章,每章内部按小节展开:表格用于字段速查,代码块用于完整片段,带底色的提示块用于容易踩的坑。

JSON 结构总览

顶层有哪些段

一份完整的配置文件是一个 JSON 对象。顶层常见的段落有九个:log 负责日志,inbounds 定义本机监听入口,outbounds 定义流量出口,routing 定义分流规则,dns 定义解析策略,policy 定义连接与缓冲策略,stats 与 api 供图形客户端读取运行状态,reverse 用于反向代理场景。其中 inbounds 与 outbounds 是必需的两段:没有入站,应用流量进不来;没有出站,流量发不出去。

下面这份最小配置只保留了必需项和一个日志段,可以用来理解结构,但它只做直连,不具备代理能力:

{
  "log": { "loglevel": "warning" },
  "inbounds": [
    {
      "tag": "socks-in",
      "listen": "127.0.0.1",
      "port": 10808,
      "protocol": "socks",
      "settings": { "udp": true }
    }
  ],
  "outbounds": [
    { "tag": "direct", "protocol": "freedom" }
  ]
}

字段命名与语法纪律

JSON 对语法很严格,配置文件里最常见的启动失败都来自下面这几条。字段名大小写敏感,outbounds 写成 outBounds、streamSettings 写成 streamsettings 都会解析失败;标准 JSON 不允许注释,从网页或笔记里复制配置时,行内的双斜线注释和块注释必须删掉;不允许尾随逗号,数组或对象的最后一项后面多一个逗号就会报错;字符串一律用双引号,不能用单引号;端口、超时这类数值直接写数字,不要加引号;布尔值只有小写 true 和 false。

tag 的作用

每个入站、出站都可以带一个 tag 字段。tag 是自定义字符串,routing 规则通过 tag 引用具体的入站或出站——比如「来自 socks-in 的流量走 proxy 出站」。tag 建议用能读懂的名字,如 socks-in、http-in、proxy、direct、block,方便几个月后回看配置时还能对得上。同一个配置里 tag 不要重复,重名会让规则指向不明确。

顶层字段 作用 是否必需 常见写法
log 日志级别与输出位置 可选 {"loglevel":"warning"}
inbounds 本机监听入口 必需 数组,至少一项
outbounds 流量出口 必需 数组,第一项为默认出站
routing 分流规则 可选 {"domainStrategy":"IPIfNonMatch","rules":[]}
dns 域名解析策略 可选 {"servers":[]}
policy 连接与缓冲策略 可选 {"levels":{"0":{}}}
stats / api 统计与本地接口 可选 图形客户端按需生成

加载与生效方式

内核在启动时一次性读取配置。改动配置后需要重启内核或触发重载,图形客户端一般在保存节点后自动完成这一步。配置错误有两种表现:一种是解析失败,内核直接退出,日志里会给出出错位置;另一种是字段合法但语义冲突,内核能启动,但连接行为与预期不符,例如路由规则顺序写反导致分流不生效。前者好定位,后者要靠对照日志逐段排除。

与订阅的关系

订阅里的每个节点最终都会被展开成一份这样的配置。客户端为每个节点生成独立的 outbounds 条目,再补上入站、路由和 DNS 段,拼成内核能读的完整文件。所以订阅更新时,客户端是按整份配置重新生成的,手工改过的字段会被覆盖,这一点在后面的客户端章节会展开讲。

不同客户端存放配置文件的位置不同,桌面端通常在程序目录或用户配置目录下,Android 端由应用内部管理。日常使用不需要关心具体路径,只有在导出配置做备份或迁移时才需要找到它。

inbounds 入站

入站做什么

入站描述内核在本机监听什么,是应用流量进入内核的入口。图形客户端通常自动生成两项:socks 入站给浏览器和系统代理使用,http 入站给只支持 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"],
      "routeOnly": false
    }
  },
  {
    "tag": "http-in",
    "listen": "127.0.0.1",
    "port": 10809,
    "protocol": "http"
  }
]

字段逐个说明

tag
入站的标识名,供路由规则引用。同一份配置里不要重复。
listen
监听地址。127.0.0.1 只允许本机访问;0.0.0.0 允许同一网络下的其他设备接入。
port
监听端口。与系统里其他程序冲突时内核启动失败,日志提示监听失败。
protocol
入站协议,常见取值 socks、http、dokodemo-door。
settings
协议相关参数。socks 的 udp 决定是否转发 UDP 流量;http 入站一般不需要额外设置。
sniffing
从流量里识别真实目标域名。destOverride 指定允许覆盖的协议类型,routeOnly 为 true 时只用于路由判断,不改写目标地址。

为什么需要 sniffing

当应用通过 socks 把目标地址传过来时,传的有可能是 IP 而不是域名。一旦目标以 IP 形式出现,routing 里所有基于域名的规则都会失效,分流自然不准。开启 sniffing 后,内核会从 TLS 握手的 SNI、HTTP 请求头的 Host 里把真实域名提取出来,再拿这个域名去匹配路由规则。destOverride 列出允许被覆盖的协议类型,常见写法是 http 与 tls;routeOnly 设为 true 时,提取出的域名只用于路由判断,不改写实际请求的目标地址,适合需要保持原始请求形态的场景。桌面端与移动端客户端默认都会开启嗅探。

dokodemo-door 说明

dokodemo-door 是另一类入站,作用是把某个本地端口收到的流量原样转发到指定目标,常用于把局域网设备或某个固定端口的请求接入内核。它在图形客户端里没有对应的开关,属于手写配置的范畴,需要自己指定 address 与 port。

入站协议 用途 典型出现位置
socks 浏览器与系统代理的标准入口 v2rayN、v2rayNG 默认生成
http 只支持 HTTP 代理的程序 v2rayN 默认生成
dokodemo-door 端口转发与局域网接入 手动配置

监听地址的安全边界

listen 写 127.0.0.1 时只有本机能访问这个端口,这是默认做法。改成 0.0.0.0 后,同一网络下的其他设备可以直接把代理指向这台机器,适合明确需要共享代理的场景,但要求网络环境可信。图形客户端里对应的选项一般写作「允许来自局域网的连接」,打开前先确认这一点。代理端口本身不做身份验证时,任何能访问到该端口的设备都可以直接使用。

端口被占用

入站端口被占用时,内核启动失败并在日志里提示监听失败。处理方式有三种:改入站端口;找出占用端口的进程并结束它;如果占用方是上一个没退干净的内核进程,重启客户端即可。改端口后记得同步更新系统代理或浏览器代理的设置,否则应用仍然把请求发到旧端口。

outbounds 出站

出站做什么

出站决定流量离开内核之后怎么走。outbounds 是一个数组,里面可以有多个条目,每个带自己的 tag。数组的第一项是默认出站,没有命中任何路由规则的流量走它。下面是一份 VLESS 出站示例,传输层使用 TCP 配合 REALITY:

"outbounds": [
  {
    "tag": "proxy",
    "protocol": "vless",
    "settings": {
      "vnext": [
        {
          "address": "node.example.com",
          "port": 443,
          "users": [
            {
              "id": "00000000-0000-0000-0000-000000000000",
              "encryption": "none",
              "flow": "xtls-rprx-vision"
            }
          ]
        }
      ]
    },
    "streamSettings": {
      "network": "tcp",
      "security": "reality",
      "realitySettings": {
        "serverName": "node.example.com",
        "fingerprint": "chrome",
        "publicKey": "your-public-key",
        "shortId": "your-short-id"
      }
    },
    "mux": { "enabled": false }
  },
  { "tag": "direct", "protocol": "freedom" },
  { "tag": "block", "protocol": "blackhole" }
]

服务器参数

vnext 数组描述远端服务器,每项包含 address、port 和 users。address 可以写域名也可以写 IP;port 是服务端监听端口。users 里的 id 是身份标识,VMess 与 VLESS 都用 UUID 形式。VLESS 的 encryption 字段固定写 none,加密交给传输层处理;VMess 的 alterId 在新版里默认 0,老节点如果还要求非零值,填错会直接连接失败。flow 是 VLESS 的流控选项,与传输层安全类型搭配使用,tcp 传输配合 TLS 或 REALITY 时常见写法是 xtls-rprx-vision。

传输层参数

network
传输方式。常见取值 tcp、ws、grpc、httpupgrade,必须与服务端一致。
security
传输层安全类型。none 表示不加密,tls 表示标准 TLS,reality 表示 REALITY。
wsSettings
WebSocket 专用参数,path 是请求路径,headers.Host 是请求头里的主机名。
tlsSettings
TLS 专用参数,serverName 是证书对应的域名,allowInsecure 跳过证书校验,不建议长期打开。
realitySettings
REALITY 专用参数,serverName、publicKey、shortId 三项必须与服务端完全一致,fingerprint 决定客户端指纹的呈现方式。

下面这段是 WebSocket 配合 TLS 的传输层写法,与上面的 REALITY 示例属于同一层级,替换 streamSettings 整段即可:

"streamSettings": {
  "network": "ws",
  "security": "tls",
  "wsSettings": {
    "path": "/your-path",
    "headers": { "Host": "node.example.com" }
  },
  "tlsSettings": {
    "serverName": "node.example.com",
    "allowInsecure": false
  }
}

VMess 出站的差别

VMess 出站的结构与 VLESS 相同,差别在 users 里的字段:VMess 用 alterId 与 security 两个字段描述加密方式,前者在新版里默认 0,后者常见写法 auto。传输层参数与 VLESS 完全通用,同一个服务端如果同时提供两种协议,切换时只需要改 protocol 和 users 这两处。VMess 与 VLESS 在身份验证与传输依赖上的差别,在协议科普里有四点对照。

mux 多路复用

mux 是多路复用开关。开启后,内核把多条连接合并到一条底层连接上,减少重复握手,在网络状况稳定的链路上能降低延迟;代价是单条连接的质量会互相影响,大文件下载这类持续高吞吐的场景反而可能变慢。客户端默认关闭,按需开启即可。

freedom 与 blackhole

freedom 是直连出站,收到什么就原样发出去,常配合路由规则处理国内域名和私有地址。它有一个 sendThrough 字段,可以指定从本机哪个地址发出。blackhole 是丢弃出站,用来拦截特定流量,可以配置返回内容。两者都不需要服务器参数,写一个 tag 就能用。

出站协议 用途 备注
vless 主推的代理出站 无内置加密,依赖传输层安全类型
vmess 兼容早期节点 alterId 新版默认 0
freedom 直连 可指定本机出口地址
blackhole 拦截与丢弃 可配置返回内容

传输参数必须逐项对齐

路径、Host、SNI、公钥、shortId 这些参数必须与服务端完全一致,任何一处对不上都会表现为连接建立后立刻断开,而不是给出明确的错误提示。排查时优先怀疑复制过程中多出的空格或缺失的斜线。

routing 路由规则

规则怎么生效

routing 决定哪些流量走哪个出站。结构由 domainStrategy 和 rules 两部分组成。规则自上而下依次匹配,第一条命中的规则生效,后面的规则不再判断——所以规则的顺序比条数更重要。rules 数组里每一项都是一个对象,type 固定写 field,其余字段描述匹配条件与命中后的动作。

domainStrategy 的三个取值

AsIs
按传入的域名或 IP 原样匹配,不做解析。速度最快,但纯 IP 形式的请求无法命中域名规则。
IPIfNonMatch
域名规则没命中时,把域名解析成 IP 再匹配一次 IP 规则。日常使用最常见的取值。
IPOnDemand
只要规则里出现 IP 条件就立即解析。判断最完整,解析开销也最大。

规则条件字段

条件字段 写法示例 说明
domain ["domain:example.com"] 按域名匹配,支持多种前缀写法
ip ["geoip:private"] 按目标 IP 或 IP 段匹配
port "443" 或 "0-65535" 按目标端口匹配,支持区间
sourcePort "1-65535" 按来源端口匹配
inboundTag ["socks-in"] 按流量来自哪个入站区分
network "tcp" 或 "udp" 按传输层协议区分
protocol ["http","tls"] 依赖嗅探结果,需要先开启 sniffing
outboundTag "direct" 命中后的动作:走哪个出站
balancerTag "auto" 命中后的动作:走负载均衡

域名匹配的四种前缀

domain:
匹配该域名及其所有子域。domain:example.com 同时匹配 example.com 与 a.example.com。
full:
精确匹配。full:example.com 只匹配 example.com,不含子域。
keyword:
包含关键词即命中。范围最宽,容易误伤,只在前两种写不出来时使用。
regexp:
正则匹配。写法灵活,但每条请求都要跑一次正则,规则多了会拖慢判断。

下面是一份可直接使用的分流片段:私有地址与国内域名直连,UDP 443 端口拦截,其余流量走默认出站。

"routing": {
  "domainStrategy": "IPIfNonMatch",
  "rules": [
    {
      "type": "field",
      "domain": ["geosite:private"],
      "outboundTag": "direct"
    },
    {
      "type": "field",
      "ip": ["geoip:private"],
      "outboundTag": "direct"
    },
    {
      "type": "field",
      "domain": ["geosite:cn"],
      "outboundTag": "direct"
    },
    {
      "type": "field",
      "network": "udp",
      "port": "443",
      "outboundTag": "block"
    }
  ]
}

顺序写反的典型后果

举一个顺序写反的例子:第一条规则写「所有流量走 proxy」,第二条写「国内域名直连」。因为第一条已经命中了全部流量,第二条永远不会被判断,分流效果等于没有。正确写法是把具体条件放在前面、宽泛条件放在后面,最后再加兜底规则。判断顺序问题时,把日志级别临时调到 debug,内核会打印每条连接的匹配结果,能直接看到命中的是哪一条。

geosite 与 geoip 数据

geosite:cn、geoip:private 这类写法依赖客户端内置或下载的规则数据文件。数据有更新周期,新出现的域名可能还没被收录,表现为个别网站的分流结果不符合预期。图形客户端一般在路由设置里提供数据更新入口,定期更新一次即可。私有地址段的数据很少变动,不需要频繁更新。

balancer 简述

balancer 用于在多个出站之间分发流量,规则里用 balancerTag 引用。它需要先定义 balancer 段,用 selector 按 tag 前缀挑选出站,再指定分发策略。普通用户很少需要,只有维护多个等价节点时才用得上。

路由不生效时的检查顺序

依次确认:sniffing 是否开启,域名规则依赖它;目标是否以 IP 形式传入,IP 形式命中不了域名规则;规则顺序是否被更宽的条件挡住;规则数据文件是否需要更新。四项都正常时再看日志里的实际匹配记录。

dns 配置

写与不写 dns 段的差别

dns 段决定内核如何解析域名。不写这段时,内核把解析交给系统;写了之后,内核按配置里的服务器列表和策略自己发出查询。写这段的价值有三点:避免解析结果被中间环节干扰、让基于域名的分流更准确、减少一次多余的解析往返。下面是常用字段的完整写法:

"dns": {
  "hosts": {
    "domain:node.example.com": "203.0.113.10"
  },
  "queryStrategy": "UseIPv4",
  "servers": [
    {
      "address": "223.5.5.5",
      "domains": ["geosite:cn"],
      "expectIPs": ["geoip:cn"]
    },
    {
      "address": "1.1.1.1",
      "domains": ["geosite:geolocation-!cn"]
    }
  ]
}
servers
DNS 服务器列表。元素可以只写地址字符串,也可以写成对象,用 domains 指定该服务器负责哪些域名,用 expectIPs 校验返回结果是否落在预期网段内。
hosts
静态映射,把域名直接指向固定 IP,跳过解析这一步。支持 domain:、full:、keyword: 前缀,写法与路由规则一致。
queryStrategy
控制优先解析出的地址族。UseIP 不限制,UseIPv4 与 UseIPv6 分别只保留对应地址族。
domains
写在服务器对象里,限定这条服务器只处理哪些域名。上面示例里第一条负责国内域名,第二条负责其余域名。
expectIPs
对返回结果做一次校验,解析出的地址不落在指定网段内就丢弃。用于防止解析结果被替换。

hosts 的用途

hosts 是静态映射,把域名直接指向固定 IP,解析这一步就省掉了。它适合两种场景:节点域名已知且稳定,想跳过解析;测试环境里需要把某个域名固定到指定地址。写法上支持 domain:、full:、keyword: 前缀,与路由规则的域名写法完全一致,不需要额外记忆。

queryStrategy 怎么选

queryStrategy 控制优先解析出的地址族。UseIP 表示不限制,按服务器返回的顺序;UseIPv4 和 UseIPv6 分别只保留对应地址族。在只有 IPv4 出口的环境里写 UseIPv4,可以避免解析出 IPv6 地址后又因为无法连接而重试,少一次失败往返。反过来,如果本机网络已经以 IPv6 为主,写 UseIPv6 能减少不必要的双栈查询。

与路由的配合

DNS 查询由内核自己发出,不经过 outbounds 里的代理链路,因此不需要为解析单独写路由规则。需要留意的是解析结果会影响路由:如果开启了 IPIfNonMatch,域名会先被解析成 IP 再匹配 IP 规则,解析结果不准,IP 规则就会跟着不准。这也是把 dns 段和 routing 段放在一起看的原因。

不同模式下谁在解析

桌面端使用系统代理时,域名解析仍由操作系统完成,内核的 dns 段只在内核需要自己解析时起作用;开启 TUN 模式后,内核接管全部流量,包括 DNS 请求。Android 上的 v2rayNG 通过 VpnService 工作,同样会接管 DNS 查询。所以同一份 dns 配置在不同客户端、不同模式下的实际影响范围并不相同,判断效果时要先确认当前处在哪种模式。

解析结果与分流的关系

分流不准时,先分清是域名规则没生效还是 IP 规则没生效。前者多半与嗅探有关,后者多半与解析结果有关。把这两类原因分开,排查范围会小很多。

policy 策略

什么时候需要写 policy

policy 控制连接的生命周期与缓冲区大小,属于调优项。默认值对普通使用足够,写它的典型场景有三个:降低内存占用、加快空闲连接的回收、给不同入站设置不同限制。下面是一份常见写法:

"policy": {
  "levels": {
    "0": {
      "handshake": 4,
      "connIdle": 300,
      "uplinkOnly": 2,
      "downlinkOnly": 5,
      "bufferSize": 512
    }
  },
  "system": {
    "statsInboundUplink": true,
    "statsInboundDownlink": true
  }
}
字段 单位 作用
handshake 握手阶段的超时时间,超过即判定失败
connIdle 连接空闲多久后被回收
uplinkOnly 下行关闭后保留上行的时间
downlinkOnly 上行关闭后保留下行的时间
bufferSize KB 单连接缓冲区大小,0 表示不使用缓冲区

levels 的用法

levels 的键是等级编号,0 是默认等级。入站的 settings 或用户配置里可以指定 level 字段,把某个入站或某个用户归到特定等级,实现按入口分别限流。日常使用只改 0 这一档就够了,给不同入口分配不同等级属于多用户场景下的做法。

system 段

system 段控制统计开关。statsInboundUplink 与 statsInboundDownlink 打开后,内核会统计入站方向的上下行流量,图形客户端的速率显示依赖这些数据;statsOutboundUplink 与 statsOutboundDownlink 对应出站方向。关闭统计可以省下一点开销,代价是界面上的流量数字不再更新。

调优的取舍

降低 connIdle 会让空闲连接更快被回收,内存占用随之下降,代价是再次使用时需要重新建立连接,表现上会多一次握手延迟。bufferSize 调大对高带宽场景有帮助,调小则省内存。handshake、uplinkOnly、downlinkOnly 一般不需要调整,只有在网络质量较差、握手经常超时的环境里才考虑放宽 handshake。

移动端的特殊情况

移动端上后台连接被系统回收,通常与 policy 无关,而是省电策略在起作用。相关处理方式在v2rayNG 使用要点里说明。调优的前提是先有稳定的基准,建议保留一份默认配置,改动后逐项对比,确认收益真实存在再保留。网上流传的参数组合大多针对特定硬件和特定场景,直接照搬未必带来改善。

客户端里的配置生成与手改

订阅是怎么展开成配置的

订阅地址返回的是一段经过编码的文本,客户端下载后逐行解析,每一行描述一个节点的完整参数,再把参数翻译成 outbounds 里的一个条目。订阅里的节点数量对应 outbounds 数组的长度,订阅更新时整份配置重新生成。理解这条链路以后,就能明白为什么在界面里改过的节点会在更新后回到原样。

分享链接参数与配置字段的对应

链接参数 对应配置字段 说明
add / address vnext[].address 服务器地址
port vnext[].port 服务器端口
id / uuid users[].id 身份标识
flow users[].flow 流控选项,仅 VLESS 使用
net streamSettings.network 传输方式
tls streamSettings.security 安全类型
host wsSettings.headers.Host WebSocket 请求头主机名
path wsSettings.path WebSocket 请求路径
sni tlsSettings.serverName TLS 域名
type tlsSettings.fingerprint 客户端指纹呈现方式

v2rayN 里的编辑入口

v2rayN 的节点列表右键菜单里有编辑入口,窗口按基础字段和传输字段分组。需要改客户端界面没有暴露的字段时,可以在参数设置里找到完整配置编辑入口。要注意订阅更新是按订阅整体替换节点列表的,手工改过的节点在下次更新后会被覆盖;需要长期保留的调整,建议另存为独立节点或先导出备份。

v2rayNG 的配置来源

v2rayNG 的节点来源有三种:扫码、从剪贴板导入分享链接、订阅导入。移动端编辑长 JSON 不方便,常见做法是在桌面端整理好再导入。分应用代理在设置里按应用勾选,只决定哪些应用的流量进入 VpnService,与 JSON 配置本身无关——也就是说,分应用代理的规则不会出现在 config.json 里。

v2flyNG 的定位

v2flyNG 与 v2rayNG 的配置格式同源,差别在内核家族。同一个节点的参数在两边都能用,当某个内核版本对特定传输方式的支持有差异时,备选客户端可以作为对照。三款客户端的平台与版本入口见获取客户端页。

什么情况值得手改配置

三种场景值得手改:客户端界面没有暴露某个字段,例如自定义路由规则、bufferSize;需要按应用或按端口单独分流;排查问题时想用最小配置复现。前两种建议在桌面端完成,改完导出再同步到移动端。第三种场景下手写的配置越短越好,只保留复现问题必需的段落。

订阅格式的更多细节

订阅有三种常见形态:base64 编码的链接列表、原生 JSON 配置、以及单条分享链接。三者的差别与转换时容易丢字段的地方,在订阅格式科普里有逐项对照。导入失败时,先确认订阅返回的是哪一种形态,再决定用哪个入口导入。

排错与日志

先把日志打开

排查任何配置问题之前,先确认日志是打开的。log 段的写法如下:

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

loglevel 从详细到简略依次是 debug、info、warning、error、none。排查问题时临时改成 debug,日志会打印路由匹配结果、连接建立过程等细节,用来确认某条规则是否命中;问题解决后改回 warning,避免日志文件快速膨胀。access 与 error 留空表示输出到控制台,图形客户端会把这些输出重定向到界面里的日志面板。

按现象定位

现象 优先检查
内核启动失败,日志报解析错误 JSON 语法:注释、尾随逗号、字段名大小写
启动成功但浏览器打不开网页 入站端口与系统代理设置是否一致
日志提示监听失败 端口是否被其他程序占用
连接建立后立刻断开 传输参数与服务端是否逐项对齐
只有部分应用走代理 分应用代理设置与系统代理范围
域名分流不生效 嗅探是否开启、规则数据是否需要更新

JSON 语法自查顺序

解析失败时日志会给出出错的行号,先看那一行附近有没有全角标点——中文引号、中文逗号、中文括号是从网页复制配置时最常见的问题;其次看有没有尾随逗号;最后确认字段名拼写与大小写。三步都过了还是报错,就把配置逐段注释掉一半再试,用二分法定位到具体段落。

字段名与版本

内核只认识它定义过的字段。多余的字段会被忽略或直接报错,不同内核版本对同一字段的处理也可能不同。客户端升级后如果出现原本正常的配置报错,先对照更新说明确认字段是否变化,而不是反复改参数。手写配置时保留一份能正常工作的备份,出问题时可以快速回退。

按失败阶段读日志

日志里的错误信息可以按阶段分类:拨号阶段失败通常指向地址、端口或传输参数;握手阶段失败指向安全类型、证书或公钥;解析阶段失败指向 DNS 配置。三个阶段的错误信息形态不同,分清阶段能少走很多弯路。debug 级别的日志会明确写出连接尝试的目标与结果,对照配置逐项核对即可。

一次只改一个参数

同时改多个参数再测试,即使问题解决了也不知道是哪一个改动起了作用。一次改一处、改完立即验证,是配置调试里最省时间的做法。

订阅更新失败与配置无关

订阅更新失败与配置本身关系不大,更多是订阅地址、更新间隔或本地网络状态的问题,排查顺序在订阅更新失败排查里逐项列出。区分方法是看日志:配置问题会在内核启动阶段报错,订阅问题只影响节点列表的刷新,不影响已经导入的节点继续使用。

回到主线

配置文件的行为最终以日志为准。遇到本页没有覆盖的字段,可以在客户端里用最小配置逐项添加,观察日志变化,这比一次写完整份配置再调试要快得多。需要重新走一遍基础流程时,回到快速上手教程;需要确认客户端版本与平台入口时,见获取客户端;需要了解三款客户端的横向差别时,见横向评测