本文适合已经会导入节点、准备阅读 Xray 原生配置的用户。先用一份仅含本地入口、直连和阻断出口的完整 JSON 建立参照,再解释日志、端口、标签、路由顺序与 DNS 的关系。读完可以定位流量在哪一段中断,也能分清客户端设置、分享链接与内核运行配置各自负责什么。
配置对象与流量路径
Xray 是处理连接的内核,v2rayN 是管理节点、生成配置并启动内核的桌面客户端。节点分享链接通常只描述一个远端连接;原生 JSON 则可以同时描述本地监听、多个出口、路由与 DNS。把分享链接保存为 config.json,不会自动变成可运行的内核配置。
上述链路是阅读配置的主线。log 负责记录状态,dns 在需要解析域名时参与处理,都不是每条请求必须依次经过的独立转发站。顶层对象在 JSON 中的书写先后,不决定流量顺序。
inbounds:流量从哪里进入,使用什么本地协议。outbounds:连接如何离开内核,是直连、代理还是阻断。routing:依据目标和来源,选择哪个出站标签。dns:配置内置 DNS;是否使用它还取决于相关解析设置。
完整 JSON:本地入口与直连基线
下面是一份用于理解结构的独立配置。SOCKS 入口监听 127.0.0.1:10808,HTTP 入口监听 127.0.0.1:10809。它不包含远端代理节点:普通请求直连,发往保留测试域名 blocked.test 的请求被阻断。它不能用来验证远端代理是否可用。
{
"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": {
"domainStrategy": "UseIP"
}
},
{
"tag": "block",
"protocol": "blackhole",
"settings": {}
}
],
"routing": {
"domainStrategy": "AsIs",
"rules": [
{
"type": "field",
"domain": [
"full:blocked.test"
],
"outboundTag": "block"
},
{
"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"
}
]
},
"dns": {
"servers": [
"localhost"
]
}
}
示例是严格 JSON:键名和字符串使用双引号,不带注释,不在最后一个数组元素后加逗号。文章后面的字段说明用于解释这份配置,不需要逐段再拼成第二份配置。
log:先确定错误发生的位置
loglevel 控制错误日志的详细程度。常用值包括 debug、info、warning、error 和 none。排障时可以临时把示例中的 warning 改成 info,完成后再恢复,避免保留过多连接细节。
| 字段 | 用途 | 排查时关注什么 |
|---|---|---|
loglevel | 调整错误日志级别 | 配置加载、监听失败、连接失败的具体提示 |
access | 指定访问日志文件 | 请求目标及实际采用的出站信息 |
error | 指定错误日志文件 | 启动和运行中的错误上下文 |
本例没有指定日志文件路径;命令行运行时先观察控制台。若自行增加 access 或 error,应选用当前进程可写的路径,并区分相对路径与启动工作目录。日志中可能出现访问目标,分享排障内容前应先移除敏感信息。
- 尚未启动就报 JSON 解析错误:先检查括号、逗号和字段类型。
- 启动时出现
address already in use:检查本地端口,不要先改远端协议。 - 入口已经接收请求,随后连接超时:再检查实际出站、解析结果和目标可达性。
inbounds:监听地址、端口与入口标签
一个入站对象就是一个接收流量的入口。listen 是绑定地址,port 是监听端口,protocol 决定应用要用哪种协议连接它。tag 是配置内部的标识,不是密码,也不是要填进浏览器的主机名。
SOCKS 入口
- 标签
socks-in- 地址
127.0.0.1- 端口
10808- 协议
socks- UDP
true
应用需要使用 SOCKS 协议接入;UDP 还要求应用和后续链路共同支持。
HTTP 入口
- 标签
http-in- 地址
127.0.0.1- 端口
10809- 协议
http- 协议设置
{}
HTTPS 网站通常通过 HTTP CONNECT 建立隧道,不是把入口协议改成 HTTPS。
127.0.0.1 只接受本机连接。将它改为 0.0.0.0 会扩大 IPv4 监听范围,是否能被其他设备访问还取决于防火墙和网络环境。本例 SOCKS 使用 noauth,因此不要为了尝试局域网共享而直接扩大监听范围。
- 浏览器读取系统代理设置时,应把代理指向实际的 HTTP 入口,而不是把两个端口混用。
- 本地端口不是远端服务器端口;修改
10808不会改变节点的服务端配置。 udp: true只开启 SOCKS 入站的 UDP 能力,不会让 HTTP 入口自动承载普通 UDP 流量。
outbounds:出口协议与默认出口
outbounds 是可供路由选择的出口数组。本例的 freedom 直接连接目标,blackhole 阻断连接。这里的 direct、block 都是自行定义的标签;真正决定行为的是 protocol,不是标签的英文含义。
| 配置层 | 示例字段 | 负责内容 |
|---|---|---|
| 出口标识 | tag | 供路由的 outboundTag 引用 |
| 代理协议 | protocol | 如 freedom、blackhole、VMess、VLESS、Trojan 或 Shadowsocks 对应的协议实现 |
| 协议参数 | settings | 按出口协议提供目标、用户或其他协议设置 |
| 传输参数 | streamSettings | 为支持的代理出口配置传输方式与传输安全 |
添加远端代理出口时,协议、服务端地址、端口、身份参数与传输设置必须互相匹配。不能只把 freedom 改为 vless 就认为已经配置好节点。TLS 或 REALITY 相关字段属于相应的传输安全配置,不应随意塞进入站 SOCKS 的 settings。
结论:调整出口顺序前先补齐兜底规则
没有命中任何路由规则时,通常使用第一个出站。本例把 direct 放在首位,所以未匹配请求直连;若希望默认代理,应明确设计兜底出口,不能只检查某条规则是否写了代理标签。
routing:规则顺序、标签引用与解析策略
routing.rules 按数组顺序匹配,先命中的规则决定出口。本例第一条把完整域名 blocked.test 送到 block;第二条把列出的 IPv4 网段送到 direct。这些网段只是示例,不是完整的特殊地址集合,也不包含 IPv6。
- 请求进入后,内核取得入口标签、目标域名或 IP、端口等可用信息。
- 从第一条规则向后检查;同一条规则中的不同条件类别通常需要同时满足。
- 同类列表内的候选项通常按“任一匹配”处理,例如命中
ip数组中的任一网段。 - 找到匹配规则后,使用其
outboundTag;没有命中时走默认出口。
full: 表示完整域名匹配,domain: 用于域名及其子域名匹配。需要限制某个入口时,可在规则里增加 inboundTag 数组。引用标签必须与对应对象的 tag 一致;入口标签和出口标签各有用途,不能把 socks-in 当作出站来引用。
| routing.domainStrategy | 域名解析时机 | 阅读规则时的注意点 |
|---|---|---|
AsIs | 不为路由匹配主动解析域名 | 域名目标不能指望仅凭 IP 规则得到分流 |
IPIfNonMatch | 域名未匹配到规则后,再解析并尝试匹配 | 过早命中的宽泛规则会阻止后续解析匹配 |
IPOnDemand | 匹配过程遇到需要 IP 的规则时触发解析 | IP 规则的位置会影响解析发生的时机 |
示例选择 AsIs,因此以域名形式提交的请求不会仅为匹配第二条 IP 规则而解析。不过本例默认出口仍是直连,所以看见请求直连,并不能反推它命中了私有网段规则。排查规则时应看实际匹配和出口,而不只看最终能否打开页面。
dns:分清路由解析与连接解析
配置 dns 不等于接管了所有应用的 DNS。应用可能先自行解析,再把 IP 交给代理;也可能把域名交给 SOCKS 或 HTTP 入口。路由能获得哪些信息,首先取决于入口实际收到什么。
本例的 dns.servers 使用特殊值 localhost,表示通过本地系统解析器解析,不是指定一台运行在本机的 DNS 服务器。它也没有创建 UDP 53 监听端口。若要向应用提供 DNS 服务,需要另行设计接收 DNS 请求的入口和处理路径。
routing.domainStrategy:决定路由匹配阶段是否需要把域名变成 IP。freedom.settings.domainStrategy:决定直连出口如何处理目标域名。dns.servers:提供内置 DNS 使用的解析来源,具体调用时机由相关功能决定。
本例在 freedom 出口设置 UseIP,让直连出口对域名使用内置 DNS 解析流程。这与路由的 AsIs 不冲突:前者发生在出口准备连接时,后者约束的是规则匹配阶段。即使出口后来得到了 IP,也不会自动重新执行已经结束的路由选择。
结论:先确认应用提交的是域名还是 IP
域名规则未命中时,先检查应用是否已经本地解析。不要同时修改路由策略、DNS 服务器和出口协议;每次只改变一层,才能判断是哪一步改变了结果。
验证与排错:从配置检查到实际连接
先用内核自带的检查命令验证配置,再启动监听,最后让应用接入。以下命令在能找到 xray 可执行文件的终端中运行;若文件不在命令搜索路径中,应使用其实际路径。先查看版本和帮助,可以确认当前二进制所支持的参数。
xray version
xray run -help
xray run -test -config ./config.json
xray run -config ./config.json
配置检查通过只说明内核接受这份配置,不代表远端服务可达,也不代表应用已经使用代理。需要做可重复的本地测试时,可以先在另一个终端启动测试服务,再分别通过两个入口访问它:
python -m http.server 8000 --bind 127.0.0.1
curl --noproxy "" --proxy socks5h://127.0.0.1:10808 http://127.0.0.1:8000/
curl --noproxy "" --proxy http://127.0.0.1:10809 http://127.0.0.1:8000/
测试需要本机已安装 Python 和 curl。响应来自本地测试目录,验证的是“应用接入入口、路由选择、直连出口”这条链路。--noproxy "" 用于避免已有绕过代理设置跳过本次入口测试。测试完成后停止临时服务,不要把终端中的目录清单当作代理节点测速结果。
配置检查通过,为什么一启动就退出?
检查控制台是否提示监听失败。确认 10808、10809 未被占用,必要时改为 11808、11809,并同步修改应用代理端口。
加了域名规则,为什么还是走默认出口?
先确认请求携带域名,再检查规则是否被更早的通用规则截获。核对 full: 的完整匹配范围,以及 outboundTag 是否引用了正确出口。
在 v2rayN 里改了运行文件,重启后怎么没了?
客户端可能重新生成运行配置。先保留独立副本,再通过当前版本提供的自定义配置入口加载,或在客户端对应的路由、DNS 设置中修改,不把临时运行文件当作长期配置来源。
能把这份 JSON 直接导入所有客户端吗?
先确认导入入口接受的是原生配置还是节点分享内容。v2rayNG 使用 Xray 内核,v2flyNG 使用 v2fly 内核;完整配置的兼容性仍取决于内核版本、字段支持与客户端的加载方式。
完成基线验证后,再加入远端代理出口,并为它设置明确的路由。每次只改一个部分,保留能运行的上一份配置。这样出现问题时,可以把范围收敛到入口、规则、解析或远端连接,而不是在多个无关设置之间反复切换。