config.json · Xray / V2Fly 内核
V2Ray 配置文件参考
一份 config.json 的逐段说明:顶层结构、入站与出站、路由规则、DNS 解析、策略调优,以及这些字段在 v2rayN 与 v2rayNG 里是怎么生成的。片段可直接作为查阅对照。
使用说明与阅读路径
本页与教程页的分工
本页是 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 级别的日志会明确写出连接尝试的目标与结果,对照配置逐项核对即可。
一次只改一个参数
同时改多个参数再测试,即使问题解决了也不知道是哪一个改动起了作用。一次改一处、改完立即验证,是配置调试里最省时间的做法。