JSON / INBOUNDS / OUTBOUNDS / ROUTING / DNS / POLICY
V2Ray 配置文件参考
从字段含义到规则执行顺序,按章节核对你的配置。
第一次导入订阅、选择节点和启用系统代理,先走完快速上手教程。本页不重复点击流程,而是解释客户端生成的 JSON 各段负责什么、哪些字段能一起改、出现异常时应从哪里查起。已经能连接,再来调整分流与 DNS,定位会更清楚。
JSON 结构总览:先看数据流
V2Ray 配置不是一组互不相关的开关。应用先连接入站,内核根据目标信息选择路由,再交给某个出站处理;DNS 为需要解析的环节提供结果,策略和日志决定连接如何管理、问题如何观察。先沿着这条数据流读一遍,比逐个背字段更实用。同一个访问失败,可能是应用没进入入站,也可能是出站无法完成握手,两者不该用同一种办法处理。
顶层对象与字段归属
顶层必须是一个 JSON 对象。inbounds 和 outbounds 是数组,允许分别定义多个入口与出口;routing、dns、policy、log 通常是对象。不要把入站的 listen 放进出站,也不要把路由规则直接塞到顶层。编辑器能识别括号,只能证明结构有机会被解析,不能证明字段放在了正确的位置。
{
"log": {
"loglevel": "warning"
},
"inbounds": [],
"outbounds": [
{
"tag": "direct",
"protocol": "freedom",
"settings": {}
}
],
"routing": {
"domainStrategy": "AsIs",
"rules": []
}
}
上面的结构片段展示字段关系,但没有本地监听入口,不能直接让浏览器接入。空数组本身是合法 JSON,其运行意义还要结合内核默认行为判断。阅读别人提供的片段时,先问清它替换哪个字段,再决定是覆盖整个数组,还是只追加其中一个对象。把两份完整对象首尾相接,会变成无法解析的文档。
| 字段 | 负责的环节 | 核对重点 |
|---|---|---|
inbounds | 接收本地应用连接 | 地址、端口、协议 |
outbounds | 建立后续连接 | 标签、协议、远端参数 |
routing | 把连接分配给出站 | 规则顺序与标签引用 |
dns | 内核侧域名解析 | 解析器与查询策略 |
policy | 连接管理与统计开关 | 等级和统计依赖 |
语法正确与配置有效是两回事
为了便于跨工具复制,本页统一使用严格 JSON:键名和字符串使用英文双引号,数组最后一项后面不加逗号,正文解释不写进代码块。某些读取器允许注释,不代表订阅处理器和其他内核也接受。布尔值写 true 或 false,不要写成带引号的字符串;数字与字符串也不要只凭外观互换,字段实际要求以对应内核为准。
同一个对象内不要重复键名。例如写两次 routing,不同处理器可能覆盖前一项,也可能直接拒绝读取;表面看上去两组规则都在,实际只生效一组。合并配置时,应把规则放进同一个 rules 数组。数组顺序也有实际含义,出站首项可能影响默认出口,路由前项可能提前截获连接,不宜用自动排序工具随意整理。
标签是跨段引用的连接点。出站定义了 direct,路由才可以用 outboundTag 指向它;标签大小写和拼写需要一致。建议给每个入站、出站使用稳定且唯一的标签,后续日志与分流都按标签识别。标签只是名字,不会因为叫作 proxy 就自动获得代理能力,实际行为仍由该对象的协议与设置决定。
保留配置来源,再开始编辑
在图形客户端中,订阅记录、界面设置与运行配置通常不是同一个文件。先保留客户端的可恢复备份,再查看本次启动实际生成的内容。不要在内核运行时改一个临时文件,就认为下次启动仍会保留。能通过界面设置完成的修改,优先在对应设置页保存;必须使用自定义配置时,再按客户端提供的入口加载。
每次修改前写清预期结果,例如“此域名使用直连出口”,而不是“优化网络”。随后只改变与该目标有关的一段配置,重载后用同一访问动作验证。这样一来,语法错误、字段不兼容和规则不命中就能分别定位。若首次连接尚未建立,先回到教程主线完成基础验证,不必同时加入复杂规则。
客户端与内核:先确认配置方言
V2Ray 常被用作一整个生态的称呼,但客户端界面与实际执行连接的内核不是一回事。v2rayN 负责桌面上的订阅管理、配置选择与运行控制,内核负责解析配置、建立连接和执行路由。看到相似菜单,不代表底层支持完全相同。查阅某个字段前,先确认当前运行的是哪一种内核,再确认客户端是否会把界面选项转换成另一种格式。
V2Fly 与 Xray 的共同结构和差异
Project V 生态中的 V2Fly 与 Xray 有共同的历史背景,也保留了不少相似的 JSON 结构。不过,协议实现、传输参数、额外特性和字段演进并不完全同步。本页示例以常见的传统 JSON 结构解释基础概念,不承诺所有扩展字段都能跨内核复制。特别是涉及 VLESS、XTLS、REALITY 等配置时,必须逐项确认所用内核和对应协议组合的支持情况。
Android 端的 v2rayNG 以 Xray 内核为主要使用方向,v2flyNG 则是 V2Fly 内核的备选客户端。桌面优先从 v2rayN 开始,实际内核选择仍应与你的配置要求匹配。不要因为某个客户端能成功导入一条链接,就推断它能完整运行链接中的每个参数;导入解析、配置生成与内核启动,是三个需要分别通过的环节。
| 客户端 | 主要场景 | 配置检查方向 |
|---|---|---|
| v2rayN | 桌面订阅与运行管理 | 当前内核、生成配置、系统代理 |
| v2rayNG | Android 连接管理 | Xray 参数、系统连接授权、应用范围 |
| v2flyNG | Android 的 V2Fly 方案 | V2Fly 字段、协议兼容性 |
图形设置不是原始 JSON 的镜像
客户端可能用一个下拉选项组合多个字段,也可能隐藏由程序管理的标签和端口。比如界面里的路由模式,可能对应一整组规则,而不是某个叫“模式”的顶层键。修改生成文件后再切换模式,原先的变更可能被覆盖。阅读配置时应区分:哪些值来自当前节点,哪些值来自全局设置,哪些值由客户端在启动时自动补齐。
自定义配置也不一定接受客户端全部托管功能。某些导入方式按完整配置运行,另一些方式只把它当成单个连接条目。系统代理指向的本地端口、客户端用来检测状态的入口,以及统计所需标签,都可能有额外约定。发现界面显示已启动但应用无法接入时,先核对实际监听端口,不要立即判断远端服务器失效。
{
"outbounds": [
{
"tag": "direct",
"protocol": "freedom",
"settings": {}
}
]
}
这段出站定义表达直接连接,适合说明通用字段,却不代表完整的远端连接。它也说明了配置兼容性的判断方法:先找协议名称,再看协议自己的 settings,最后检查传输相关参数。只替换协议名称而保留原协议的设置对象,通常无法得到正确结果;不同协议使用的服务器、认证和传输字段应作为一组核对。
迁移配置时按能力核对
切换内核前,先列出当前实际使用的协议、传输方式、路由数据库、DNS 策略与入站功能。确认新内核支持这些能力,再用一条配置做小范围验证。不要把整份配置一次替换后,只依据界面是否亮起判断迁移成功。内核可以启动,但某条少见路由、某种 UDP 使用场景或额外传输行为仍可能与原先不同。
路由数据库同样属于兼容性边界。配置里写着 geosite:cn,还需要当前内核能找到对应资源,并且文件包含这个分类。客户端更新规则资源的目录,未必就是另一内核查找资源的目录。手动迁移时不能只带走 JSON;需要一起核对资源加载位置,但不要随意把不同格式的数据文件改名混用。
排错时先记下“客户端名称、实际内核、配置来源、报错字段”四项信息,通常比一张首页截图更有用。需要选择安装包可前往客户端页面;要进一步理解两条内核分支的取舍,可读Xray 与 V2Fly 内核区别。不要把更换客户端当成通用修复,先确认它是否解决了具体的兼容问题。
inbounds 入站:定义应用接入口
入站决定应用怎样把连接交给内核。常见的本地入口是 SOCKS 与 HTTP 代理,应用需要使用正确的协议和端口连接它们。入站端口不是远端服务器端口,监听在本机也不意味着远端连接已经成功。排错的第一步,是确认应用确实到达这个入口;如果请求根本没有进入内核,继续调整出站认证参数不会改变结果。
本地地址、端口与协议要一起核对
{
"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": {}
}
]
}
这段配置建立两个仅在本机回环地址上监听的入口。SOCKS 应用使用 10808,HTTP 代理应用使用 10809,不能把两个端口当成随意互换的别名。这里的数值是示例约定,不代表你的客户端必然采用相同端口。若界面显示其他值,以实际运行配置为准,并同步修改应用侧的代理地址。
listen 为 127.0.0.1 时,其他设备不能通过局域网地址访问该入口。若改成通配监听地址,接入范围就不再限于本机,必须同时考虑认证、系统防火墙和可信网络边界。上面的 SOCKS 示例使用不要求认证的模式,只适合明确限制为本机的场景,不应原样改成对外开放的共享代理。
UDP 开关不是全链路保证
SOCKS 设置中的 udp 允许入站处理相应的 UDP 请求,但最终能否完成通信,还取决于应用是否真的使用 SOCKS 的 UDP 能力、出站协议是否支持以及远端网络是否放行。HTTP 代理入口通常服务于 HTTP 请求与隧道连接,不等同于一个通用 UDP 接入口。遇到浏览器正常而某个实时应用失败,应先区分它们使用的传输类型。
同样,系统代理只是向遵循系统设置的应用公布代理入口,不会自动接管所有流量。一些程序读取自己的代理配置,一些直接连接网络。TUN 则属于另一类接管方式,涉及虚拟网络接口、权限、路由与 DNS 配合,不能仅靠增加一个 SOCKS 入站来替代。要判断生效范围,应从具体应用的流量入口开始查,而不是只看托盘状态。
嗅探提供域名线索,但不是万能识别
{
"inbounds": [
{
"tag": "socks-in",
"listen": "127.0.0.1",
"port": 10808,
"protocol": "socks",
"settings": {
"auth": "noauth",
"udp": true
},
"sniffing": {
"enabled": true,
"destOverride": ["http", "tls"]
}
}
]
}
嗅探会尝试从已接收流量中提取协议或域名信息,帮助内核处理只携带目标 IP 的连接。它不是解密工具,也不能保证任何连接都能还原出域名。某些握手方式、加密元数据或非 HTTP、TLS 流量会限制识别能力。开启后还要确认当前内核的目标覆盖语义,不能把“可用于路由的域名线索”和“实际连接目标”简单视为同一件事。
给入站加上稳定标签,还有助于按入口分流。例如独立的测试入口可以配合路由的 inboundTag,只影响从该入口进入的连接。不过规则仍按顺序执行,如果前面已有更宽泛的匹配,入口专用规则可能没有机会命中。标签应在新增入口时就确定,避免后续改名却漏掉引用它的路由。
验证入站时,先使用明确支持手动代理的应用,指定本机地址和对应端口,再观察日志是否出现请求。没有记录时查应用设置、监听地址和防火墙;出现记录但随后报错,再转向出站与解析。只有局域网设备无法访问时,则另外检查绑定地址和访问范围。把这三类问题分开,通常能减少无关的配置修改。
outbounds 出站:区分连接方式与标签
出站负责接到一条连接后,实际怎样访问后续目标。它可以直接连接,也可以按照远端协议建立连接,或者明确阻断请求。入站解决“应用如何进入”,出站解决“内核如何出去”,两者不要求使用相同协议。应用经 SOCKS 入站进入内核后,可以被路由到不同类型的出站;因此不能看到本地 SOCKS 端口,就推断远端也使用 SOCKS。
先建立直连与阻断两个基本出口
{
"outbounds": [
{
"tag": "direct",
"protocol": "freedom",
"settings": {}
},
{
"tag": "block",
"protocol": "blackhole",
"settings": {}
}
]
}
freedom 表示由内核直接向目标建立连接,blackhole 用于丢弃被分配到它的流量。direct 和 block 都只是本例标签,你可以更换名字,但必须同步修改路由引用。阻断出口适合表达明确的拒绝策略,不应被当成连接失败时的自动备用;如果规则误把常用请求送到这里,应用看到的现象可能只是超时或连接中断。
在传统配置行为中,未被规则选中的流量通常会交给出站数组中的首个出口。上面的首项是直连,所以默认结果也是直连。把远端出站加入数组末尾,并不会自动让所有请求改走远端。调整默认出口之前,先确认客户端是否另行生成了兜底规则,以及是否使用了负载均衡等额外机制,不能只凭数组顺序推断所有场景。
远端参数需要完整成组保留
VMess、VLESS、Trojan 等协议的认证与传输字段并不相同。远端地址、端口、用户信息、传输类型以及 TLS 相关参数,必须与服务端实际配置对应。不要把一条链接中的认证信息搬到另一种协议对象里,也不要只为了让配置通过解析而删掉不认识的字段。通过解析只能说明格式被接受,无法证明双方的握手约定一致。
当远端使用 TLS 时,连接地址、用于握手的服务器名称以及应用层请求中的主机字段,可能分别承担不同职责。它们有时一致,但不能因为看起来都是域名就混为一谈。传输路径同样可能由服务端明确约定。应以你取得的完整配置为依据,逐项对照;随机替换名称或路径,往往只会把原本清楚的错误变成多处不匹配。
| 检查层次 | 主要内容 | 常见误区 |
|---|---|---|
| 对象识别 | tag、protocol | 把标签当作协议功能 |
| 协议设置 | settings 内的连接参数 | 混用不同协议的认证结构 |
| 传输设置 | streamSettings 等适用字段 | 只改传输名称,不改配套参数 |
| 路由引用 | outboundTag | 出口存在但始终没有被选中 |
错误发生在哪一层
连接被分配到某个出站后,还可能依次经历域名解析、建立底层连接、TLS 握手、协议认证以及数据传输。某一步失败,不应直接归结为“节点不可用”。例如本地解析失败时,连目标地址都未得到;底层端口可达,也不代表协议认证一定成功。查看日志时应寻找最早的具体错误,而不是只复制最后一行汇总信息。
测试直连与测试远端出站,应使用不同的明确目标。先让同一个本地入站接入一个已知可直接访问的页面,确认应用到内核这一段成立;再选择已有的远端出站,观察路由与握手结果。如果两个测试同时失败,优先排查共同的入站或客户端运行问题。只有远端路径失败时,再检查远端字段、网络条件与协议兼容性。
不要把跳过证书验证当成默认排错步骤。证书名称、系统时间、信任链与服务端配置都可能影响 TLS,直接关闭验证会掩盖真正的不匹配。应先核对连接信息来源与设备时间,再根据日志处理具体原因。也不要把包含认证信息的完整 JSON 发到公开讨论区;说明问题通常只需要协议类型、字段名称与经过处理的报错。
在客户端里,订阅更新可能重新写入远端出站,因此长期保留的本地路由应尽量使用客户端支持的管理方式。需要新安装客户端时前往下载页面,导入后的验证顺序见v2rayN 首次连接检查。出站先保持最少数量,等单条路径验证通过后再增加复杂组合。
routing 路由:按顺序判断连接
路由不是按规则数量决定优先级,而是按配置顺序判断。通常从上往下查找,遇到匹配项就选择其出口,后面的规则不再参与这次选择。因此,具体例外应放在宽泛分类前面。某个域名明明写了直连却仍走远端,先检查前面是否已有更大的分类覆盖它,比反复重启客户端更有针对性。
规则顺序与标签引用
{
"routing": {
"domainStrategy": "IPIfNonMatch",
"rules": [
{
"type": "field",
"ip": ["geoip:private"],
"outboundTag": "direct"
},
{
"type": "field",
"domain": ["domain:example.com"],
"outboundTag": "direct"
},
{
"type": "field",
"domain": ["geosite:cn"],
"outboundTag": "direct"
},
{
"type": "field",
"network": "tcp,udp",
"outboundTag": "block"
}
]
}
}
本例依赖已经存在的 direct、block 出站,以及可加载的 GeoIP、GeoSite 数据。末项把剩余 TCP、UDP 连接送往阻断出口,表示一种明确限制的策略,不是建议所有用户采用的默认方案。若你希望其余连接走已有远端,应引用那个真实出站的标签,并确认它确实存在;不要凭空添加一个叫“代理”的标签。
同一条规则中,不同条件字段通常需要同时满足;同一列表里的多个候选通常用于匹配任意一项。例如规则同时写了 inboundTag 和 domain,表达的是从指定入口进入且命中指定域名,而不是两者满足其一即可。把多个无关条件塞进一条规则,可能让它永远不命中。需要表达两条独立路径时,应拆成两个规则对象。
域名匹配要选对语义
domain:example.com 用于匹配该域及其子域,full:example.com 用于精确匹配完整域名。普通字符串与正则表达式有不同语义,不能仅因能匹配一次就认为边界正确。常规域名分流优先使用明确的域名匹配形式,避免一个过短的关键词误中其他域名;需要正则时,再单独验证边界与转义。
JSON 字符串本身会处理转义,正则表达式也会处理转义,所以从其他工具复制规则时要特别小心。先确认正则在 JSON 中的实际字符串,再确认内核如何解释它。若只想匹配一个域名及子域,没有必要为了简短而使用复杂表达式。规则越容易读懂,后续定位误匹配就越不依赖猜测。
domainStrategy 决定何时借助 IP
AsIs 不为了路由主动把域名解析成 IP,但已知 IP 的连接仍可参与 IP 规则匹配。IPIfNonMatch 在域名阶段没有找到匹配时,再尝试解析并按 IP 条件判断;IPOnDemand 会在匹配过程中需要 IP 信息时触发解析。它们改变的是路由阶段的解析时机,不等同于全局切换设备 DNS,也不等同于指定远端出口。
尤其要注意兜底规则的影响。如果域名阶段已经被一条宽泛规则接住,IPIfNonMatch 可能没有机会进入解析后的匹配过程。于是你以为私有 IP 规则会处理某个域名,实际它先被末尾的网络兜底选走了。设计规则时要明确哪些目标以域名分类为准,哪些必须在解析后检查地址,不能只看字段名字推测执行顺序。
维护规则时,把“本地地址、明确例外、业务分类、最终兜底”分成可读的顺序,每次只增改一类。规则资源更新后,也应复测少量代表性目标,因为分类内容可能改变。遇到资源缺失或分类找不到,先处理启动日志,不要通过删除所有分流规则掩盖。具体资源维护可接着看GeoIP 与 GeoSite 数据库更新说明。
最后用日志核对目标域名、入口标签与被选中的出站。只有浏览器打开成功,还不足以证明规则命中了预期出口,因为直连和远端都可能访问成功。若路由结果不符,先检查实际加载配置中的规则顺序,再看应用是否提交了域名,最后检查数据库。按这个顺序排查,能避免把域名信息缺失误当成分类错误。
dns 配置:分清谁在解析域名
一次访问中可能出现多个解析者:应用自己解析、操作系统解析、内核内置 DNS 解析,或者由远端连接的一侧解析。看到配置中有 dns,不代表设备上的所有查询都经过它。先弄清应用交给入站的是域名还是 IP,再判断这段配置是否参与了当前请求。否则,改了内核 DNS 却观察系统解析结果,很容易得出错误结论。
servers 与 queryStrategy 的基本作用
{
"dns": {
"servers": [
"1.1.1.1",
"localhost"
],
"queryStrategy": "UseIPv4"
}
}
这里配置一个明确地址的解析器和本地系统解析入口,并把内核支持的查询地址族限制为 IPv4。localhost 在这里表示使用本地系统解析机制,不是一个远端主机名。列表也不应简单理解成“第一项失败才试第二项”的固定主备关系;实际选择、并发与回退行为需要结合服务器对象、匹配域名及当前内核实现判断。
UseIPv4 不是性能优化口诀,而是地址族选择。如果目标只有可用的 IPv6 地址,限制 IPv4 可能直接让它不可达;如果设备的 IPv6 路径有问题,允许双栈又可能暴露另一类连接失败。应先确认本地网络和远端路径具备哪些能力,再设置查询策略。这个字段也不会自动关闭系统的 IPv6,不能用它代替设备网络管理。
按域名选择解析器
{
"dns": {
"servers": [
{
"address": "1.1.1.1",
"port": 53,
"domains": ["domain:example.com"]
},
"localhost"
],
"queryStrategy": "UseIP"
}
}
服务器对象可以表达面向特定域名的解析选择。例子把 example.com 及其子域列为指定服务器的匹配范围,其余查询仍需结合完整回退逻辑判断。domains 不是路由的 domain 字段,不能因为内容相似就交换名称。更复杂的服务器对象还可能涉及期望地址与回退设置,添加前要确认对应内核支持其准确语义。
解析器的网络可达性同样需要验证。明文 DNS、加密 DNS 与本地解析入口,可能经过不同的连接路径;某些形式受普通路由影响,另一些具有本地处理语义。不能笼统地说“写进 servers 就一定走代理”。如果解析器地址本身需要域名解析,还要考虑启动阶段怎样获得它的地址,避免解析依赖自身,形成无法完成的循环。
| 设置位置 | 主要作用 | 不能直接推出 |
|---|---|---|
| 系统网络设置 | 影响使用系统解析的程序 | 内核所有查询都使用它 |
顶层 dns | 提供内核侧解析能力 | 设备全部 DNS 被接管 |
| 路由解析策略 | 决定匹配时是否需要地址 | 指定某个连接出口 |
| 应用独立解析设置 | 影响该应用的解析路径 | 其他程序采用相同结果 |
缓存、嗅探与 FakeDNS 的边界
修改解析策略后,应用、系统和内核可能仍保留旧缓存,已有连接也可能继续复用。验证时应新建连接,必要时按对应程序的方式处理缓存,不要只刷新同一页面一次。若浏览器采用独立的加密解析,它看到的结果可能与系统不同。先明确验证工具使用哪条解析路径,再比较结果,才能判断修改是否真正参与了请求。
FakeDNS 通过虚拟地址保存域名映射,目标是帮助后续流量恢复域名信息,不是向公网分配真实目标地址。它需要与接管方式、映射回收和嗅探设置配合,不能单独打开一个字段就期待所有应用正常。若某个程序绕开预期入口,拿到虚拟地址后直接访问,就可能失败。常规系统代理已经可用时,不必为了增加字段而启用它。
DNS 排错建议分三步:先确认是否得到结果,再确认结果是否适合当前网络,最后确认访问使用了哪个结果。日志中出现解析超时,应先查解析器可达性;得到地址却连接失败,则继续检查地址族、出站与远端路径。相关原理可读FakeDNS 工作原理与适用场景。不要把所有访问失败都归因于 DNS。
配置稳定后,保留一小组能代表不同解析路径的目标作为回归测试。每次更换服务器、查询策略或接管模式,都用相同目标重新验证。解析结果会随服务调度变化,不必要求地址永远相同;真正要核对的是解析能完成、返回地址可用,并且连接遵循预期的路由边界。
policy 与日志:控制连接,保留证据
policy 处理连接管理和统计相关策略,不负责决定某个域名走哪个出口。路由异常应先查 routing,认证异常应先查出站;不要因为策略里出现“超时”字段,就把所有连接失败都归结为等待时间不够。大多数普通使用场景可以先保留默认策略,等日志明确表明某种连接生命周期不符合需求时,再做定向调整。
等级策略怎样关联连接
{
"policy": {
"levels": {
"0": {
"handshake": 4,
"connIdle": 300,
"uplinkOnly": 2,
"downlinkOnly": 5,
"statsUserUplink": false,
"statsUserDownlink": false
}
},
"system": {
"statsInboundUplink": false,
"statsInboundDownlink": false,
"statsOutboundUplink": false,
"statsOutboundDownlink": false
}
}
}
这里的等级键 "0" 是对象键,所以需要双引号。连接使用哪个等级,需要结合相应协议中支持的用户等级设置判断;有的入站通过 userLevel 关联,有的协议把等级放在用户对象内。只新增一个等级对象,不会自动把所有连接迁移过去。本例数值仅用于解释字段,不是针对任何网络环境的统一推荐值。
handshake 与建立连接时的握手等待有关,connIdle 处理连接空闲时长,uplinkOnly 和 downlinkOnly 则涉及单向传输状态下的保留时间。这些时间通常以秒计,具体作用还取决于协议与连接阶段。把所有数值调得很大,可能只是让无效连接占用资源更久,并不能修复错误的服务器地址或认证参数。
统计开关不是完整统计服务
策略中的统计布尔值只负责允许记录某类数据,完整读取还可能依赖统计模块、用户标识、接口配置以及客户端的调用方式。打开几个开关,不代表界面马上就会显示所有统计。使用图形客户端时,优先保留它管理的统计相关配置,避免手动改标签或删除接口后,使界面失去与内核通信的能力。
也不要为了查看统计而随意开放管理接口。接口是否监听、绑定在哪个地址、谁能访问,都需要独立考虑;它不是普通应用代理入口。若客户端已经提供流量信息,一般不必另建外部可访问接口。本页的基线示例不包含管理接口,目的是把连接路径保持清楚,而不是提供完整的监控部署方案。
日志先用 warning,需要时短暂提高详细度
{
"log": {
"loglevel": "warning"
}
}
平时使用 warning 可以减少常规输出。排错需要观察请求去向时,可短暂切换到更详细的日志级别,再复现一次问题。不要长时间保留过量调试日志,因为它可能记录目标地址、连接细节并增加存储负担。完成定位后恢复常规级别,同时根据客户端提供的方式处理不再需要的日志。
{
"log": {
"access": "access.log",
"error": "error.log",
"loglevel": "info"
}
}
这个片段把访问与错误输出写到相对路径文件。相对路径一般受进程工作目录影响,不一定落在你打开 JSON 的目录;客户端可能另行管理输出。使用前确认目录可写、文件位置可找到,也要考虑日志持续增长。若日志路径无效导致启动失败,先恢复客户端默认输出方式,不要在没有证据的情况下反复修改连接参数。
读日志时从时间顺序还原一次访问:内核是否启动、入口是否接到连接、路由选了哪个出口、解析是否成功、握手在哪一步失败。若第一条明确错误是配置字段无法识别,后面的连接状态没有分析价值;若启动正常但没有访问记录,则应回到应用入口。先找到最早发生的确定性异常,再决定改哪一段。
移动端还要把进程生命周期与连接策略区分开。应用被系统回收、后台权限受限或网络切换,不能单靠延长 connIdle 解决。遇到熄屏后断连,可结合v2rayNG 后台运行与电池设置检查系统层条件。策略参数只有在内核仍然运行、连接确实由它管理时,才有讨论意义。
验证与回退:用最小配置定位问题
验证配置时,先把“内核能够启动”和“目标能够访问”拆开。前者主要检查 JSON、字段兼容性、资源和监听条件,后者还包括应用接入、解析、路由及后续连接。下面给出一份本地直连基线,只用于确认应用能否通过内核访问原本就可直连的目标,不包含远端代理功能,也不需要 GeoIP、GeoSite 资源。
完整的本地直连基线
{
"log": {
"loglevel": "info"
},
"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": "direct",
"protocol": "freedom",
"settings": {}
}
],
"routing": {
"domainStrategy": "AsIs",
"rules": [
{
"type": "field",
"network": "tcp,udp",
"outboundTag": "direct"
}
]
}
}
先备份现有客户端设置,通过客户端明确支持的完整自定义配置入口加载这份基线。不要把它粘贴到只接受单个节点字段的输入框。若客户端托管端口或另有生成规则,应根据它的实际配置方式操作,避免同时运行两份内核争用端口。加载后,选择支持手动代理的应用,把它指向对应的本地入口,再访问已知可直接连接的目标。
按层验证,不要同时改变多个变量
如果基线无法启动,先看最早的报错。语法类错误核对括号、逗号和双引号;端口占用检查其他进程;字段无法识别则确认内核类型和配置格式。此时不要添加 DNS、嗅探或更多出站,因为它们会让错误来源增加。最小配置的价值,就在于把本来交织的问题拆成几个可以单独确认的环节。
如果启动成功但应用访问失败,先看日志里有没有这次请求。没有请求时,查应用代理协议、地址和端口;有请求但解析失败,查系统解析与目标域名;有地址却连接失败,再查本机网络与目标服务。这个阶段还没有远端出站,所以无需讨论远端认证或传输参数。先确认基线成立,后续对照才有意义。
基线可用后,恢复你已有的远端出站,并用一条明确路由指向它。先验证单条远端连接,再逐步加入域名分类、DNS 对象和其他策略。每加入一组设置,都执行同一套访问动作并记录结果。若加入某段后开始失败,回退该段即可缩小范围,不必把已经验证通过的入站重新配置一遍。
| 观察到的现象 | 优先检查 | 暂不优先处理 |
|---|---|---|
| 内核立即退出 | 语法、字段、资源、端口 | 浏览器缓存 |
| 启动正常但无请求 | 应用入口与代理范围 | 远端认证参数 |
| 请求进入但出口不符 | 加载配置、规则顺序、标签 | 增大连接超时 |
| 出口正确但握手失败 | 协议、传输、时间与远端信息 | 重排域名分类 |
配置重载与已有连接
修改配置后,需要按客户端支持的方式重新加载或重启内核。已经建立的长连接、浏览器连接池和应用缓存,可能继续保留旧状态,不能仅凭一个仍在播放的页面判断新规则无效。验证时新建连接,必要时关闭对应应用后重试,但不必每改一个字段就重启整台设备。先用小范围动作确认配置切换,效率更高。
系统代理与 TUN 的验证也应分开进行。先在一种明确的接入方式下完成测试,再切换另一种方式,避免两套接管逻辑叠加后无法判断流量从哪里进入。桌面与 Android 的系统集成方式不同,但检查顺序一致:入口、解析、路由、出口。若只是某个应用不受影响,应优先确认它的代理范围,而不是宣布整个内核失效。
回退时恢复一整组关联字段
有效备份不只是一个 JSON 文件,还包括配置来源、当前内核、所需资源和客户端相关设置。回退路由时恢复完整规则顺序,回退出站时恢复协议与配套传输字段,回退 DNS 时同时检查应用独立解析。不要只撤销最后一个肉眼可见的值,却留下指向已删除标签的规则;关联字段不完整,会引入新的错误。
最后保留一份简短变更记录:修改目标、涉及字段、验证方法和结果。记录不需要包含账号信息,也不必保存每次完整日志。下次遇到相似现象时,先复用已验证的基线,再比较新增部分。首次使用回到教程,常见连接问题查看连接故障问答;本页则作为字段与执行关系的查阅入口,按实际问题回到相应章节即可。