JSON 结构总览与处理链路
先看数据怎样穿过配置
V2Ray 配置不是一组彼此独立的开关,而是一条有顺序的处理链。应用流量先进入 inbounds,内核从入站连接中取得目标地址、端口、网络类型与入站标签;随后 routing 按规则从上到下判断应该交给哪个出站;域名在匹配或建立连接时可能进入 dns 解析流程;最终由 outbounds 中被选中的代理、直连或拦截出口处理。policy、log 与统计配置不直接改变目的地,却会影响连接生命周期、可观测信息和排错效率。理解这条链路,比孤立记忆字段更可靠。
顶层对象通常包含 log、dns、inbounds、outbounds、routing 与 policy。数组中的每个入站和出站都应设置清晰的 tag,因为路由规则通过标签引用它们。标签只是配置内部标识,不会自动创建网络连接,也不能与订阅里的节点备注混为一谈。一个常见错误是规则写了 outboundTag: proxy,实际出站却叫 proxy-main,配置可能通过 JSON 语法检查,但运行时无法按预期选路。
{
"log": {
"loglevel": "warning"
},
"dns": {
"servers": [
"1.1.1.1",
"localhost"
]
},
"inbounds": [
{
"tag": "socks-in",
"listen": "127.0.0.1",
"port": 10808,
"protocol": "socks",
"settings": {
"auth": "noauth",
"udp": true
}
}
],
"outbounds": [
{
"tag": "proxy",
"protocol": "vmess",
"settings": {
"vnext": [
{
"address": "node.example.com",
"port": 443,
"users": [
{
"id": "11111111-1111-4111-8111-111111111111",
"security": "auto"
}
]
}
]
}
},
{
"tag": "direct",
"protocol": "freedom"
},
{
"tag": "block",
"protocol": "blackhole"
}
],
"routing": {
"domainStrategy": "AsIs",
"rules": []
}
}
对象、数组与字段类型
JSON 对格式的要求很严格:对象使用花括号,数组使用方括号,键名和字符串使用双引号,布尔值只能写成 true 或 false,数字不能加引号。最后一个字段后不能保留逗号,配置中也不应混入说明性注释。许多“内核启动失败”并非协议问题,而是复制片段后出现全角标点、弯引号、重复键或括号层级错位。编辑时应保持 UTF-8 文本,先完成纯 JSON 语法检查,再判断字段是否被当前内核支持。
字段支持范围取决于内核家族。v2rayNG 通常配合 Xray 内核,v2flyNG 对应 V2Fly 内核,v2rayN 则能管理不同类型的核心与配置。VMess、VLESS、传输层安全和路由字段存在大量交集,但 REALITY 等能力要按实际内核支持情况选择。把另一内核专属字段直接粘贴过来,最常见结果是“未知字段”、出站初始化失败或客户端在保存时丢弃该字段。配置迁移应先确认协议能力,再逐段迁移,不宜一次替换整份文件。
图形客户端与内核配置的边界
v2rayN、v2rayNG 和 v2flyNG 都会把界面设置、订阅节点和路由选项转换为内核配置。界面中的“系统代理”“VPN 服务”“绕过局域网”等选项不一定对应同名 JSON 字段,有些属于操作系统接管层,有些才会进入 routing.rules。因此排错时要先判断问题属于哪一层:客户端是否接管了流量、生成配置是否正确、内核是否成功启动、目标连接是否命中预期出站。只盯着订阅节点状态,往往会遗漏系统代理和路由层。
手工维护配置时,建议采用稳定的标签命名,例如 socks-in、http-in、proxy、direct、block。名称简短、含义唯一,能降低后续规则拼写错误。复杂配置还应记录每个出站的职责,而不是把节点备注当作永久标识。客户端更新订阅后,节点名称可能变化;职责型标签则应保持稳定,让路由规则只依赖“代理、直连、拦截”这些逻辑出口。
inbounds 入站:流量从哪里进入
监听地址、端口与暴露范围
inbounds 定义本机应用怎样把流量交给内核。桌面客户端常见 SOCKS 与 HTTP 入站,移动端客户端还会通过系统网络接口接管应用流量。手工配置中最先需要确认的是 listen 和 port:监听 127.0.0.1 表示仅接受本机连接,适合浏览器、终端或系统代理使用;监听所有网络接口会扩大可访问范围,需要同时评估局域网环境、认证方式和系统防火墙。除非明确需要让其他设备连接,一般保持本机监听更便于控制。
端口必须未被其他程序占用,并且不同入站不能重复监听同一地址和端口组合。v2rayN 界面中的本地端口通常由客户端管理,手工改配置后若界面仍保存旧端口,系统代理可能继续指向旧值,表现为“内核已运行但网页不通”。此时应同时核对内核日志中的监听信息、客户端显示的本地端口以及操作系统代理设置,三处必须一致。
{
"inbounds": [
{
"tag": "socks-in",
"listen": "127.0.0.1",
"port": 10808,
"protocol": "socks",
"settings": {
"auth": "noauth",
"udp": true,
"ip": "127.0.0.1"
},
"sniffing": {
"enabled": true,
"destOverride": [
"http",
"tls"
],
"routeOnly": true
}
},
{
"tag": "http-in",
"listen": "127.0.0.1",
"port": 10809,
"protocol": "http",
"settings": {}
}
]
}
SOCKS、HTTP 与透明接管
SOCKS 入站适合支持 SOCKS5 的应用,并可通过 udp: true 接收 UDP 请求。HTTP 入站主要处理 HTTP 代理与 CONNECT 隧道,兼容大量桌面软件。二者都要求应用或系统代理明确指向对应端口。透明接管则不同:流量可能由操作系统路由、虚拟网络接口或转发规则送入内核,目标地址的恢复方式更复杂。图形客户端通常会管理这部分平台差异,不建议在不了解系统转发链时把桌面 SOCKS 示例直接改成透明入站。
settings 的内容由入站协议决定。SOCKS 的 auth、udp 与 HTTP 入站的账户字段不能互相套用。若监听范围只在本机,noauth 是常见设置;需要供局域网设备使用时,应先在客户端中启用对应共享能力,并设置访问控制。不要仅通过把监听地址改大来完成共享,因为系统防火墙、网络类型和认证仍会影响实际暴露范围。
流量嗅探与 routeOnly
sniffing 用于从 HTTP 请求或 TLS 握手中识别域名,以便域名规则在原始目标只有 IP 地址时仍有机会匹配。destOverride 指定可识别的协议类型,routeOnly 表示嗅探结果主要用于路由判断,而不是直接改写最终连接目标。启用嗅探并不等于所有连接都能获得域名:加密客户端问候、非标准协议、已建立连接和不包含主机信息的流量仍可能只能看到 IP。
嗅探开启后若某些站点连接异常,可按两条路径排查。第一条是暂时关闭嗅探,确认问题是否来自域名识别或目标改写;第二条是保留嗅探但使用 routeOnly,让域名只参与规则匹配。若规则主要基于 IP,嗅探收益有限;若配置大量 domain、geosite 或后缀规则,嗅探通常更有价值。最终选择应由规则设计决定,而不是把它视为固定的性能开关。
| 入站类型 | 常见用途 | 重点检查 |
|---|---|---|
| SOCKS | 浏览器、终端与支持 SOCKS5 的应用 | UDP 开关、监听地址、本地端口 |
| HTTP | 系统代理与支持 HTTP CONNECT 的软件 | 端口一致性、代理协议选择 |
| 透明接管 | 由系统转发链或虚拟网络接口统一接管 | 平台权限、目标恢复、路由循环 |
outbounds 出站:代理、直连与拦截
出站职责与选择顺序
outbounds 定义内核可以使用的出口。常见配置至少包含代理出站、freedom 直连出站和 blackhole 拦截出站。路由规则通过 outboundTag 选择其中一个;未命中规则时,内核通常使用出站数组中的首个可用项,因此数组顺序也具有实际意义。若希望默认代理,就把代理出口放在前面;若希望默认直连,则应明确调整顺序并补齐需要代理的规则,不能只改标签名称。
一个出站由协议层、服务器账户、传输方式和安全层共同组成。以 VMess 或 VLESS 为例,settings 描述服务器地址、端口与用户信息,streamSettings 描述 TCP、WebSocket、gRPC 等传输以及 TLS 或 REALITY 等安全方式。四部分必须与服务端参数逐项对应。地址正确但传输方式不同,或端口正确但安全层名称不同,都会导致握手失败。
{
"outbounds": [
{
"tag": "proxy",
"protocol": "vless",
"settings": {
"vnext": [
{
"address": "edge.example.com",
"port": 443,
"users": [
{
"id": "22222222-2222-4222-8222-222222222222",
"encryption": "none"
}
]
}
]
},
"streamSettings": {
"network": "tcp",
"security": "tls",
"tlsSettings": {
"serverName": "edge.example.com",
"allowInsecure": false
}
}
},
{
"tag": "direct",
"protocol": "freedom",
"settings": {
"domainStrategy": "UseIP"
}
},
{
"tag": "block",
"protocol": "blackhole",
"settings": {
"response": {
"type": "none"
}
}
}
]
}
服务器地址、用户与传输层
address 可以是域名或 IP,port 必须是数字。使用域名时,内核需要先完成解析,因此 DNS 配置会间接影响代理出站建立。用户标识、加密设置和 flow 等字段依协议而异,不应把 VMess 用户对象直接改名后当作 VLESS 配置。分享链接或订阅中已经包含这些参数时,优先让客户端解析;手工录入适合核对字段,但要避免漏掉路径、主机名、服务名或服务器名称。
streamSettings.network 表示底层传输。选择 WebSocket 时通常还需要路径和请求头主机;选择 gRPC 时需要服务名;选择 TCP 时也可能配置特定头部或安全层。传输名称相同并不表示其他参数可以省略。排错时应把“协议账户”和“传输握手”分开:账户错误常在协议认证阶段失败,传输参数错误则更早表现为连接关闭、TLS 名称不匹配或服务路径不可达。
TLS、REALITY 与内核差异
TLS 配置中的 serverName 用于服务器名称校验和握手,应按节点提供的信息填写,不能简单等同于连接地址。allowInsecure 控制证书验证,常规配置应保持 false。若节点依赖 REALITY,需要确认客户端当前使用的是支持该能力的 Xray 内核,并完整填写节点给出的服务器名称、公钥、短标识和指纹等字段。v2flyNG 使用 V2Fly 内核,选择客户端时应先按节点协议确认兼容范围,而不是仅比较界面。
v2rayN 可以管理桌面端节点和不同内核配置,适合 Windows、macOS 与 Linux。v2rayNG 面向 Android,并以 Xray 协议能力为主要选择依据;v2flyNG 则是 V2Fly 内核路线的备选。三者都属于配置管理层,节点能否连接仍由协议参数、内核支持和网络路径共同决定。需要安装对应客户端时,可在客户端下载页按平台选择。
直连、拦截与链式出口
freedom 表示由本机网络直接建立目标连接,适合局域网、设备地址或明确需要本地出口的域名。blackhole 用于终止被规则命中的连接。拦截规则应放在足够靠前的位置,并尽量缩小匹配范围,避免把更新服务、登录接口或局域网设备一起拦截。若日志只显示连接被关闭,首先检查目标是否误命中 block,而不是立即更换代理节点。
复杂配置可能通过 proxySettings 或其他机制把一个出站转交给另一个出站,形成前置代理或链式出口。链路越长,排错成本越高:任何一层的 DNS、传输或认证失败都会导致最终连接中断。建立链式配置前,应先分别验证每个单独出口可以工作,再逐层串联;同时保证中间出站标签唯一,避免规则直接选到只为链路内部准备的出口。
routing 路由:规则顺序与匹配边界
从上到下,命中即停止
routing.rules 是分流配置的核心。规则按数组顺序从上到下检查,一条连接命中后通常不会继续评估后续规则。因此,具体规则应放在通用规则之前:局域网直连可以早于大范围代理规则,明确拦截项应早于宽泛域名后缀,兜底策略则由最后的规则或默认出站承担。很多分流故障不是匹配条件写错,而是前面已有更宽的规则提前截获了流量。
规则可以按域名、IP、端口、网络类型、入站标签、协议识别结果或用户标识匹配。一个规则中同时出现多类条件时,通常需要这些条件共同成立;同一字段数组内的多个值则通常表示任一值命中。设计规则前要先把自然语言需求拆清楚,例如“从 SOCKS 入站进入、目标端口为 53 的 UDP 流量走 DNS 出站”,其中包含入站标签、端口、网络三类条件,缺少任意一项都可能扩大范围。
{
"routing": {
"domainStrategy": "IPIfNonMatch",
"domainMatcher": "hybrid",
"rules": [
{
"type": "field",
"ip": [
"geoip:private"
],
"outboundTag": "direct"
},
{
"type": "field",
"domain": [
"domain:example.internal",
"full:router.example.internal"
],
"outboundTag": "direct"
},
{
"type": "field",
"domain": [
"geosite:category-ads-all"
],
"outboundTag": "block"
},
{
"type": "field",
"network": "tcp,udp",
"outboundTag": "proxy"
}
]
}
}
域名规则的四种常见写法
full: 用于完整域名匹配,只命中完全相同的主机名;domain: 通常覆盖指定域名及其子域;regexp: 使用正则表达式,灵活但更容易扩大范围;geosite: 引用内核可用的分类数据。没有前缀的写法在不同配置语境中可能具有特定含义,为了便于维护,建议显式写出匹配类型。排查域名规则时,应记录实际访问主机名,而不是只看网页标题或产品名称。
正则规则需要同时考虑转义层。正则表达式本身使用反斜杠,放进 JSON 字符串后还要进行 JSON 转义,肉眼检查很容易漏掉。可以用 full: 和 domain: 表达的需求,不必优先使用正则。分类数据也不是实时网络状态,它只是一组随数据文件更新的域名或地址集合;命中结果与当前内核加载的数据内容有关。
IP、端口、网络与入站标签
IP 规则既可以写单个地址,也可以写 CIDR 网段或 geoip: 分类。geoip:private 常用于局域网与保留地址直连,但仍需结合实际网络检查。若公司网络或家庭网络使用特殊地址范围,应显式补充对应网段。端口可以写单个值或范围,网络类型则常见 tcp、udp 或组合。限制条件越明确,规则对其他流量的副作用越小。
inboundTag 能让相同目标在不同入口采用不同策略。例如浏览器通过 socks-in 进入时走代理,某个本地服务通过另一入站进入时保持直连。这比复制两套内核实例更易维护。前提是入站标签真实存在且拼写一致。标签比较通常区分字符,额外空格、大小写变化和客户端重新生成配置都可能导致规则失效。
domainStrategy 怎样触发解析
AsIs 优先使用连接中已有的域名进行路由,不为了 IP 规则主动解析域名;IPIfNonMatch 表示域名规则未命中时,再解析为 IP 尝试匹配 IP 规则;IPOnDemand 会在需要 IP 条件时更积极地触发解析。策略越积极,IP 分流能力越强,但 DNS 依赖也更深。若 DNS 服务器不可达或返回结果不符合预期,路由阶段就可能出现延迟和误判。
选择策略要与规则集配套。以域名规则为主、IP 规则只处理直接给出的地址时,AsIs 更直观;需要让域名最终匹配地区 IP 分类时,可考虑 IPIfNonMatch。修改后应分别测试域名目标与直接 IP 目标,并在日志中确认实际选择的出站。有关连接成功后无法访问的系统化排查,还可参考DNS、路由规则与系统代理逐项排查清单。
DNS 配置:解析路径与分流一致性
内置 DNS 与系统 DNS 的职责
dns 模块为内核内部的域名解析提供规则和服务器选择,主要服务于路由判断、代理服务器域名解析以及由内核接管的请求。它不必然替代操作系统全部 DNS 行为:如果应用自行发起加密 DNS、浏览器绕过系统设置,或流量没有进入内核,对应查询可能不经过此处。排错时要先确认“是谁发起解析”,再检查 V2Ray 的 DNS 配置,不能把所有域名故障都归到同一个模块。
servers 可以包含普通地址、localhost 或带匹配域名的服务器对象。简单列表按配置策略选择解析器;服务器对象则能让特定域名交给指定解析服务。若解析服务器本身使用域名,内核还需要先解析该服务器地址,容易形成额外依赖。用于基础解析的服务器尽量写成明确可达的地址,并确认其连接应该走直连还是代理。
{
"dns": {
"queryStrategy": "UseIP",
"disableCache": false,
"disableFallback": false,
"servers": [
{
"address": "1.1.1.1",
"domains": [
"domain:example.com"
],
"skipFallback": true
},
{
"address": "8.8.8.8",
"domains": [
"geosite:geolocation-!cn"
]
},
"localhost"
],
"hosts": {
"router.example.internal": "192.168.1.1"
}
}
}
hosts、缓存与查询策略
hosts 提供静态域名映射,适合固定的局域网服务或测试环境。它的优先级通常高于外部查询,因此旧映射会长期覆盖真实解析结果。修改服务器地址后若仍连接到旧 IP,应先检查 hosts,再检查 DNS 缓存。静态映射应只放确实稳定的目标,并在网络调整后同步更新。
disableCache 控制内核 DNS 缓存。保持缓存可减少重复查询和连接等待;排查解析变化时可以临时关闭,但长期关闭会增加查询量。queryStrategy 决定优先请求哪些地址族,常见选择包括使用 IP、仅使用 IPv4 或仅使用 IPv6,具体名称和支持范围应以当前内核为准。若本地网络没有稳定的 IPv6 路径,却获得 IPv6 地址并优先连接,可能出现域名能解析但连接超时的现象。
按域名指定解析器
服务器对象中的 domains 用来限定该解析器负责的域名。匹配语法与路由域名规则相近,可以使用完整域名、后缀或分类数据。skipFallback 表示匹配到该服务器的域名不再进入通用回退流程,适合必须使用特定解析器的内部域名;设置过宽则会让目标在该服务器失败后失去其他解析路径。
disableFallback 会整体改变回退行为,不适合在未理解服务器匹配顺序时直接开启。更稳妥的做法是先保留回退,用日志观察特定域名选中了哪台服务器,再针对少量确定目标增加 skipFallback。DNS 分流和路由分流应保持一致:若某类域名解析请求走代理,而解析得到的目标连接却被规则送往直连,可能出现出口视角不一致。反过来也一样,解析和连接路径分裂会增加定位难度。
代理服务器域名的启动依赖
代理出站的 address 若填写域名,内核必须在代理连接建立前解析它。此时还没有可用代理隧道,依赖代理才能访问的解析器可能造成启动闭环。处理方式不是盲目更换节点,而是确保至少有一条基础 DNS 路径能在代理建立前工作,并让代理服务器域名的解析走这条路径。配置复杂 DNS 出站时尤其要关注这一点。
判断 DNS 是否为根因,可以按四步收缩范围:先用固定 IP 目标验证出站链路;再检查节点服务器域名能否解析;随后检查目标域名的 A 与 AAAA 结果;最后观察路由是否因解析结果改变了出站。若固定 IP 同样失败,问题通常不只在 DNS。若节点能连接、部分域名失败,则继续检查域名匹配、缓存和地址族选择。
| 现象 | 优先检查 | 常见边界 |
|---|---|---|
| 所有域名都失败 | 基础解析器可达性、节点域名解析 | 代理尚未建立时的解析闭环 |
| 部分域名失败 | 服务器对象 domains、hosts、回退 | 规则范围过宽或静态映射过期 |
| 解析成功但连接超时 | 地址族、路由命中、目标出站 | IPv6 路径或出口选择不一致 |
policy 策略:连接生命周期与统计开关
系统策略与用户等级
policy 用于控制连接超时、握手时间、上下行空闲判断和统计开关。它不决定流量走哪个节点,也不替代路由规则。配置通常分为 levels 与 system:levels 按用户等级应用连接策略,协议用户对象中的 level 与这里的键对应;system 则控制全局统计维度。若用户没有显式设置等级,通常会落入默认等级策略。
等级键在 JSON 中以字符串形式出现,例如 "0"。不同协议对用户等级的引用方式可能不同,客户端自动生成配置时也可能省略未使用的策略。手工增加等级前,应先确认对应入站或用户对象确实引用了它。只创建 "1" 策略却没有任何用户设置 level: 1,不会自动提升全部连接。
{
"policy": {
"levels": {
"0": {
"handshake": 4,
"connIdle": 300,
"uplinkOnly": 2,
"downlinkOnly": 5,
"statsUserUplink": false,
"statsUserDownlink": false,
"bufferSize": 0
}
},
"system": {
"statsInboundUplink": true,
"statsInboundDownlink": true,
"statsOutboundUplink": true,
"statsOutboundDownlink": true
}
},
"stats": {}
}
handshake 与 connIdle
handshake 限制连接建立阶段允许等待的时间,单位通常为秒。数值过小会让高延迟网络、首次 DNS 查询或复杂握手在完成前被终止;数值过大则会让明显失败的连接占用更久。调整时应先区分“连接建立慢”和“建立后传输慢”,前者才与握手等待直接相关。若日志显示出站已经建立,继续增加握手时间通常没有帮助。
connIdle 控制连接在没有数据活动时可保持多久。即时通信、长轮询、远程终端和后台同步可能长时间没有明显流量,过短的空闲时间会造成周期性断线;普通网页连接则通常能接受较短的空闲回收。修改此值前,先观察问题是否总在固定空闲时长后发生。若连接在持续传输时也中断,应继续检查网络路径、服务器限制和传输层,而不是只调整策略。
uplinkOnly、downlinkOnly 与缓冲
uplinkOnly 和 downlinkOnly 用于半关闭状态下的连接回收。当一侧数据方向结束后,内核仍可等待另一方向完成剩余传输。等待过短可能截断响应尾部,过长则让已结束的连接保留更多时间。这类参数通常保持合理默认值即可,只有日志和抓取现象明确指向半关闭阶段时才需要调整。
bufferSize 影响每条连接的缓冲策略,含义和单位可能随内核实现而变化。更大的缓冲不等同于更快速度,在大量并发连接下还会增加内存占用。性能调优应先确认瓶颈来自 CPU、网络、协议握手还是应用读取速度,再决定是否改变缓冲。没有测量依据时,保持客户端或内核默认配置更稳定。
统计数据如何启用
system 下的统计开关决定是否记录入站和出站的上下行数据,同时通常需要顶层存在 stats 对象。用户级统计还要在对应等级中开启 statsUserUplink 与 statsUserDownlink。只写 stats: {} 不会自动产生全部维度;只打开策略开关而没有消费统计数据的接口,也不会在客户端界面凭空出现图表。
统计会增加一定的状态维护成本,是否启用应由实际观测需求决定。排查分流时,出站统计能帮助判断流量是否进入了代理、直连或拦截出口;排查单个用户时,用户级统计才有意义。个人桌面配置通常只需要出站维度,不必同时打开所有用户统计。图形客户端若已提供流量显示,应以其生成配置和读取机制为准,避免重复配置多个统计入口。
策略调整后的验证应覆盖三类连接:快速短连接、持续传输连接和长时间空闲后恢复的连接。仅打开一个网页无法判断空闲回收是否合理,也无法验证半关闭等待。若客户端每次保存节点都会重新生成配置,手工策略可能被覆盖,应把可用选项写入客户端自定义配置功能,或在每次更新订阅后重新核对生成结果。
日志、统计与运行状态
日志级别与文件输出
log 是配置排错的第一入口。常见级别从详细到简略包括 debug、info、warning、error 与 none,具体名称以当前内核支持为准。日常运行使用 warning 通常能保留关键异常,同时减少重复信息;定位规则或握手问题时可临时提高到 info 或 debug。问题复现完成后应恢复常用级别,避免大量日志占用磁盘和干扰后续检索。
access 与 error 可以指定访问日志和错误日志路径。使用相对路径时,其基准目录取决于内核启动位置,图形客户端、终端和系统服务可能各不相同。若配置显示已写入文件但实际找不到,应先检查进程工作目录与文件权限。路径所在目录需要已经存在,并允许当前用户写入;不要把日志路径指向安装包内部或临时解压目录。
{
"log": {
"access": "./logs/access.log",
"error": "./logs/error.log",
"loglevel": "warning",
"dnsLog": false
},
"stats": {}
}
怎样阅读一条连接记录
阅读日志时应按时间把同一连接的几个阶段串起来:入站接受连接、识别目标、路由命中、选择出站、解析服务器地址、建立传输、协议握手和关闭原因。单独看到“connection closed”信息并不能判断是节点失效、目标主动关闭还是路由拦截。需要结合同一时间附近的目标地址、入站标签和出站标签,确认关闭发生在哪一层。
日志中若只有入站记录而没有出站选择,应优先检查路由规则和配置加载;有出站选择但服务器地址解析失败,转向 DNS;远端 TCP 已建立但协议握手失败,核对用户、传输和安全参数;握手成功后特定目标失败,则继续检查目标路由、地址族和应用行为。按阶段定位能避免在多个模块之间反复试错。
访问日志与错误日志的分工
访问日志更适合回答“哪个目标通过哪个入口被处理”,错误日志更适合回答“处理为什么中断”。路由验证时,可以选择一个容易识别的测试域名,清空旧日志后只发起一次请求,再查看新记录。并发打开大量网页会产生后台请求、更新检查和媒体连接,目标混在一起后很难判断某条规则是否准确命中。
日志中的域名和 IP 可能来自不同阶段。嗅探识别出的域名用于规则匹配,DNS 返回的 IP 用于建立连接,最终访问日志显示哪一种取决于内核和日志位置。看到 IP 不代表域名规则一定没有执行,看到域名也不代表连接没有解析。需要结合 domainStrategy、嗅探设置和路由日志共同判断。
统计、API 与客户端界面
统计模块记录计数,API 或客户端界面负责读取和展示。若使用内核 API,通常还需要专用入站、服务标签和路由规则把 API 流量送到对应出站。该结构具有较强的内核差异和客户端管理边界,手工添加前应先确认客户端是否已经创建同名标签。重复的 API 入站端口会导致启动失败,重复的路由标签则可能让状态查询进入普通代理出口。
v2rayN 等图形客户端通常已经提供运行日志、核心日志和连接状态入口。排错时优先使用客户端展示的实际启动配置和错误信息,因为界面设置可能在启动前转换字段。手工编辑一份独立 JSON,但客户端实际加载另一份临时配置,是常见的信息错位。确认配置来源的方法是查看启动日志中的配置路径、监听端口和出站标签,再与正在编辑的文件逐项比对。
日志中的隐私与留存
访问日志可能包含域名、目标地址、本地账户标识和连接时间。启用详细级别前,应确认日志保存位置和使用范围;排错完成后及时降低级别并清理不再需要的调试文件。分享错误片段时,只保留与故障直接相关的阶段,并替换节点地址、用户标识、路径和账户字段。仅删除一行服务器地址并不够,因为相邻握手信息也可能暴露配置细节。
日志分析的目标是建立可重复的因果链,而不是收集越多内容越好。一次只复现一个问题,记录修改前后的差异,保留明确的时间点和测试目标。若更换节点、修改 DNS、调整路由和切换系统代理同时进行,即使问题消失,也无法确定哪个改动有效。稳定的排错记录应包含当前客户端、所用内核家族、入站方式、命中出站和最终错误阶段。
配置验证、迁移与故障排查
先过三层检查
配置验证应分成三层。第一层是 JSON 语法:括号、逗号、引号和字段类型必须正确。第二层是配置语义:协议字段是否被当前内核识别,标签引用是否存在,端口是否冲突。第三层是运行链路:入站是否收到流量、路由是否命中、出站是否建立、目标是否响应。三层不能互相替代;JSON 能被解析,只能说明文本结构成立,不能证明节点参数和路由结果正确。
部分内核提供配置测试模式,可在不长期运行服务的情况下读取配置并返回错误。命令形式会随内核与打包方式变化,应以客户端附带核心的帮助信息为准。桌面客户端更稳妥的方式是先使用界面中的检查、重启核心或查看启动日志功能。测试时确认命令调用的是客户端实际使用的核心文件,系统路径中的另一份核心可能支持不同字段。
v2ray run -test -config ./config.json
xray run -test -config ./config.json
若命令提示参数形式不受支持,先执行对应程序的帮助命令查看本地语法,不要据此判断配置内容错误。验证成功后再启动内核,并检查日志中是否出现预期监听端口。端口没有出现,说明运行配置、权限或端口占用仍有问题;端口出现但应用没有流量进入,则应回到系统代理或应用代理设置。
按模块进行二分排查
面对复杂配置,最快的方法不是逐字阅读全部字段,而是缩减到最小可运行链路。保留一个本地 SOCKS 入站、一个已知参数完整的代理出站、一个直连出站和空路由规则。先确认代理出口能够连接,再加入私有地址直连,随后加入域名分类、DNS 分流与拦截规则。每增加一层都留下可回退的配置副本。某一步出现故障,范围就限定在刚加入的模块。
若节点显示连接成功但网页打不开,按“应用接管、入站监听、节点连接、DNS、路由、系统代理”顺序检查。客户端状态只说明某个进程已启动或某次测试已完成,不代表当前浏览器流量确实进入该入站。最直接的判断是查看访问日志中是否出现测试目标;没有记录就先处理流量入口,有记录再分析出站。
订阅更新后的配置变化
订阅更新会刷新节点列表和部分节点参数,客户端还可能根据当前路由模式重新生成运行配置。手工改动临时文件通常无法长期保留。需要持久化的路由规则应写入客户端提供的自定义规则、预设配置或受支持的模板位置。更新后重点核对节点协议、传输方式、服务器名称、出站标签和规则顺序,尤其是从不同内核来源导入节点时。
单条 vmess:// 或 vless:// 分享链接通常表示一个节点,订阅地址则返回一份可更新的节点清单。两者在客户端中的导入入口和更新行为不同。相关区别可阅读分享链接与订阅地址的使用说明;若更新后没有节点或返回错误,可继续参考订阅更新失败排查与自动更新设置。
跨内核迁移的检查表
从 V2Fly 配置迁移到 Xray,或反向迁移时,应先保留两边都支持的基础结构:SOCKS 入站、常规直连出口、简单域名与 IP 路由。然后按协议逐项确认用户字段、传输层、安全层和流控设置。遇到未知字段时,不应直接删除整段安全配置并继续连接,因为字段可能是该节点成立的必要条件。正确做法是确认目标内核能否表达同一协议能力;不能表达时,选择匹配该节点的客户端和内核。
REALITY 节点通常应使用支持对应能力的 Xray 内核路线,Android 可优先考虑 v2rayNG;使用 V2Fly 配置与节点时,可按需求选择 v2flyNG。桌面端首推 v2rayN,并在核心设置中确认实际启用的内核。更完整的生态与内核关系可查看Project V、V2Fly、Xray 与客户端关系梳理以及Xray 与 V2Fly 内核选择参考。
| 故障阶段 | 典型表现 | 检查对象 |
|---|---|---|
| 配置加载 | 核心立即退出、未知字段、JSON 错误 | 语法、字段支持、标签引用 |
| 入站接管 | 核心运行但访问日志没有请求 | 本地端口、系统代理、应用设置 |
| 出站建立 | 连接超时或握手失败 | 节点地址、协议、传输、安全层 |
| 解析与路由 | 部分域名失败、出口与预期不符 | DNS、嗅探、规则顺序、地址族 |
| 目标访问 | 代理已建立但特定服务中断 | 目标端口、网络类型、应用行为 |
形成可维护的配置基线
一份长期可维护的配置应包含明确标签、有限的规则层级、可解释的 DNS 路径和适度日志。每次修改记录目的,而不是只记录字段值;例如“让局域网网段直连”比“增加 geoip 条目”更容易在以后判断是否仍然需要。规则应按拦截、特殊直连、特殊代理和兜底的逻辑分组,组内从具体到宽泛排列。
完成修改后至少验证本地地址、普通域名、直接 IP、TCP 请求和需要 UDP 的应用场景。再重启客户端一次,确认配置不是只在当前进程内临时生效。若依赖订阅,还应执行一次更新并检查自定义规则是否保留。快速使用流程可回到v2rayN 与 v2rayNG 配置教程,需要重新选择安装包时前往V2Ray 客户端下载页。