配置文件结构与请求路径
V2Ray 配置文件以一个 JSON 对象为根。阅读时先找 inbounds、outbounds 和 routing:入站接收应用请求,路由判断请求应交给哪条出站,出站负责后续连接。dns 提供内核可调用的域名解析能力,policy 管理部分连接时限与统计开关。字段之间有引用关系,但不是把所有段落按文件顺序依次执行;顶层键放在前面或后面,通常不改变处理逻辑。
先区分三份容易混淆的数据。订阅内容描述远端连接资料,客户端设置保存界面选项,内核运行配置则是客户端把这些资料组合后交给内核的结果。订阅文本未必是完整 JSON,客户端自己的设置文件也未必能直接由内核加载。看到包含服务器列表、窗口状态或订阅更新时间的文件,不能仅凭扩展名就认定它是运行配置。应从客户端的日志、配置查看入口或自定义配置说明确认文件用途。
完整骨架:本地代理入口与直连出口
下面是一份基础 V2Ray 风格配置。它在回环地址上提供 SOCKS 与 HTTP 入口,所有正常请求最终直连,不包含远端代理服务器。用途是观察入站、出站与路由如何衔接,而不是替代订阅生成的代理配置。示例端口属于本文约定,使用前应确认没有其他程序占用;若当前客户端生成的是混合入站,实际端口布局可能不同。
{
"log": {
"loglevel": "warning"
},
"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": {}
},
{
"tag": "block",
"protocol": "blackhole",
"settings": {}
}
],
"routing": {
"domainStrategy": "AsIs",
"rules": [
{
"type": "field",
"ip": ["geoip:private"],
"outboundTag": "direct"
}
]
}
}
这里的 direct 与 block 都是自定义标识,不是保留关键字。路由中的 outboundTag 必须与某个出站的 tag 完全一致。没有规则命中的请求,默认交给第一条出站,因此本例仍然直连。私有地址规则依赖相应的地理数据资源;若运行环境未提供这些资源,应先解决资源加载问题,或在理解用途后改用明确的地址段,而不是忽略启动错误。
JSON 语法与内核语义分开检查
标准 JSON 的键名和字符串使用双引号,数字与布尔值不加引号,数组与对象的最后一项不能追加逗号。本文代码块均按标准 JSON 编写,不在配置内部加入注释。某些加载方式允许扩展语法,但不能把一种客户端接受的写法视为所有内核都接受。复制时只取代码内容,不把标题、解释文字或代码块边界带入文件。
语法正确也不代表字段有效。"port": 10808 是数字端口,"udp": true 是布尔开关;把它们写成字符串可能导致解析失败或产生非预期行为。重复键同样值得排查:不同解析实现的处理方式可能不同,应删除重复定义而不是依赖后一个覆盖前一个。修改后先检查结构,再检查引用,最后检查运行结果,这三个步骤不能互相替代。
后续章节中的短示例均是局部片段,只用于替换或理解对应段落,不能单独作为完整运行文件。若已有客户端生成配置,应在副本中调整一个目标字段,保留其余有效内容。更详细的段落串联示例可参阅配置文件 JSON 结构拆读。
inbounds:监听地址、端口与入站协议
inbounds 是数组,每个元素定义一个接收请求的入口。它回答四个问题:在哪个地址监听、使用哪个端口、接受什么协议、为这个入口设置什么标识。应用必须使用与入站相匹配的代理协议和端口。浏览器填写 HTTP 代理时,应连接 HTTP 入站;支持 SOCKS 的应用可连接 SOCKS 入站。只把某个数字填进系统代理,并不能让该端口自动变成应用期望的协议。
listen 决定接收范围。单机使用时优先绑定 127.0.0.1,使入口只服务本机。绑定所有网卡会扩大可访问范围,还涉及防火墙、身份认证与局域网访问控制,不能作为网页打不开时的通用修复。回环地址也有地址族区别:应用连接 IPv6 回环地址,而服务只监听 IPv4 回环地址时,可能连接失败。排错时先显式使用配置中实际监听的地址。
SOCKS 入站的 UDP 与域名传递
下面的片段启用本地 SOCKS 入站及 UDP 支持。auth 为 noauth 表示这个入口不要求 SOCKS 用户名密码,并非远端节点不需要身份资料。由于它只绑定回环地址,适合单用户桌面的本机应用场景。如果改成共享入口,应重新评估访问边界,而不是只修改监听地址。
{
"inbounds": [
{
"tag": "socks-in",
"listen": "127.0.0.1",
"port": 10808,
"protocol": "socks",
"settings": {
"auth": "noauth",
"udp": true
}
}
]
}
启用 udp 只是允许入站接收相应的 UDP 转发请求,不代表所有应用流量都会进入内核,也不代表后面的每种出站都能完成 UDP 传输。应用需要使用兼容的转发方式,出站协议与远端服务也要支持对应能力。普通网页访问成功只能证明当前网页请求链路可用,不能据此判断实时通信或其他 UDP 应用一定可用。
域名在哪里解析,取决于应用如何发起代理请求。应用可能先在本机解析,再把目标 IP 交给 SOCKS;也可能把域名交给代理端处理。前一种情况下,域名路由可用的信息可能减少,后一种情况下,内核有机会按原始域名匹配规则。应用里的“通过代理解析域名”等选项需要结合实际行为判断,不能只根据 SOCKS 名称推断解析位置。
HTTP 入站与入口标识
HTTP 代理入口常用于系统代理或浏览器手动代理。访问 HTTPS 网站时,应用通常通过 HTTP 代理建立隧道,这不意味着本地 HTTP 入站本身必须配置网站证书。不要把本地代理协议、目标网站协议与远端代理传输层混成一个设置项。若使用独立 HTTP 入站,系统代理里填写的端口应与该入站一致;若客户端使用混合入口,则以客户端当前显示的端口为准。
| 字段 | 作用 | 核对重点 |
|---|---|---|
listen | 本地监听地址 | 与应用连接的地址族一致 |
port | 本地监听端口 | 不能与已有监听冲突 |
protocol | 入站协议 | 匹配应用的代理类型 |
tag | 入口标识 | 供路由的 inboundTag 引用 |
入站 tag 不决定端口类型,但可以作为路由条件。例如同一台电脑上的两个入口可以分别标记,再按 inboundTag 走不同出站。标识应保持唯一、简短且语义明确,修改标识时同步检查所有引用。不要把入站 tag 与出站 tag 当成自动配对关系;名称相同也不会自动建立连接,实际选择仍由路由和默认出站规则决定。
排查端口占用时,先关闭重复启动的客户端实例,再查看日志是否出现绑定失败。改端口后,需要同时更新应用设置和系统代理;只改 JSON 会留下旧入口地址。客户端重启内核后,还应重新确认监听确实建立。入站存在、应用已连接和远端访问成功属于三个不同层次,应逐层验证,避免通过频繁切换服务器掩盖本地入口错误。
outbounds:出站协议、tag 与默认出口
outbounds 定义内核接收请求之后的连接方式。直连出站通常使用 freedom,阻断出站通常使用 blackhole;远端代理出站则依据连接资料使用相应协议。协议名决定配置结构,tag 负责被其他段落引用。把 tag 改成 proxy 不会把直连出站变成代理,真正的行为仍取决于 protocol、协议设置与传输设置。
阅读客户端生成配置时,先列出每条出站的 tag,再标注其实际用途。常见命名是 proxy、direct、block,但客户端可以使用其他名称。路由里写了 outboundTag: "proxy",就必须找到同名出站;如果实际名称是另一串标识,应以运行配置为准。大小写、连字符与前后空格都不能凭感觉忽略。
直连与阻断的最小定义
{
"outbounds": [
{
"tag": "direct",
"protocol": "freedom",
"settings": {}
},
{
"tag": "block",
"protocol": "blackhole",
"settings": {}
}
]
}
这个片段的第一条出站是直连。未命中路由规则时,请求默认落到第一条出站,因此调换数组顺序可能改变大量请求的去向。不能把顺序整理当成纯排版操作。若希望默认使用代理,应确认第一条实际是有效代理出站,或者根据内核支持的路由写法明确设置兜底规则。不能为了凑齐名称而添加一个内容为空的代理出站。
阻断出站用于主动拒绝或丢弃符合规则的流量。它与连接远端失败不是同一件事:前者可能是预期路由结果,后者通常需要检查网络或远端参数。某个域名始终无法访问时,应先查它是否命中了阻断规则,而不是先更换 DNS。规则列表越长,越需要保留每条阻断规则的用途说明;这些说明放在维护文档或客户端备注中,不必强行写进标准 JSON。
协议设置与传输设置分层阅读
远端代理出站可以分成几层理解:服务器地址与端口描述连接位置,协议设置描述身份与协议行为,streamSettings 描述底层传输与安全层。VMess、VLESS、Trojan 的字段不能互相套用;REALITY 属于特定内核支持的安全层方案,也不是把出站协议名直接改成 REALITY。处理订阅导入结果时,先确认实际协议,再逐层核对参数。
端口与目标地址相同,仍不足以说明两条配置等价。服务端要求的传输类型、TLS 服务名称、路径或其他协商参数只要有一项不匹配,都可能在连接或握手阶段失败。不要从另一条节点资料里借用看似相近的值。本文不提供可用远端凭据;真实连接资料应来自用户有权使用的服务配置,并在分享日志时遮去身份信息及订阅地址。
域名形式的服务器地址还引入了解析依赖。内核建立远端连接之前,必须知道该地址对应的 IP;如果解析过程又被设置为依赖尚未建立的同一条连接,就可能形成启动环。故障表现可能是持续超时,而非明显的 JSON 错误。排查时应区分“远端地址解析失败”和“目标网站解析失败”,两者处于请求链路的不同位置,不能只看一条 DNS 设置。
客户端可能根据当前所选服务器重建代理出站。此时手动编辑临时运行文件,即使短时间生效,也可能在切换服务器或重启时被覆盖。需要长期保留的出站调整,应通过客户端支持的自定义配置方式实现。若只是比较桌面与移动端的管理差异,可查阅客户端选型指南;不要把不同客户端导出的所有字段原样合并成一份文件。
验证出站时,至少选择一项明确应直连的请求和一项明确应代理的请求分别观察。单次页面打开不能证明路由选择符合预期,浏览器缓存、已有连接和应用自己的代理设置都会干扰判断。修改后关闭旧连接再测试,并结合日志中的目标地址、出站标识及错误阶段确认结果。
routing:匹配条件、规则顺序与兜底
routing 决定请求交给哪条出站。规则通常从上到下检查,第一条匹配后即采用该条规则的出口,不会继续寻找“更精确”的后续规则。因此,规则顺序本身就是配置语义。把范围很大的规则放到前面,会遮住后面的小范围规则;把例外规则放到最后,也可能永远无法命中。编辑前先写清预期顺序:局部例外、常规分类、最终兜底。
一条规则中,不同条件字段通常需要同时满足;同一条件数组里的多个值通常作为候选匹配。例如同时写入 inboundTag 与 domain,表示来自指定入口且目标域名满足条件。它不是“满足入口或满足域名任意一项”。需要表达不同路径时,应拆成独立规则,避免在一个对象里堆入互不相干的条件。
先明确域名规则,再补充地址规则
下面的片段展示匹配次序,所有命中结果均指向 direct,用于观察条件结构。它要求配置里已经存在同名出站。示例使用保留的示例域名说明 full: 与 domain:,并用明确的私有地址段避免对地理数据文件的依赖。它不是一套完整的地区分流方案。
{
"routing": {
"domainStrategy": "AsIs",
"rules": [
{
"type": "field",
"domain": ["full:example.com"],
"outboundTag": "direct"
},
{
"type": "field",
"domain": ["domain:example.org"],
"outboundTag": "direct"
},
{
"type": "field",
"ip": [
"10.0.0.0/8",
"172.16.0.0/12",
"192.168.0.0/16"
],
"outboundTag": "direct"
}
]
}
}
full: 用于完整域名匹配,domain: 用于指定域及其子域的匹配。后者适合管理一组同属某个域的服务,但一个网站的页面、图片和认证接口可能来自多个域,不能把页面主域名视为全部依赖。裸字符串和正则表达式还有各自的匹配语义,维护一般规则时优先使用意图明确的前缀,减少误匹配和后续解释成本。
geosite: 与 geoip: 是数据集引用,不是在线查询服务。它们能否使用、包含哪些分类,取决于运行环境中的数据文件与分类内容。规则里写着某个分类,并不代表当前内核一定能加载它。导入第三方规则时,应同时确认分类存在、资源可读以及所引用的 tag 有定义;不能只检查 JSON 括号是否闭合。
domainStrategy 不等于 DNS 服务器设置
AsIs 表示路由阶段通常按现有目标信息匹配,不为了 IP 条件主动解析域名。IPIfNonMatch 会在域名规则未匹配时尝试解析,以便继续进行 IP 匹配。IPOnDemand 则会在路由需要 IP 信息时触发解析。选择策略要看规则结构,而不是把解析越早视为越准确;额外解析会增加依赖,也可能改变请求处理时机。
路由的 domainStrategy 与 DNS 的 queryStrategy 管理不同问题:前者决定何时为路由获得地址,后者决定 DNS 查询偏好的地址族。直连出站也可能有独立的域名解析策略。排查时应写出发生解析的具体阶段,而不是笼统地说“已经开启 DNS”。域名在应用端已被解析时,内核是否还能获得域名信息,还取决于应用传递内容和嗅探等额外机制。
兜底需要单独核对。没有规则命中时,默认选择第一条出站;如果维护者误以为“最后一条出站是默认出口”,就会得出相反结论。某些客户端界面用 final → proxy 表达最终去向,这是阅读上的概括,不意味着内核 JSON 存在一个通用的 final 顶层字段。应查看客户端实际生成的规则或第一条出站,确认界面选择如何落实。
新增规则后,用一个应命中的目标和一个不应命中的目标对照测试。若新规则没有效果,先向上查是否被已有规则截获,再核对目标在内核里是域名还是 IP,最后查 tag 引用及资源加载。系统代理中的“全局”只影响应用如何交付流量,内核里的路由仍可能分流;二者应分别确认,相关操作路径见使用指南中的模式选择。
dns:解析服务器、地址族与查询路径
dns 定义内核可使用的解析能力,但不会因为这个段落存在,就自动接管整台电脑的全部 DNS。应用、操作系统、浏览器与内核可能分别执行解析。先确定是哪一层发起查询,再讨论应该修改什么。浏览器自行启用加密解析时,系统 DNS 的变化未必影响它;应用先把域名转换为 IP 时,内核也未必会按预想的域名规则处理请求。
判断配置是否符合预期,需要回答三个问题:查询发送给谁、查询通过哪条路径到达、得到的地址用于哪个阶段。只替换服务器地址解决的是第一个问题,不能保证后两个问题同时改变。远端代理服务器的地址解析、路由进行 IP 匹配时的解析,以及直连目标的解析,也可能发生在不同位置。记录这些依赖,比同时添加多个解析服务器更有助于稳定排错。
显式服务器与静态 hosts
下面是局部 DNS 示例。静态 hosts 将示例域名固定到回环地址,仅用于本机测试;日常使用应删除这条测试映射。服务器列表使用明确 IP,避免为了联系解析服务器,先解析该服务器自身的域名。具体服务器是否可达、查询通过什么出口,仍需结合内核行为与路由配置验证。
{
"dns": {
"hosts": {
"example.com": "127.0.0.1"
},
"servers": [
"1.1.1.1",
"8.8.8.8"
],
"queryStrategy": "UseIP"
}
}
hosts 适合临时固定一个已知地址,或在受控环境里验证解析与连接的区别。它不适合长期替代会变化的服务地址。映射到回环地址后,访问这个域名会指向本机,若本机没有对应服务,连接失败是预期结果。排错结束要移除测试映射,否则下一次故障可能来自遗留设置,而不是解析服务器本身。
queryStrategy 常见取值包括 UseIP、UseIPv4 与 UseIPv6,实际支持范围以当前内核为准。双栈网络中,解析到 IPv6 地址不等于 IPv6 连接可达。临时限定 IPv4 可以帮助确认地址族问题,但不应把禁用某个地址族当作所有网络的固定答案。还要考虑远端地址、目标地址与操作系统网络能力是否一致。
分域解析与回退边界
更复杂的服务器对象可以带域名匹配范围和预期地址等条件,用于将不同域名交给不同解析源。引入这种配置前,先确认当前内核支持的字段和回退规则。多个服务器并不简单等于“按数组逐个尝试直到成功”;匹配条件、回退开关和解析结果判断都会参与决策。没有建立清晰需求时,应先维护一条可解释的基础路径,再逐步增加分域策略。
使用加密 DNS 时,还要区分传输加密和出口选择。加密只描述查询在相应链路上的传输形式,不自动说明请求经过哪条代理出站。不同解析地址形式可能采用不同的处理路径,不能把常规路由对 UDP 查询的行为直接套给所有加密解析方式。配置前查明所用形式的路由与引导解析要求,再通过日志和实际请求验证。
所谓解析依赖环,常见于解析服务器需要代理访问,而代理服务器的域名又依赖同一个解析服务器。此时配置即使通过结构检查,也可能无法建立第一条连接。修复应为必要的启动解析提供可用路径,而不是不断增加超时时间。记录代理服务器域名、解析服务器地址与所用出站,可以把这个环直接画出来,再决定在哪一处解除依赖。
测试 DNS 时,先关闭旧页面和已有连接,确认应用使用预期代理设置,再比较目标域名的解析与访问结果。操作系统或浏览器缓存可能让一次修改看起来没有生效,连接复用也可能绕过新的解析过程。需要清理哪一层缓存,应由实际查询发起者决定。面向具体检测步骤,可继续阅读DNS 查询路径检测与设置排查,不要把单一检测页面的结果等同于所有应用的行为。
policy:用户等级、连接时限与统计
policy 管理部分连接行为和统计开关,不负责选择远端服务器,也不负责按地区分流。它通常分为 levels 与 system:前者按用户等级定义策略,后者控制系统范围的部分统计。阅读时先确认某条连接采用哪个等级,再看该等级里实际设置了哪些字段。把所有用户一律理解为等级零,可能漏掉协议用户对象里已经指定的其他等级。
等级名称在 JSON 中写成对象键,因此示例使用字符串 "0";协议配置里引用的 level 通常是数字。等级不是服务器优先级,也不是节点质量评分。提高等级数字并不会提高连接性能,只会选择另一组策略。如果没有明确的分级需求,应保持简单,避免添加没有任何用户引用的等级条目,造成“配置已经改了但没有效果”的误判。
连接时限的局部示例
{
"policy": {
"levels": {
"0": {
"handshake": 4,
"connIdle": 300,
"uplinkOnly": 2,
"downlinkOnly": 5,
"statsUserUplink": false,
"statsUserDownlink": false
}
},
"system": {
"statsInboundUplink": false,
"statsInboundDownlink": false
}
}
}
这些数值用于展示字段结构,不是针对所有网络的推荐调优值。handshake 表示握手阶段允许的时间,单位为秒;connIdle 涉及连接空闲时限。uplinkOnly 与 downlinkOnly 用于一侧方向结束后,另一方向继续保留的时限。它们主要影响连接生命周期,不能改变路径拥塞、远端服务处理能力或本地无线网络质量。
握手超时过短时,网络抖动可能使原本可建立的连接提前结束;过长时,真正无法到达的目标又会让应用等待更久。判断是否需要修改,必须结合错误发生阶段。若日志显示服务器名称或安全层参数不匹配,延长时间不会修复参数错误;若错误是本地端口绑定失败,policy 更不是处理入口。先找到失败位置,再决定是否调整时限。
统计开关与客户端显示分开理解
用户统计和入站统计描述的是不同范围。开启某个统计开关,并不自动在客户端界面出现对应内容;还可能需要内核的统计模块、查询接口及客户端读取配合。部分统计要求用户具备可识别的标记。只复制开关,不确认采集与读取链路,容易得到一直为空的结果。也不要因为界面没有展示,就判断网络连接没有经过内核。
客户端自身可能维护应用状态、连接记录或其他运行信息,这些内容未必全部来自 policy。阅读导出配置时,应把“内核是否采集”与“界面是否显示”分开。对于仅用于排错的临时统计,明确排错目标即可,不必为了看起来完整而启用所有项目。需要长期保存的运行记录,还应考虑磁盘占用和日志中可能包含的访问目标。
| 字段组 | 关注点 | 不能替代 |
|---|---|---|
handshake | 握手阶段等待 | 远端参数核对 |
connIdle | 空闲连接回收 | 路由与 DNS 配置 |
uplinkOnly | 单向结束后的保留 | 应用长连接设计 |
statsUserUplink | 用户上行统计 | 统计接口与读取配置 |
缓冲区相关策略同样不应照抄所谓通用性能方案。连接数量、应用数据模式与设备内存共同决定资源压力,单纯放大缓冲可能增加内存消耗,却不改善实际响应。不同内核还可能调整字段支持范围或默认值。遇到不认识的策略字段,先查当前内核文档;不要因为旧文章里出现过,就认定当前客户端一定接受。
有必要测试策略变化时,固定同一应用、同一出口与相近的网络条件,只修改一组相关值,并保留修改前的配置。测试需要覆盖新建连接、短时间空闲后恢复,以及长时间空闲后的重连。若应用本身有心跳机制,连接可能不会进入预想的空闲状态。一次持续下载不能验证空闲回收行为,应针对字段真正管理的场景观察。
默认配置能满足需求时,可以不显式写出整段 policy。省略字段意味着使用当前内核的默认行为,不等于功能被关闭。把每个默认值都展开,会增加维护负担,也可能把旧内核的选择固定到新环境。维护手册应记录“为何覆盖默认值”,而不是只记录一串数字,便于之后判断这项调整是否仍有必要。
客户端生成配置与自定义配置边界
v2rayN 是本站首推的桌面客户端,覆盖 Windows、macOS 与 Linux;Android 可使用以 Xray 为主要内核的 v2rayNG,或以 V2Fly 为内核的 v2flyNG。客户端提供订阅、服务器、路由及参数管理界面,最终运行行为还取决于选用的内核和生成结果。安装包入口统一放在客户端下载页,本手册只讨论配置关系,不在正文提供独立内核包或远端服务器资料。
客户端配置的关键边界是“资料由谁管理”。订阅负责更新连接资料,服务器选择决定当前代理出站,路由模板决定分流规则,参数设置影响入站端口和其他运行选项。生成文件是这些输入的组合结果。直接修改生成文件,可能在切换服务器、更新订阅、重启内核或应用设置后被覆盖;这不是 JSON 没有保存,而是下一次生成又恢复了管理源中的值。
订阅管理不是内核顶层键
subscription 是客户端管理概念,不是本文所述 V2Ray 内核 JSON 的通用顶层字段。订阅地址、自动更新周期和分组名称应在客户端的订阅管理界面维护,不能靠在运行文件中添加一个同名对象实现。订阅内容也可能以编码文本或协议链接集合交付;先由客户端解析,再转成内核需要的协议与传输配置。
更新订阅失败时,先保留现有可用资料,再核对链接有效期、访问路径、返回格式和客户端提示。不要因为更新失败就删除所有服务器,也不要把订阅地址粘贴进公开日志。自动更新解决的是资料同步,不会自动修复本地端口冲突或系统代理设置。具体排查可参阅订阅更新失败与自动刷新设置。
系统代理、路由与接管模式分层核对
系统代理决定愿意遵循系统代理设置的应用将请求交给哪个本地入口;内核路由决定进入入口的请求如何离开。选择“自动配置系统代理”并不意味着所有应用都被接管,选择“清除系统代理”也不一定停止内核监听。有些应用保留自己的代理设置,可能继续使用本地端口。排错时需要同时查看操作系统与应用自己的网络选项。
v2rayN 的常见相关入口包括“订阅分组”“路由设置”“参数设置”和系统代理菜单,实际名称及位置可能随界面类型变化。Android 客户端通常通过系统授权建立相应接管方式,不能直接套用桌面系统代理的路径。跨平台迁移时应迁移需求与连接资料,再在新平台确认权限、监听方式和路由模式,而不是只复制桌面生成文件。
某些客户端还提供虚拟网卡接管模式。它与普通系统代理的流量范围、权限要求和 DNS 路径不同。启用后应重新验证局域网访问、解析和其他网络软件的共存情况,不能把之前仅针对 HTTP 代理得到的结论直接沿用。需要提升权限时,应先确认该模式确有必要;单个浏览器能够手动代理的场景,不必为解决一个端口填写错误而立即改变接管方式。
保留可维护的修改来源
准备长期自定义前,先确认客户端提供的是路由规则编辑、自定义片段,还是完整自定义配置。三者覆盖范围不同。局部片段可能被合并,完整配置可能绕过部分自动生成流程;具体以当前客户端说明和生成结果为准。每次调整都应保存原始设置,并记录修改入口、目标字段和预期现象,便于覆盖发生时定位真正的管理源。
导入外部完整配置前,检查其中是否包含额外监听、控制接口、远端地址和不明路由。可运行不代表符合本机需求。尤其要确认监听范围没有从回环地址变成所有网卡,原有系统代理端口仍能对应正确入口,且默认出站方向符合预期。对不理解的字段,先查用途,不要为了通过启动就盲目删除整段安全层或路由设置。
配置文件与日志也有分享边界。协议身份信息、完整订阅链接、访问目标和本机路径可能包含个人资料。公开求助时只保留复现问题所需的字段与错误阶段,替换敏感值,并注明内核类型。来自不同内核的报错不能只凭相似字面合并处理;先把环境描述清楚,才能让对方判断是语法、支持范围还是网络路径问题。
配置验证、日志阅读与回退路径
验证应沿请求路径推进:配置能否加载、入站能否监听、应用是否进入入口、路由是否选对出站、远端连接是否建立、目标解析与访问是否完成。每一层都可能失败,而且外部表现常常只是“网页打不开”。不要同时更换服务器、DNS、路由和本地端口;多个变量一起变化,即使暂时恢复,也难以知道真正原因,更难在下一次故障时复用判断。
开始前保存一份已知可工作的客户端设置或配置副本,记录当前模式。然后修改一项,应用设置并重启对应内核,再用明确目标测试。只保存文件而未让内核重新加载,观察到的仍可能是旧配置。反过来,重启客户端后设置又消失,则应返回上一章检查配置生成来源,而不是反复编辑同一个临时文件。
先区分加载失败与连接失败
加载阶段的问题通常包括 JSON 语法错误、字段类型错误、内核不支持的协议或字段,以及路由数据资源缺失。此时先看日志中最早出现的关键错误,不要只看最后的“启动失败”。错误行附近的逗号、引号和数组边界尤其值得检查,但有时定位指向错误之后的位置,因此还应回看前一个对象的结尾。
内核已经启动但端口无法连接时,检查是否存在地址族不一致、端口冲突或应用仍使用旧端口。系统代理残留也是常见原因:客户端退出后,系统仍指向已不存在的本地监听,所有遵循系统代理的应用都会受影响。处理时先恢复正确系统代理,再检查客户端运行状态,不需要先修改远端协议参数。
日志临时提高到可观察级别
下面的片段将日志级别设为 info,用于临时观察连接与路由。不同客户端可能将日志收集到自己的界面,也可能写入指定文件。未显式设置文件路径时,实际显示位置由启动方式决定。若信息仍不足,可以在受控排错期间进一步提高详细程度,完成后恢复较少输出,避免长期积累大量请求信息。
{
"log": {
"loglevel": "info"
}
}
阅读日志时围绕同一次测试查找目标、入站、出站和错误阶段。超时可能发生在解析、建立连接或握手期间,含义不同;连接被拒绝通常提示地址端口处没有预期服务,或请求被明确拒绝;安全层握手失败则应核对服务名称、时间和协议参数。不要把所有错误都归因于节点不可用,也不要把某条正常关闭记录当成故障根源。
| 现象 | 优先检查 | 下一步 |
|---|---|---|
| 内核无法启动 | 语法、字段与资源加载 | 回退最近修改的段落 |
| 本地入口连接失败 | 监听地址、端口、进程状态 | 核对应用实际代理设置 |
| 只有部分站点失败 | 规则顺序与解析结果 | 对照命中出站及地址族 |
| 切换服务器后失效 | 生成配置与自定义覆盖 | 确认新的出站标识 |
| 休眠恢复后断连 | 网络变化与旧连接 | 重建连接后再测试 |
系统时间也影响某些协议与安全握手。若日志表现为认证或证书时间相关错误,应先检查设备时间和时区是否正确,再看远端资料。网络切换后出现的问题,则要重新确认默认网络、解析服务器可达性和已有连接状态。设备从有线网络切换到无线网络,并不保证旧连接仍然有效;重建连接有助于区分环境变化与静态配置问题。
回退时恢复的是整个相关修改单元,而不是只删报错字段。例如修改了出站 tag,就要连同路由引用一起恢复;修改了端口,就要同步恢复系统和应用代理。恢复后重新加载内核,确认日志没有残留的启动错误,再重复最初的测试。如果恢复副本仍不可用,应考虑外部网络或远端服务变化,而不是继续在同一段 JSON 中寻找并不存在的差异。
完整的复现记录应包括测试应用、接管方式、内核类型、目标属于哪类路由、错误发生阶段以及最后一次修改。无需公开完整订阅或所有服务器资料。更贴近界面操作的排查顺序见已连接却打不开网页的检查清单;需要重新建立基础流程时,返回快速上手指南,从导入资料、选择模式到验证连接重新确认。
最终维护目标是让每个字段都有明确来源,每条规则都有可解释的用途,每次修改都有可执行的回退。配置较短不必补齐所有可选段,配置较长也不代表能力更完整。保留实际需要的入口、出站与规则,理解默认行为和内核边界,比持续叠加来源不明的片段更便于查阅和排错。