JSON 配置参考
从本地入站到出站选择,按字段查阅配置结构、执行顺序和客户端接管范围。
首次配置建议先完成使用指南中的导入、模式选择和连接验证。本页用于系统查阅:解释配置为什么生效、哪些字段互相依赖,以及修改后怎样定位错误。桌面操作优先以 v2rayN 为例;安装入口见客户端与平台下载。
JSON 结构与处理路径
先区分客户端与内核
v2rayN、v2rayNG、v2flyNG 提供配置管理界面;内核负责监听端口、处理协议和转发连接。界面里的节点记录通常不是完整内核配置。客户端会把节点、路由模板、本地监听和运行选项组合成运行文件。因此,修改某个临时生成的 JSON,并不意味着下次启动仍会保留。阅读前先确认正在查看的是节点资料、自定义配置,还是客户端生成的运行配置。
V2Fly 与 Xray 的配置有共同来源,但不能视为完全相同的接口。协议支持、传输字段、DNS 扩展和默认行为可能不同。本文优先使用两者常见的结构,涉及具体协议时明确说明边界。不要把不同内核的示例各截一段拼起来,再通过反复删除报错字段让它启动;启动成功只能证明配置被接受,不能证明连接路径符合原意。
最小本地测试配置
下面的配置监听本机回环地址,提供一个 SOCKS 入站,并把收到的连接直接发向目标。它用于验证配置结构、端口和应用代理设置,不用于测试远端节点。运行前确认端口空闲;若客户端已经生成同名监听,应在客户端支持的自定义配置入口中单独测试,避免两个进程争用同一端口。
{
"log": {
"loglevel": "warning"
},
"inbounds": [
{
"tag": "socks-local",
"listen": "127.0.0.1",
"port": 10808,
"protocol": "socks",
"settings": {
"auth": "noauth",
"udp": true
}
}
],
"outbounds": [
{
"tag": "direct",
"protocol": "freedom",
"settings": {}
}
]
}
连接的处理路径可以概括为:应用连接入站,入站识别目标,路由选择出站,出站建立连接。DNS 参与域名解析,但不是所有请求都必然经过配置中的内置 DNS;日志和策略则分别负责记录问题、控制连接行为。把这些职责分开,才能判断错误发生在入口、决策还是出口,而不是把所有无法访问都归因于节点。
对象、数组与数据类型
顶层是一个对象。inbounds 与 outbounds 是数组,因为可以同时声明多个入口和出口;routing、dns、policy 通常是对象。数组顺序可能具有业务含义,例如路由规则的先后;对象字段顺序通常不决定执行顺序。调换顶层配置段的位置,不会让 DNS 比路由更早或更晚执行。
严格 JSON 使用双引号包围字段名和字符串,不允许尾随逗号或注释。端口等数字不应随意改成字符串,布尔值应写成 true 或 false。不同加载器可能容忍部分宽松语法,但可移植配置应遵循严格 JSON。尤其要避免同一对象内重复字段:某些解析器只保留最后一个值,造成文件能读入、前面的设置却被覆盖。
tag 是配置内部引用名称,不是协议类型。出站可以叫 direct,也可以叫其他名称;路由必须引用完全一致的字符串。大小写、空格和拼写差异都可能造成引用失败。建议在纸面先列出入站标签和出站标签,再编写规则。每次只修改一个配置段,并保存可恢复副本,比一次替换整个运行文件更容易判断问题来源。
inbounds 入站配置
监听地址决定入口范围
入站定义内核怎样接收连接,不决定连接最终走哪个服务器。listen 是绑定的本地地址,port 是监听端口,protocol 指定入口协议。仅供当前设备使用时,优先绑定 127.0.0.1。它与远端服务地址没有关系,不能把订阅里的服务器域名填到这里;那会尝试绑定一个不属于本机的地址,通常导致监听失败。
绑定 0.0.0.0 会监听所有本机 IPv4 接口,可能让同一网络中的其他设备访问入口。是否可达还取决于防火墙和网络隔离,但不能把防火墙当作配置认证。确需局域网共享时,应同步限制允许的来源、设置适当认证,并核对监听接口。不要为了排查连接失败,先把所有入口开放到全部网卡;这会引入新的访问范围问题。
| 字段 | 职责 | 检查重点 |
|---|---|---|
tag | 标识入口 | 与路由的 inboundTag 一致 |
listen | 绑定本地地址 | 本机使用优先回环地址 |
port | 监听端口 | 与应用设置一致且未被占用 |
settings | 协议专用参数 | 不能跨协议直接套用 |
sniffing | 尝试识别流量目标 | 区别识别结果与实际连接目标 |
SOCKS 与 HTTP 入口
SOCKS 入站适合支持 SOCKS 代理的应用,HTTP 入站适合使用 HTTP 代理设置的应用。两者的地址都可能是本机地址,但协议不能混用。应用填写的是 HTTP 代理,却指向 SOCKS 监听端口时,TCP 连接可能已经建立,后续握手仍会失败。此时更换远端节点通常没有作用,应先检查应用选择的代理类型与入口协议是否一致。
{
"inbounds": [
{
"tag": "http-local",
"listen": "127.0.0.1",
"port": 10809,
"protocol": "http",
"settings": {}
}
]
}
这段 HTTP 入站可以与第一章的 SOCKS 入站并列存在,但必须合并到同一个 inbounds 数组,不能在顶层再放一个同名字段。两个入口应使用不同端口。客户端界面可能自动管理这些端口,此时应优先在界面修改,而不是只改临时文件。应用端口、客户端设置与运行日志中的实际监听位置需要相互对应。
SOCKS 设置中的 udp: true 只表示该入口允许相应 UDP 转发能力,不代表所有应用的 UDP 都会自动进入内核。应用必须支持相应代理方式,后续出站和远端服务也必须支持。传统系统 HTTP 代理并不会接管全部 UDP。判断语音或其他 UDP 应用的问题时,应先确定流量是否进入,而不是只看入口里有没有这个布尔字段。
嗅探与路由的边界
sniffing 可以尝试从受支持的协议握手中识别域名,常见识别类型包括 HTTP 与 TLS。它不是对全部流量内容的通用解析,也不能保证每条连接都有域名。应用若直接连接 IP,且握手里没有可识别的主机名,域名规则仍可能无法匹配。因此不能把启用嗅探当作域名分流必然成功的保证,应结合访问日志确认实际识别结果。
某些内核支持让嗅探结果仅参与路由,而不替换实际连接目标,相关字段及行为应查当前内核规范。这里不把这些扩展写入通用示例。需要时先明确目标:是为了补充路由依据,还是要改变连接目的地。两者混淆会导致日志看似匹配正确域名,实际解析或连接却发生变化,尤其容易影响本地服务和特定 IP 访问。
outbounds 出站配置
出口与默认选择
出站描述内核如何处理已经接收的连接。可以直接连接目标,也可以通过远端代理服务转发,还可以主动丢弃。没有规则匹配时,通常使用 outbounds 数组中的第一个出站。因此,数组第一个对象不是纯粹的排版位置,而是默认行为的一部分。把直连对象移到首位,可能让此前未覆盖的连接改为直接访问。
tag 为每个出口提供可引用名称,protocol 决定采用哪个出站协议,settings 的结构随协议变化。路由中的 outboundTag 引用标签,而不是协议名。一个配置里可以有多个采用相同协议的出站,但标签应保持唯一,否则无法清楚表达规则引用,客户端的生成逻辑也可能覆盖原有对象。
{
"outbounds": [
{
"tag": "direct",
"protocol": "freedom",
"settings": {}
},
{
"tag": "block",
"protocol": "blackhole",
"settings": {}
}
]
}
freedom 表示由当前设备直接连接目标,不能据此推断请求一定使用哪台 DNS。blackhole 表示丢弃匹配连接;应用可能表现为超时或连接失败。上面的片段单独使用时,默认出口是直连,阻断出口只有被规则选中才会使用。声明了一个出口不等于流量自动会经过它,必须同时检查默认顺序或路由引用。
远端节点参数不能互相推算
VMess、VLESS、Trojan 等代理出站需要与服务端约定匹配。服务器地址、端口、身份信息、传输方式和安全层属于不同维度,不能用某个字段的值推测其他字段。地址正确但传输路径不同,或认证信息正确但安全层不匹配,都会连接失败。实际节点优先由客户端导入有效链接或订阅,不建议根据网页片段手填一套未知参数。
常见代理出站还会使用 streamSettings 描述传输与安全层。协议回答“怎样封装代理请求”,传输回答“怎样承载字节流”,安全层回答“怎样保护或验证连接”。这些不是三个可任意组合的开关。服务端只接受某种组合时,客户端必须对应设置;把安全字段全部打开并不会自动增加兼容性,反而可能构造出服务端无法理解的握手。
连接地址与 TLS 的服务器名称也应分开理解。前者用于建立网络连接,后者参与服务器身份验证和握手;二者可以不同,但必须符合服务配置及证书约束。证书报错时应检查名称、设备时间和服务端证书链。不要把跳过验证当成常规修复方法,因为那会改变身份验证条件,且往往掩盖本来填写错误的服务器名称。
内核能力与出口能力
v2rayNG 使用 Xray 内核,v2flyNG 属于 V2Fly 内核客户端;v2rayN 的实际内核选择应以当前配置和运行日志为准。某个分享链接能被界面识别,不等于当前所选内核支持全部字段。遇到未知协议或不支持的传输参数时,先确认内核家族,再判断是否需要换用匹配的配置,不能仅通过修改协议名称来转换节点。
出站还可能涉及 UDP 转发、多路复用、连接复用和套接字选项。这些功能取决于内核、协议及服务端组合,不宜在最小配置里一起开启。排错时先使用客户端生成的基础出站,确认单条连接可用,再逐项恢复扩展。否则一次请求失败可能同时涉及入口 UDP、远端协议和底层网络,日志也难以说明哪一层先出了问题。
管理多个节点时,应区分客户端的“当前节点”与内核配置中的“多个出站”。切换界面选择,可能是重新生成唯一代理出口,也可能是修改某个被引用出口,具体行为由客户端决定。订阅更新后应重新确认标签和规则引用是否仍存在。关于内核关系,可继续阅读Project V、V2Fly 与 Xray 分支脉络,再决定使用哪款客户端。
routing 路由规则
顺序匹配与条件关系
routing.rules 是有顺序的规则数组。内核按顺序检查,找到可用匹配后选择对应出口;没有命中时回到默认出站。应把明确、狭窄的条件放在前面,把兜底条件放在后面。若第一条规则已经覆盖某个入口的全部 TCP 与 UDP,后面针对同一入口的域名规则就没有机会生效,即使后面写得更具体也不会自动提高优先级。
同一条规则里,不同条件字段通常是同时满足的关系;同一字段数组中的多个条目通常表示任选其一。例如同时指定 inboundTag 与 domain,表示指定入口收到且目标域名匹配的连接,不是入口匹配或域名匹配任一个即可。需要表达两种独立情形时,应拆成两条规则,而不是把条件堆进同一个对象。
{
"routing": {
"domainStrategy": "AsIs",
"rules": [
{
"type": "field",
"ip": ["127.0.0.0/8", "10.0.0.0/8", "172.16.0.0/12", "192.168.0.0/16"],
"outboundTag": "direct"
},
{
"type": "field",
"domain": ["full:example.com"],
"outboundTag": "block"
}
]
}
}
此片段依赖第三章声明的 direct 与 block。第一条处理列出的 IPv4 地址范围,第二条只阻断精确域名。它不是完整的内网清单,也没有覆盖全部 IPv6 场景。示例使用 AsIs,所以不能假设一个尚未解析的内网域名会因为最终地址属于这些网段而自动命中第一条;目标呈现形式也属于规则条件的一部分。
域名规则与资源文件
full:example.com 表示精确域名;domain:example.com 用于域名及其子域匹配。不要把完整网址直接写进域名字段,协议前缀、路径和查询参数不属于域名。需要同时处理根域和子域时,应明确选择匹配语法。正则表达式适合确有模式需求的情形,普通域名使用明确前缀更容易审查,也能减少错误扩大匹配范围的风险。
geosite: 与 geoip: 引用分类资源,不是内核自动理解的任意中文分类名。资源文件必须存在,类别必须确实包含在当前文件里,客户端还可能采用不同的规则资源来源。出现资源加载失败时,先检查文件位置和类别拼写。不要把修改出站地址当作修复办法,因为规则资源在建立远端连接之前就可能已经导致配置加载失败。
domainStrategy 的解析边界
AsIs 尽量使用原始目标参与路由;IPIfNonMatch 可在域名未匹配时尝试解析,再检查 IP 条件;IPOnDemand 在匹配过程需要 IP 条件时可能触发解析。后两者会改变路由阶段的 DNS 需求。它们并不是“全局代理”“直连模式”的同义词,也不直接决定远端代理服务器由哪里解析最终目标。
客户端界面的路由模式往往对应一整套规则模板,而不是单个 domainStrategy 值。更换模式可能替换规则顺序、默认出站或分类资源。检查分流效果时,应查看最终生成的 routing,记录目标域名、入口标签、命中出口和规则位置。只观察浏览器页面能否打开,无法区分默认出口生效与具体规则命中。
建议建立小型测试清单:精确域名、子域名、直接 IP、本地服务分别验证,且每次只变更一条规则。若访问日志只显示 IP,应继续检查应用是否在进入内核前解析,以及入口是否提供域名信息。DNS 与路由需要配合,但二者不能互相替代。进一步的解析分流方法见V2Ray DNS 分流配置详解。
dns 解析配置
先确定哪一层发起查询
同一次访问可能涉及多个解析过程:系统解析应用目标、内核为路由解析域名、出站解析远端服务器地址,以及远端服务解析最终目的地。配置 dns 段只是在内核中定义解析器行为,不会自动把系统和所有应用的查询都接管。排查时必须先问“哪个进程查询了哪个名称”,否则很容易把浏览器自己的解析结果误认为内核 DNS 的结果。
入口收到域名时,内核仍可能按域名直接交给代理出站;入口只收到 IP 时,DNS 域名分组通常没有可用的原始名称。路由策略、直连出口的解析选项和客户端网络接管方式都会影响实际查询路径。因此,修改 DNS 地址后没有看到访问路径变化,不一定是设置失效,也可能是这条请求根本没有使用内置 DNS。
servers、hosts 与查询类型
{
"dns": {
"hosts": {
"full:example.com": "192.0.2.1"
},
"servers": [
"localhost"
],
"queryStrategy": "UseIPv4"
}
}
这个片段用于说明静态映射和系统解析入口。192.0.2.1 是文档示例地址,不是可用网站地址;保留该映射后,依赖内置 DNS 的相关连接不能据此验证正常访问。localhost 表示使用系统解析机制,不是发送到本机某个任意 UDP 端口。实际使用时应删除演示映射,再选择与环境相符的解析方案。
hosts 可以固定特定名称的结果,适合定位问题或已知的内部名称需求,但也会绕过该名称的正常动态解析。服务地址变更后,旧映射可能长期指向错误位置。若某个域名始终解析到同一个异常地址,应同时检查内核映射、系统 hosts 和应用缓存,而不是只刷新订阅。三者属于不同层,修改其中一层不会自动清理其他层。
queryStrategy 控制内置查询使用的地址族,例如 UseIPv4、UseIPv6 或 UseIP。它不等于修改系统网络协议,也不保证全部连接都只走某一种地址族。若设备有 IPv6 地址但路径不可用,应分别验证解析和连接;得到 AAAA 记录只证明解析返回了结果,不说明到该地址的传输一定能够完成。
按域名选择解析器
servers 数组可以包含服务器对象,常见字段有 address、domains 与 expectIPs。domains 用于声明优先由该服务器处理的域名集合,expectIPs 用于约束可接受的结果范围。后者不是给域名静态分配地址,也不是出站规则;结果被筛除后是否回退,还取决于其他服务器和当前内核的回退配置。
不要给范围很广的域名集合套用过窄的预期 IP 条件。内容分发、双栈部署和服务迁移都会让合法结果发生变化。严格筛选可能把正常响应变成解析失败,表面上看却像远端节点不可用。配置前应先确认分类规则与实际地址分布,配置后记录被接受和被丢弃的结果;缺少这些信息时,优先使用较小范围的定向规则进行验证。
普通 DNS、加密 DNS 和本地系统解析的连接路径可能不同,部分地址形式会绕开一般出站处理,部分则会参与内核路由。具体行为必须按当前内核的服务器地址规范确认,不能从“加密”两个字推断一定经过代理。若解析器连接需要代理,而代理服务器名称又依赖该解析器解析,就形成启动依赖环,应先安排独立的服务器名称解析路径。
policy 连接与统计策略
级别不是路由优先级
policy 用于设置连接生命周期和部分统计行为,不负责选择节点。levels 下面的键是用户级别编号,JSON 对象键仍需使用字符串。协议用户或相应入站设置可以引用用户级别,但具体引用字段随协议而变。没有显式级别时通常使用默认级别;不能把级别数字理解成越大速度越快,也不能用它替代路由规则顺序。
配置策略前应先确认实际使用者。若入口协议没有对应用户设置,或客户端生成文件没有写入预期级别,自定义的其他级别可能根本不会被引用。应在最终运行文件中查找关联字段,而不是只看到 levels 对象存在就认为已生效。对单人本地客户端而言,明确默认级别的行为通常比建立多个没有关联的级别更容易维护。
{
"policy": {
"levels": {
"0": {
"handshake": 4,
"connIdle": 300,
"uplinkOnly": 2,
"downlinkOnly": 5
}
},
"system": {
"statsInboundUplink": false,
"statsInboundDownlink": false
}
}
}
这些时间值用于展示秒为单位的常见策略写法,不是通用优化建议。不同内核的默认值与支持项需要单独核对。遇到连接中断时,不应首先复制一组更大的超时数字;应判断究竟是握手未完成、连接长时间空闲,还是某一方向已经关闭。策略只有在对应阶段生效,不能修复认证错误、证书错误或远端服务未监听。
四类超时对应的阶段
handshake 限制连接握手阶段允许等待的时间。网络建立缓慢时,过短的限制可能让原本可完成的握手提前终止;但把它无限放大只会延长失败等待。connIdle 关注连接空闲时间,常用于清理长期没有活动的连接。它与应用自身的请求超时、远端反向代理超时并不是同一个计时器,实际断开可能由任何一层先触发。
uplinkOnly 与 downlinkOnly 涉及连接只剩单方向活动时的保留时间。下载、长连接和半关闭场景可能受影响,但名称中的上下行应从内核处理方向理解,不宜简单映射成“上传加速”“下载加速”。若应用在发送结束后仍等待较长响应,过于激进的单向超时可能提前结束连接,应结合应用协议和日志分析。
判断是否真的需要修改策略,可观察问题是否稳定发生在相似空闲时长之后,以及恢复活动是否能避免中断。如果每次连接刚开始就失败,更应检查协议和认证;若只有切换网络后失败,则先检查连接重建和系统网络状态。把所有故障都归入超时,会掩盖真正原因,还可能使无效连接占用资源的时间更长。
统计开关不等于统计接口
policy.system 中的入站、出站流量统计开关用于控制相应计数,用户级别也可能提供用户统计选项。启用这些字段不等于界面自动出现流量图,更不等于已经对外提供查询接口。客户端还需要配置统计模块、查询服务和标签关联。只想让客户端显示流量时,应先检查客户端内置选项,避免手工创建与它重复的接口。
统计服务和管理接口若需要监听地址,应限定在合适的本地范围,不要随局域网入站一起开放。统计标签也应与实际入口、出口对应,否则可能得到空计数或错误归属。配置中增加未知的统计字段,不会让不支持该功能的内核自动兼容;出现字段或服务加载错误时,应先恢复基础策略,再逐项核对扩展支持情况。
验证策略应使用可复现的单连接场景,而不是根据网页打开体感判断。记录修改前后的等待阶段、关闭原因和应用表现,再决定保留哪项调整。内核重启通常会影响现有连接和内存计数,比较时应保持起点一致。对于日常客户端使用,保留生成器的合理默认策略,并只修改有证据需要调整的字段,通常更便于后续升级与排错。
客户端与配置接管
找到持续生效的配置来源
图形客户端通常同时保存节点资料、订阅分组、路由模板和界面设置,再按当前选择生成内核运行文件。这几层不是同一份数据。订阅更新主要改变远端节点资料,切换路由模式主要改变规则,系统代理则影响应用入口。修改前先确定需求属于哪层,避免为了改变浏览器入口而编辑远端出站,或为了调整路由而重新导入全部订阅。
在 v2rayN 中,优先通过相应的本地监听、路由设置和内核设置入口完成常规调整;需要完整自定义 JSON 时,再使用客户端提供的自定义配置功能。菜单名称可能随界面类型变化,应按功能确认,不要照搬其他截图中的文件路径。尤其不要只打开正在运行的临时配置修改,因为重新选择节点或重启后,生成器可能立即覆盖它。
| 来源 | 主要内容 | 常见覆盖时机 |
|---|---|---|
| 节点记录 | 远端协议、地址、认证与传输 | 编辑节点或更新订阅 |
| 路由模板 | 规则顺序与出口选择 | 切换路由模式 |
| 客户端设置 | 本地入口、运行选项 | 保存设置或重新启动 |
| 自定义配置 | 由文件声明的内核行为 | 重新加载文件或更换配置 |
导入、保存与运行不是同一步
文件被客户端接受,可能只说明格式或链接被识别;还需要选中对应配置、启动内核,并检查运行日志。保存后未重新加载,旧进程仍可能使用旧内容。验证时应观察启动记录和实际监听信息,不能只看列表中名称已经变化。若客户端支持预览生成配置,应在启动前后对照关键字段,确认本次运行使用了预期的入口标签和出站引用。
Android 上,v2rayNG 与 v2flyNG 的系统网络接管通常通过系统授权建立虚拟网络入口,应用选择和后台运行设置也会影响哪些流量进入。桌面系统代理的行为不能原样套到这里。手动添加一个 SOCKS 入站,并不等于替代客户端的网络接管流程;反过来,系统接管已开启,也不能证明自定义文件里每个入口都被应用使用。
三款客户端之间迁移时,可迁移的节点资料与可迁移的完整配置应分别判断。分享链接通常表达节点信息,未必包含本地端口、DNS、路由资源和策略。即使完整 JSON 字段被目标内核支持,客户端也可能要求特定标签、入口或运行方式。迁移后应重新验证入口、默认出口、DNS 和规则资源,不能只检查节点列表是否出现。
合并配置的安全顺序
合并片段时,以当前可运行配置为基底,先备份,再替换一个完整配置段。数组需要合并元素,对象需要合并字段,不能把两份顶层对象直接粘在一起。标签冲突应先重命名再更新全部引用。尤其是路由规则指向新标签时,必须确认出站已经存在;若先启用规则再补出口,内核可能在加载阶段就拒绝启动。
订阅地址和节点认证信息属于敏感资料。保存配置副本、提交截图或向他人询问时,应移除地址中的访问参数、身份字段和订阅链接。日志也可能带有服务器地址或访问目标,需要检查后再分享。本文示例只包含本地入口和文档地址,不能把它们当作远端服务资料;实际认证内容应从服务配置获取,不应在公共文档中填入真实值。
系统代理与内核运行应分别验证。内核正常时,如果系统代理仍指向旧端口,应用会连接失败;退出客户端后,如果系统代理尚未恢复,应用也可能继续尝试一个不存在的入口。相反,某些应用会忽略系统代理,需要单独配置。遇到“只有一个应用不能访问”时,先检查该应用入口,不要立即替换整个内核文件。
更新客户端或切换内核后,应保留原配置副本,并重新核对扩展字段和生成逻辑。界面保留某个旧选项,不代表新内核仍按原行为解释它。基础使用流程可返回快速上手主线;订阅相关问题可查订阅更新与自动更新设置,避免把订阅获取失败与内核转发失败混为一谈。
配置验证与日志排错
按加载、监听、连接分层检查
验证应从最早失败的阶段开始。第一层是 JSON 能否解析,第二层是字段与标签能否被内核接受,第三层是入口能否监听,第四层是应用流量能否进入,第五层才是路由、解析和远端连接。若日志已经显示端口绑定失败,继续更换 DNS 没有意义;若内核根本没有启动,浏览器的连接失败也不能用于判断出站协议是否正确。
先在客户端日志入口确认所选内核及本次启动结果,再查看最早出现的错误。后续“进程退出”“连接被拒绝”可能只是前一个错误的结果。阅读日志时保留时间顺序,区分启动错误与访问错误。同一窗口可能混有上一轮运行记录,修改后应明确新的启动边界,避免把旧报错当成修复仍未生效的证据。
{
"log": {
"loglevel": "info"
}
}
需要观察连接过程时,可以临时把日志级别设为 info;更细的调试级别只在必要时短时间启用。日志配置应合并到原有 log 对象,避免重复声明。访问日志与错误日志的输出方式可能由客户端管理,不宜随意填写一个无写入权限的路径。完成排错后恢复适当级别,减少持续记录访问目标和产生大量文件。
从错误类型定位配置段
解析错误通常涉及引号、逗号、括号和数据类型。编辑器指向的位置可能是错误被发现的位置,而不是错误起点;应向前检查上一项是否少了分隔符。未知协议、未知字段或无效枚举值则更像内核兼容问题。先核对当前内核,不要把字段拼写改成另一个看起来相近的名称,除非规范明确说明了对应关系。
监听失败应检查端口是否被其他进程占用、绑定地址是否属于本机,以及客户端是否已经建立同一入口。路由加载失败应检查目标标签是否存在、资源文件是否可读、类别名称是否有效。DNS 失败则需确认查询目标、服务器可达性和回退条件。这几类问题发生位置不同,逐类处理比一次重装客户端更能保留排错线索。
| 现象 | 优先检查 | 暂不先改 |
|---|---|---|
| 加载配置即退出 | JSON、字段支持、标签引用 | 应用代理设置 |
| 本地入口连接被拒绝 | 进程、监听地址与端口 | 远端 DNS 分流 |
| 仅域名访问失败 | 解析路径与返回地址 | 全部入站参数 |
| 规则没有预期命中 | 目标形式、顺序与标签 | 无关的连接超时 |
| 远端握手失败 | 协议、传输、安全层与时间 | 本地规则资源 |
建立可恢复的测试闭环
准备一份能够稳定启动的基础配置作为基线,再逐项加入入站扩展、代理出口、规则、DNS 和策略。每加入一段,先确认启动,再执行对应测试。用直连基线只能验证本地入口和基础网络,不能证明远端节点可用;用代理访问成功也不能证明分流规则正确,因为连接可能走了默认出口。测试结论必须限制在实际覆盖的范围内。
记录每次修改的字段、预期结果、实际日志和恢复方法。对路由测试,应至少包含域名与直接 IP 两种目标;对 DNS 测试,应区分地址族和缓存;对策略测试,应区分连接建立与空闲阶段。若结果不符合预期,先恢复上一份基线,确认问题随改动出现,再继续缩小范围,避免在已损坏的配置上不断叠加补丁。
配置文件是多个职责明确的对象组合,不是越长越完整的功能清单。保留能够解释用途的字段,删除经过确认不再需要的试验设置,并把客户端负责生成的部分留在正确入口管理。常见现象可查常见问题;启动报错的阅读顺序见内核启动失败与日志定位。排错完成后,保存最终可运行副本,再恢复正常使用。