01 / STRUCTURE
JSON 结构与配置边界
先区分客户端设置与内核配置
V2Ray 生态中的图形客户端与代理内核承担不同职责。v2rayN、v2rayNG、v2flyNG 提供服务器管理、订阅更新、界面设置和启动控制;内核负责监听端口、建立连接、匹配路由和处理数据。界面上的一个开关可能生成多个 JSON 字段,也可能只改变系统代理而不写入内核配置。因此,排查时先确认问题发生在客户端、操作系统还是内核,不要只凭界面文字推断最终行为。
客户端通常会根据当前服务器与全局设置生成运行配置。这个文件可能位于工作目录或临时目录,重启后也可能被重新生成。直接编辑生成结果不一定能长期保存。需要持续生效的修改,应优先写入客户端提供的路由、DNS 或自定义配置入口。具体入口名称随客户端界面变化,判断依据是设置保存后实际运行的配置,而不是磁盘上某个恰好名为 config.json 的文件。
顶层对象与引用关系
基础配置以一个对象为根,inbounds 与 outbounds 是数组,允许定义多个入口和出口;routing、dns、policy 则是对象。入站把应用连接交给内核,路由决定连接选择哪个出站,出站再决定直接访问还是经远端服务器转发。DNS 为需要解析的环节提供结果,策略控制特定用户等级的超时或统计行为。它们不是互相独立的功能清单。
下面是一份可用于本地连通性实验的完整基础配置:应用通过 SOCKS 入口访问网络,内核使用直连出口,不包含远端代理服务器。它适合检查监听地址、端口和应用代理设置是否正确,不用于验证远端协议。运行前确认端口空闲,并使用所选内核支持的配置入口加载;在图形客户端中,应使用自定义配置功能,而不是把整份 JSON 粘贴到服务器地址栏。
{
"log": {
"loglevel": "warning"
},
"inbounds": [
{
"tag": "local-socks",
"listen": "127.0.0.1",
"port": 10808,
"protocol": "socks",
"settings": {
"auth": "noauth",
"udp": true
}
}
],
"outbounds": [
{
"tag": "direct",
"protocol": "freedom",
"settings": {}
}
],
"routing": {
"domainStrategy": "AsIs",
"rules": []
}
}
语法正确不等于配置正确
严格 JSON 的键名和字符串必须使用双引号,布尔值写作 true 或 false,最后一个数组成员后面不加逗号。端口通常是数字,而不是为了视觉统一全部写成字符串。部分配置加载器允许注释或额外语法,但复制到其他客户端时未必保留这种兼容性。本页示例使用不带注释的 JSON,说明文字放在代码块外,便于分辨可解析内容与解释内容。
tag 是配置内部的引用名称,不是协议名,也不是必须与界面服务器备注相同的名称。路由中的 outboundTag 必须对应实际出站,拼写、大小写和连字符都应一致。准备复杂配置时先列出标签关系,再补协议字段。一个对象内部不要重复定义同名键;不同解析器处理重复键的结果可能不同,不能把重复键当成覆盖机制。
阅读顺序可以沿连接路径展开:先确定入口接收了什么,再确认出口能否建立连接,随后处理路由与 DNS。不要一次引入所有章节的字段。基础路径稳定后,每次增加一个对象或一条规则,记录预期变化与实际结果。这样的配置更容易回退,也能避免把语法错误、引用错误和网络问题混在同一轮测试中。
02 / INBOUNDS
inbounds:本地入站监听
监听地址决定接入范围
inbounds 描述内核接收连接的入口。桌面客户端常见的是 SOCKS 和 HTTP 代理入口,应用必须使用匹配的协议连接到指定地址与端口。listen 写为 127.0.0.1 时,仅允许本机通过这个 IPv4 回环地址访问。它不是服务器地址,也不是远端节点的出口地址。只供本机应用使用时,保留回环监听通常更容易控制接入范围。
将监听改为 0.0.0.0 表示监听所有本地 IPv4 接口,不等于开启所有系统防火墙规则,也不代表网络中的其他设备一定能够到达该端口。若确实需要局域网接入,还要检查设备地址、防火墙入站规则、网络隔离与认证设置。回环地址属于访问发起设备自身;手机填写电脑代理时,不能用手机上的回环地址代替电脑的局域网地址。
SOCKS 与 HTTP 入口的分工
下面的片段用于替换基础配置的 inbounds 数组。两个入口使用不同端口和标签,出口与路由沿用原配置。SOCKS 入口启用 UDP 支持,但应用本身仍要通过相应机制发起 UDP 代理请求;HTTP 入口适合只提供 HTTP 代理设置的应用。两个入口同时存在,不意味着同一个应用会自动在它们之间切换。
[
{
"tag": "local-socks",
"listen": "127.0.0.1",
"port": 10808,
"protocol": "socks",
"settings": {
"auth": "noauth",
"udp": true
},
"sniffing": {
"enabled": true,
"destOverride": ["http", "tls"]
}
},
{
"tag": "local-http",
"listen": "127.0.0.1",
"port": 10809,
"protocol": "http",
"settings": {}
}
]
| 字段 | 作用 | 检查重点 |
|---|---|---|
listen | 本机监听地址 | 回环与局域网接入范围 |
port | 监听端口 | 是否占用、调用端是否一致 |
protocol | 入口协议 | SOCKS 与 HTTP 不混用 |
tag | 入口标识 | 供路由的入站条件引用 |
sniffing | 协议与目标信息探测 | 是否确有域名匹配需求 |
嗅探不是 DNS 的替代品
sniffing 可以从部分连接的协议内容中提取域名线索,例如 HTTP 主机名或 TLS 握手中的服务器名称。它不能保证恢复每条连接的原始域名,也不会解密应用内容。启用后的目标处理还受内核支持的具体字段影响,因此不能简单把“开启嗅探”理解为“所有域名规则都能命中”。遇到已经只剩 IP 的连接,应先查应用如何完成解析。
destOverride 指定允许用于目标覆盖的协议类型。目标覆盖与只用于路由判断不是完全相同的行为;部分内核提供额外字段控制这一点,不能把扩展字段直接套到所有内核。若服务依赖原始目的地址,或者同一 IP 上存在特殊连接逻辑,修改嗅探后应单独验证。没有明确需求时,先使用最少的探测类型,避免无目的地增加配置变量。
端口、系统代理与接管方式
端口占用错误出现在监听阶段,与远端服务器是否在线无关。处理时先退出重复运行的客户端,确认当前进程使用的端口,再决定是否更换。修改入站端口后,浏览器、开发工具和系统代理里的对应端口也要同步修改。只改内核而保留旧的系统代理地址,会表现为应用连接被拒绝,此时反复更新订阅并不能解决问题。
系统代理只是告诉遵循系统设置的应用去使用某个代理入口,不保证全部应用都经过内核。TUN 类接管方式还涉及虚拟接口、系统路由与权限,不能用新增一个 SOCKS 入站代替。Android 客户端的系统接管也由客户端与平台机制共同完成。判断流量是否进入内核,应观察实际连接记录,而不是只检查界面上的系统代理开关。
验证入口时固定一个测试应用和一个已知可访问的目标,先观察是否产生连接,再观察是否选择了预期出口。若没有任何连接记录,重点检查应用是否使用代理、地址协议是否正确以及是否仍缓存旧设置;若已经产生连接,排查范围应移向出站和路由。有关首次设置的操作顺序,可对照v2rayN 初始配置要点。
03 / OUTBOUNDS
outbounds:出站协议与标签
出站描述下一跳连接
outbounds 决定内核如何处理已经接收的连接。freedom 表示直接建立目标连接,blackhole 用于阻断,VLESS 等代理协议则把连接交给配置中的远端服务器。一个出站并不是一条具体路由规则:同一个出站可以被多条规则引用,某条规则也可以匹配多个域名后统一选择同一出口。这样可以把协议参数与流量分类分开维护。
未命中路由规则时,常规配置使用出站数组的第一项作为默认出口。因此,数组顺序具有实际含义。把 direct 放在第一项并不只是调整显示顺序,它可能改变所有未命中流量的处理结果。准备配置时,应先明确默认行为,再添加例外规则。需要默认代理时,把可用代理出站放在前面;需要默认直连时,则明确保留直连作为第一项。
直连与阻断可以独立检查
下面的数组可用于直连和阻断实验,替换基础配置中的 outbounds 即可。两个标签供路由引用,默认仍是第一项直连。blackhole 是主动丢弃连接的出口,不是备用线路,也不会自动寻找其他可用服务器。若把它用于某个测试域名,应用看到连接失败是预期行为,应结合路由记录确认命中,而不是据此判断整个客户端故障。
[
{
"tag": "direct",
"protocol": "freedom",
"settings": {}
},
{
"tag": "block",
"protocol": "blackhole",
"settings": {}
}
]
VLESS 参数必须与服务器一致
以下是 VLESS 出站对象的结构示例,不是可直接连接的公共服务器。your-server.example 是教学用域名,示例 UUID 也仅用于展示格式;使用时必须替换为合法持有的服务器参数。这个对象包含 TCP 与 TLS 设置,远端也必须提供相同组合。将它加入数组并不能让已有的其他协议服务器自动接受 VLESS 连接。
{
"tag": "proxy",
"protocol": "vless",
"settings": {
"vnext": [
{
"address": "your-server.example",
"port": 443,
"users": [
{
"id": "00000000-0000-4000-8000-000000000001",
"encryption": "none",
"level": 0
}
]
}
]
},
"streamSettings": {
"network": "tcp",
"security": "tls",
"tlsSettings": {
"serverName": "your-server.example",
"allowInsecure": false
}
}
}
address 是连接服务器的地址,port 是服务器监听端口,id 是协议用户标识。VLESS 用户对象中的 encryption 与传输安全层并非同一设置;写成 none 不代表外层 TLS 被关闭。相反,传输安全由 streamSettings.security 等字段决定。不要把多个名称相近的“加密”选项合并理解,否则容易出现协议能导入但连接无法建立的情况。
用户对象中的 level 可以与 policy.levels 建立关联,它不是节点优先级,也不控制路由规则顺序。flow 等扩展参数只有在服务端、内核及传输组合均支持时才使用;不能仅因为导入链接里出现过某个值,就给全部服务器统一补上。导入后应核对地址、端口、用户标识、传输方式和安全层,尤其关注客户端是否提示未知字段。
协议选择与客户端选择分开判断
客户端名称不等于协议能力清单。桌面端优先使用 v2rayN;Android 可根据实际内核需求选择 v2rayNG 或 v2flyNG。能否使用某种扩展,最终取决于当前内核与配置组合,而不是客户端备注里出现了协议名称。选择依据可参阅三款客户端的内核差异,安装入口统一在下载页。
出站故障要分成服务器不可达、协议认证失败和传输握手失败三类。地址或端口错误通常发生在建立底层连接时;用户标识不匹配发生在协议处理阶段;TLS 名称错误则属于安全层。先依据日志确定阶段,再核对对应字段。一次同时替换地址、用户标识和传输方式,即使恢复连接,也无法确认真正原因,不利于后续维护。
04 / STREAM SETTINGS
传输方式与 TLS 安全层
把协议、传输和安全层拆开看
代理协议说明双方如何组织代理请求,传输方式说明这些数据通过何种通道承载,安全层则处理握手、身份验证与加密连接。三者通常共同出现在一个出站对象中,但不能任意组合。界面里同为 VLESS 的两个服务器,可能分别要求不同传输与安全层;复制其中一个服务器的传输参数到另一个服务器上,可能在协议认证之前就失败。
streamSettings.network 用于选择传输类型,对应的设置对象继续描述具体参数。TCP 的结构相对直接,WebSocket 则通常还需要路径,并可能涉及 HTTP 主机名。远端若经过反向代理,公开端口和路径由服务端部署共同决定。客户端填写的每个值都应有服务端依据,不能通过随意尝试常见路径来替代参数核对。
WebSocket 示例的字段分层
下面的对象用于说明常见 WebSocket 与 TLS 组合,应替换出站内的整个 streamSettings,不能替换顶层配置。域名与路径均为教学示例。address 仍位于协议的服务器对象中,负责确定实际连接目的地;这里的主机名、服务器名称和路径则服务于上层握手。实际部署若要求不同值,应逐项填写,不能假定三处总是相同。
{
"network": "ws",
"security": "tls",
"tlsSettings": {
"serverName": "your-server.example",
"allowInsecure": false
},
"wsSettings": {
"path": "/proxy",
"headers": {
"Host": "your-server.example"
}
}
}
| 字段 | 所在层次 | 作用 |
|---|---|---|
address | 协议服务器对象 | 确定底层连接目标 |
serverName | TLS 设置 | 服务器名称与证书名称验证 |
Host | WebSocket 请求头 | HTTP 虚拟主机选择 |
path | WebSocket 设置 | 匹配服务端请求路径 |
security | 传输设置 | 选择传输安全层 |
证书报错先检查名称和时间
TLS 连接需要验证证书的适用名称与有效时间。系统时间明显偏差、服务器名称与证书不符、证书链部署不完整,都可能导致握手失败。使用 IP 连接时,若证书签发给域名,仍需依据服务端要求填写正确的服务器名称。不要把服务器地址、HTTP 主机名与证书名称视为可以相互替换的同义字段,它们可能恰好相同,但职责不同。
allowInsecure 控制是否跳过证书验证中的相应检查,不是修复证书部署的选项。本页示例保持 false。出现证书错误时,先同步系统时间,再核对服务器名称、证书覆盖范围和服务端证书链。长期关闭验证会改变连接的身份验证条件,也会掩盖名称填写错误。排查步骤可对照TLS 握手与证书报错说明。
扩展字段与连接复用的边界
REALITY 属于特定内核支持的安全层方案,不能当作普通 TLS 配置的别名。它的服务端名称、公钥及其他配套参数需要按实际服务端要求成组填写,不能只把 security 字符串改掉。类似地,某些传输名称与扩展设置在内核之间存在差异。先确认实现与支持范围,再迁移配置;遇到未知字段提示,不要仅删除提示字段后继续假定行为相同。
Mux 多路复用尝试在一定条件下复用底层连接,它既不是分流功能,也不会修正协议参数。是否适合启用取决于协议、服务端支持、应用连接模式及当前内核限制。排查单连接失败时,先保持复用关闭,确认基础连接稳定,再单独测试。不要把复用与传输层自身已有的复用能力混为一谈,也不应同时调整复用、DNS 和路由后比较结果。
传输排查应固定同一服务器和同一测试目标,按底层连接、TLS 握手、传输握手、代理请求的顺序判断。连接超时通常需要先检查地址与可达性;已收到证书错误就应转向名称和证书;WebSocket 路径不符则需要检查请求转发规则。日志提供的是失败阶段的线索,不是完整结论,必须与服务端参数和客户端实际生成配置交叉确认。
05 / ROUTING
routing:规则匹配与出口选择
顺序与默认出口先于规则数量
routing.rules 按配置顺序检查规则,命中后通常采用该规则指定的出口,不会为了寻找“更精确”的域名继续遍历。把宽泛规则放在前面,可能使后面的细分规则永远无法命中。维护规则时先写明确的特殊例外,再写较大范围的分类,最后保留清楚的默认出口。规则多不代表覆盖正确,顺序不清晰反而会增加解释成本。
同一条规则内,多个不同条件字段通常需要同时满足;一个条件数组中的多个候选值则用于该字段的替代匹配。例如同时设置 inboundTag 与 domain,意思是来自指定入口且目标域名符合条件,而不是两者任意满足即可。需要表达两组独立例外时,拆成两条规则通常比构造复杂条件更容易检查。
域名策略与域名匹配不是同一个设置
domainStrategy 决定路由匹配过程中何时为域名获得 IP。AsIs 保留目标现有形式;IPIfNonMatch 在域名未匹配时尝试解析并进行 IP 规则判断;IPOnDemand 则在匹配过程需要 IP 信息时触发解析。它不负责给所有应用强制设置 DNS,也不会凭空恢复应用已经解析掉的原始域名。选择策略时,要同时考虑输入目标的实际形式。
下面的对象可替换顶层 routing,要求出站中已定义 direct。私有地址使用普通 IP 网段表示,便于看清匹配条件;域名例外使用保留示例域名。未命中时仍回到第一个出站,因此若基础配置只有直连,整个示例并不会产生代理出口。要实现其他默认行为,必须同时配置实际可用的对应出站。
{
"domainStrategy": "IPIfNonMatch",
"rules": [
{
"type": "field",
"ip": [
"10.0.0.0/8",
"172.16.0.0/12",
"192.168.0.0/16"
],
"outboundTag": "direct"
},
{
"type": "field",
"domain": [
"full:example.com",
"domain:example.org"
],
"outboundTag": "direct"
}
]
}
匹配前缀决定覆盖范围
full:example.com 用于完整域名匹配;domain:example.org 用于该域名及其子域名;regexp: 引入正则表达式,必须注意 JSON 字符串的反斜杠转义。没有前缀的字符串可能使用内核定义的关键字匹配行为,不适合在不明确范围时替代完整域名。需要准确控制一个主机时,优先使用含义明确的前缀,再按真实请求补充子域名。
geosite: 引用域名分类资源,geoip: 引用 IP 分类资源,例如常见的 geosite:cn 与 geoip:private。它们不是在线自动查询指令,运行环境需要提供匹配的数据文件,且文件中应包含对应分类。分类名称、数据内容与更新状态都可能影响结果。遇到分类找不到或规则加载失败,应检查资源与内核,而不是把错误归因于目标网站。
从请求条件反推规则
调试时记录入口标签、目标是域名还是 IP、目标端口及预期出口,然后从第一条规则逐项检查。若域名规则没有命中,先确认内核确实拿到了域名;若 IP 规则没有命中,再检查解析时机、返回地址族与网段范围。不要在没有证据时直接追加一条宽泛规则,因为它可能暂时覆盖问题,却同时改变其他连接的出口。
修改规则只影响新建连接的选择,已有的长连接可能继续沿用原路径。测试前应关闭测试应用中的相关连接或重新发起请求,避免把旧连接结果当成规则未生效。更完整的语法与顺序示例见自定义路由规则写法;需要查术语时,可转到术语表理解域名分类、地址网段与出口标签的区别。
06 / DNS
dns:解析来源与查询路径
先确定是谁发起解析
一次应用请求可能涉及多处解析:应用自己解析目标域名,操作系统解析服务器地址,内核为路由匹配解析目标,或者出站在建立连接时请求解析。顶层 dns 只影响调用内置解析器的相关环节,不会自动接管所有应用的 DNS 请求。浏览器或其他应用若使用独立的加密解析功能,也可能走自己的连接路径,不能仅通过修改内核 DNS 就推断其行为已改变。
排查前先写清楚问题对象:是代理服务器域名无法解析,还是目标网站域名无法解析;是解析失败,还是返回地址可解析但不可达;是系统解析异常,还是仅路由匹配阶段异常。这些情况需要检查的设置不同。服务器域名的解析属于建立代理连接之前的依赖,目标域名解析则可能发生在本地或远端,不能把两者合并成一个“DNS 不通”的结论。
hosts、servers 与地址族
下面是顶层 dns 的结构示例。hosts 为教学域名指定文档用地址,适合说明静态映射格式,不是可访问的服务。两个数值解析器地址用于展示服务器数组的写法,实际应选择当前网络能够到达、符合使用需求的解析服务。将这个对象加入配置后,还要有调用内置解析器的相关行为,才能观察到它的作用。
{
"hosts": {
"example.test": "192.0.2.10"
},
"servers": [
"1.1.1.1",
"8.8.8.8"
],
"queryStrategy": "UseIP"
}
hosts 适合明确、稳定的映射,不适合长期硬写频繁变化的业务地址。目标可能使用多个地址、按地区调度或调整证书与服务入口,过期映射会绕开正常解析结果。排查完成后应移除临时映射,并检查是否仍有系统 hosts 文件或客户端其他 DNS 设置产生覆盖。否则即使修改了解析服务器,请求仍可能继续使用旧的静态结果。
queryStrategy 控制查询地址族,常见值包括 UseIP、UseIPv4 和 UseIPv6,具体支持以当前内核为准。它不是给操作系统启用或关闭 IPv6 的开关。网络没有可用 IPv6 路径时,返回 IPv6 地址与成功建立 IPv6 连接是两回事;同样,只查 IPv4 也不会修复代理服务器本身的连通性问题。先确认地址族和路由实际可用,再调整查询范围。
解析流量也有出口依赖
内核发起的 DNS 查询通过什么路径发送,取决于解析器类型、内核实现与相关路由设置。普通远程查询、系统解析调用及某些带本地语义的解析方式,并不保证经过同一套分流。配置加密 DNS 时,还会增加解析器主机名、TLS 名称和连接可达性的依赖。只看到地址使用加密查询格式,不能据此判断查询最终从哪个出口离开。
特别需要避免循环依赖:代理服务器使用域名,而解析这个域名的查询又被要求通过尚未建立的同一代理;或者加密解析器的域名只能由该解析器自身解析。处理思路是为启动阶段提供可达的解析路径,必要时使用明确的引导解析或服务端认可的连接地址。不要直接把所有 DNS 相关地址都指向代理出口,再期待内核自动解决依赖环。
| 现象 | 先检查 | 不要直接推断 |
|---|---|---|
| 服务器域名解析失败 | 启动解析路径、系统网络 | 目标网站的路由错误 |
| 域名可解析但连接超时 | 返回地址、地址族与出口 | 解析服务器一定故障 |
| 修改后仍返回旧地址 | 应用、系统与内核缓存 | 新设置没有保存 |
| 只有部分应用异常 | 应用自己的解析与代理设置 | 全部流量使用同一 DNS |
缓存与分流一起验证
DNS 缓存可能存在于应用、系统、内核和上游解析器。调整配置后,即使重启内核,应用仍可能复用缓存或旧连接。测试时固定一个域名,记录返回地址与连接出口,再分别确认缓存来源。不要同时清空全部设置并更换多处解析器,这会让前后结果失去可比性。对多地址服务,单次查询的差异也不一定表示配置不稳定。
域名规则与 IP 规则共同存在时,应把 DNS 看作路由的输入来源,而不是单独的优化开关。域名先命中规则时可能无需本地解析;进入 IP 判断后,解析结果又可能改变出口选择。因此,设计分流时应同时写出“何时解析”和“解析后如何匹配”。若目标只是修复一个域名的异常,先做局部测试,再决定是否推广到全局配置。
07 / POLICY & LOG
policy:连接策略、日志与统计
用户等级是策略索引
policy 用于定义连接处理与统计相关策略。levels 以用户等级作为索引,协议用户对象中的 level 可以关联到相应策略。这个等级不是账户权限排名,不代表服务器性能,也不控制路由优先级。只有当具体协议与连接使用了对应等级,相关配置才会发挥预期作用;给一个没有被引用的等级填写参数,不会自动改变全部连接。
等级键在 JSON 对象中写成字符串,例如 "0",协议用户的等级字段则通常是数字。名称看似相近,但所在位置和类型不同。维护多个等级时,应为每个等级记录使用对象与调整目的,避免只保留一组难以解释的数字。大多数普通客户端使用场景无需频繁改动策略,保持默认行为比套用来源不明的“通用优化参数”更容易排查。
超时字段作用于不同阶段
下面的对象展示常见策略字段,可作为顶层 policy 的参考。数值单位为秒,表示示例策略而非统一推荐。handshake 控制相应握手阶段的时间预算,connIdle 与空闲连接有关,uplinkOnly 和 downlinkOnly 则处理单向仍活动的阶段。它们不能简单理解为同一个总连接超时,具体生效位置还受协议实现影响。
{
"levels": {
"0": {
"handshake": 4,
"connIdle": 300,
"uplinkOnly": 2,
"downlinkOnly": 5,
"statsUserUplink": false,
"statsUserDownlink": false
}
},
"system": {
"statsInboundUplink": false,
"statsInboundDownlink": false,
"statsOutboundUplink": false,
"statsOutboundDownlink": false
}
}
过短的空闲策略可能让交互终端、通知连接或暂时没有数据的会话更频繁重建;过长的策略也可能让无用连接保留更久。应用自身还有心跳、读写超时与重连逻辑,因此观察到定期断开时,要同时比较应用设置与内核日志。不要只因为断开间隔接近某个策略数值,就认定已经找到原因,网络设备与远端服务也可能有独立超时。
握手失败应先检查协议、地址和安全层参数,而不是立即拉长握手时间。参数不匹配不会因为等待更久而正确;对网络确实较慢的环境,适当增加时间预算可能有帮助,但应以可重复测试为依据。调整时只改变一个字段,并记录开始握手与报错阶段。若故障出现在传输握手之前,修改应用数据阶段的空闲策略通常没有针对性。
日志等级决定记录粒度
日志设置位于顶层 log,并不写在 policy 内。日常可使用 warning,需要定位时短期改为 info 或更详细的等级。下面的对象只设置记录粒度,输出位置由客户端与内核运行方式决定。未指定磁盘路径时,不应假定日志已经保存在某个固定目录;先查看客户端日志面板或其明确提供的日志文件入口。
{
"loglevel": "warning"
}
连接记录中可能包含目标域名、IP、入口标签与错误原因。公开排错信息前,应移除订阅地址、用户标识和个人路径等不必要内容。为了保留排错价值,可以用一致的示例标签代替敏感名称,但应保留错误阶段、字段类型和各标签之间的引用关系。只截取一行“连接失败”往往不足以说明问题,前后的初始化与握手信息同样重要。
统计开关不等于统计界面
策略中的统计开关表示是否收集相应计数,不会凭空创建客户端图表。读取统计还需要内核统计设施、接口以及客户端支持等配套配置。某些用户统计依赖协议用户的识别信息,不能认为打开系统统计就能自动获得每个应用或每个服务器的独立数据。只需要定位连接失败时,通常先查看日志,不必为此额外启用整套接口。
日志与统计属于观察工具,不是连接成功的前置条件。错误的策略调整可能让问题更复杂,而缺少图表也不代表代理未运行。配置完成后先验证实际请求,再根据维护需求选择记录粒度。若客户端已经提供统计功能,优先使用其既有入口,避免重复开放不需要的管理接口。详细记录完成后恢复日常日志等级,并清理不再需要的临时诊断文件。
08 / APPLY & DIAGNOSE
配置应用、订阅管理与分层排错
先建立可回退的修改流程
应用新配置之前,保存当前可工作的客户端设置和自定义配置副本,记录这次修改涉及的字段与预期行为。备份应放在自己能够识别的位置,不与客户端临时运行文件混用。恢复时要同时考虑服务器选择、系统代理、路由模式和 DNS 设置,仅还原一段 JSON 不一定能恢复整个客户端状态。一次修改的范围越清楚,回退越可靠。
配置的实际来源可能有多层:订阅提供服务器参数,客户端全局设置提供入口与路由模板,自定义配置又可能覆盖部分字段。排查时确认当前启动的是普通服务器配置还是完整自定义配置,以及哪个入口拥有最终决定权。如果启动模式不同,同一个界面开关可能不再影响运行结果。不要把未使用的自定义文件反复修改后,误判为内核没有读取配置。
订阅不等于完整运行配置
订阅通常用于分发服务器条目或分享信息,不保证携带本地监听、系统代理、路由与 DNS 的完整策略。更新订阅后,服务器名称、地址和可选参数可能发生变化,而本地自定义分流是否保留取决于客户端实现。订阅地址本身也应视为需要妥善保管的信息,不放进公开截图、文章或故障讨论中。导入成功只证明客户端识别了内容,不能证明每项服务器参数都适用。
多设备同步时,应区分共享服务器来源与同步设备设置。电脑和手机可以使用同一合法订阅,但监听端口、系统接管方式和网络权限不必相同。整份桌面运行配置不宜直接覆盖到移动客户端。若需要迁移,先同步服务器条目,再按设备单独检查入口、路由和 DNS;操作方案可参阅订阅、分享链接与配置导出的同步说明。
沿连接阶段定位失败
第一阶段检查加载与启动。若出现 JSON 解析错误,先定位附近的引号、逗号和括号;若提示字段不支持,检查内核与字段归属;若提示监听失败,检查端口占用和权限。这些问题都发生在实际代理请求之前,暂时不需要调整远端服务器。修复后确认内核保持运行,再继续下一阶段,避免在进程已经退出时测试网络。
第二阶段检查请求是否进入内核。选择一个明确配置代理的测试应用,重新发起连接并查看日志。没有记录时,核对应用代理协议、回环地址与端口,并检查系统代理是否仍指向旧入口。已经有记录但出口不符合预期时,转向路由顺序、入口标签和目标形式。此时反复重装客户端通常不能替代对实际请求路径的确认。
| 阶段 | 典型现象 | 优先检查 |
|---|---|---|
| 加载配置 | 启动即退出 | JSON、字段支持、标签引用 |
| 监听入口 | 端口绑定失败 | 重复进程、地址、权限 |
| 应用接入 | 没有请求记录 | 应用代理与系统接管 |
| 选择出口 | 命中非预期出站 | 规则顺序、目标形式、默认出口 |
| 建立远端连接 | 超时或握手报错 | 服务器地址、协议、传输安全 |
| 访问目标 | 仅部分服务异常 | DNS、地址族、目标规则与应用行为 |
第三阶段检查远端与目标。连接服务器失败时核对地址、端口和启动解析;握手失败时核对协议用户、传输路径及证书名称;服务器已连接但部分目标异常时,再检查目标 DNS、规则和地址族。应使用多于一个目标区分局部服务故障与全局配置问题,但每轮测试保持其他变量不变。一次成功只证明当前路径可用,不足以证明所有规则均符合预期。
修改后的验收与清理
验收至少覆盖本机入口、默认出口、明确直连例外和一个预期被阻断的测试条件;没有配置阻断时,不必为了验收额外增加。每项检查都应写明输入条件与预期出口,并通过新连接验证。长连接与缓存可能保留旧结果,因此应重新建立测试会话。确认配置保存后,再通过客户端正常重启一次,检查运行配置是否仍与修改一致。
最后恢复日常日志等级,删除临时 hosts 映射与实验规则,保留简短的变更记录。首次使用仍应回到快速上手文档完成客户端操作主线;字段查阅则按本页目录逐段核对。配置维护的核心不是积累更多开关,而是让入口、解析、路由与出口之间的关系始终能够被说明、被验证,并在失败时准确回退。