xray配置入站,个人遇到的一点小问题

日志 / 部落格 1991 views 5 replies
#1 ·

Xray VLESS 入站配置:users 还是 clients?

问题

按照 Xray 官方文档 配置 VLESS 入站时,文档要求使用 users 字段:

{
  "inbounds": [{
    "protocol": "vless",
    "settings": {
      "users": [
        { "id": "5783a3e7-e373-51cd-8642-c83782b807c5" }
      ],
      "decryption": "none"
    }
  }]
}

但实际运行时,客户端连接被拒绝,服务器日志报错:

rejected  proxy/vless/encoding: invalid request user id

改为 clients 后一切正常。为什么文档和实际行为不一致?


本机环境

项目 值
Xray 版本 v26.3.27
协议 VLESS
操作系统 Linux (WSL2)
安装日期 2026-06-27
安装方式 官方安装脚本

实验:对照测试

实验设计

构建两个仅字段名不同的 VLESS 入站配置,用同一客户端分别连接,观察服务器日志。

步骤 1 — 准备配置文件

配置 A:使用 users 字段(官方文档写法)

{
  "log": {"loglevel": "debug"},
  "inbounds": [{
    "listen": "127.0.0.1",
    "port": 19997,
    "protocol": "vless",
    "settings": {
      "users": [
        { "id": "test-user-uuid-00000000000000" }
      ],
      "decryption": "none"
    },
    "tag": "vless-in-users"
  }],
  "outbounds": [{"protocol": "freedom", "tag": "direct"}]
}

配置 B:使用 clients 字段(网络教程常见写法)

{
  "log": {"loglevel": "debug"},
  "inbounds": [{
    "listen": "127.0.0.1",
    "port": 19996,
    "protocol": "vless",
    "settings": {
      "clients": [
        { "id": "test-user-uuid-00000000000000" }
      ],
      "decryption": "none"
    },
    "tag": "vless-in-clients"
  }],
  "outbounds": [{"protocol": "freedom", "tag": "direct"}]
}

客户端配置(出站始终使用 users——VLESS 出站未受影响)

{
  "log": {"loglevel": "debug"},
  "inbounds": [{
    "listen": "127.0.0.1",
    "port": 29998,
    "protocol": "dokodemo-door",
    "settings": {"address": "httpbin.org", "port": 80, "network": "tcp"},
    "tag": "dokodemo-in"
  }],
  "outbounds": [{
    "protocol": "vless",
    "settings": {
      "vnext": [{
        "address": "127.0.0.1",
        "port": 19997,
        "users": [{
          "id": "test-user-uuid-00000000000000",
          "encryption": "none"
        }]
      }]
    },
    "streamSettings": {"network": "tcp"},
    "tag": "vless-out"
  }]
}

步骤 2 — 运行测试

测试 A:users 配置

# 启动服务器
/tmp/xray run -c server_users.json &
SERVER_PID=$!

# 等待服务器就绪
sleep 2

# 启动客户端并发起请求
/tmp/xray run -c client.json &
CLIENT_PID=$!

# 通过 dokodemo-door 代理访问 httpbin.org
curl -x http://127.0.0.1:29998 http://httpbin.org/ip

测试 B:clients 配置

# 同上,仅将服务器配置和端口替换为 server_clients.json / 19996

步骤 3 — 对比日志

测试 A 的服务器日志(users):

from 127.0.0.1:46619 rejected
  proxy/vless/encoding: invalid request user id: 14268965-70cd-5490-ac03-e71afae4f108

[Info] proxy/vless/inbound: firstLen = 159
[Info] app/proxyman/inbound: connection ends > proxy/vless/inbound:
  invalid request from 127.0.0.1:46619 >
  proxy/vless/encoding: invalid request user id: ...

测试 B 的服务器日志(clients):

[Info] proxy/vless/inbound: firstLen = 159
[Info] proxy/vless/inbound: received request for tcp:httpbin.org:80
[Info] app/dispatcher: default route for tcp:httpbin.org:80
[Info] transport/internet/tcp: dialing TCP to tcp:httpbin.org:80
from 127.0.0.1:43385 accepted tcp:httpbin.org:80 [vless-in-clients >> direct]
[Info] proxy/freedom: connection opened to tcp:httpbin.org:80,
  local endpoint 192.168.1.249:44725, remote endpoint 198.18.56.109:80

结论

字段名 连接结果 服务器行为
users ❌ 拒绝 用户列表为空,不认识任何客户端
clients ✅ 接受 正确识别用户,成功转发到目标

根因分析

追溯源码

VLESS 入站配置由 Protobuf 定义。检查 Xray-core 源码:

文件:proxy/vless/inbound/config.proto

message Config {
  repeated xray.common.protocol.User users = 1;
  repeated Fallback fallbacks = 2;
  string decryption = 3;
  // ...
}

对应生成的 Go 结构体(config.pb.go):

type Config struct {
    Users     []*protocol.User `protobuf:"bytes,1,rep,name=users,proto3" json:"users,omitempty"`
    Fallbacks []*Fallback      `protobuf:"bytes,2,rep,name=fallbacks,proto3" json:"fallbacks,omitempty"`
    Decryption string          `protobuf:"bytes,3,opt,name=decryption,proto3" json:"decryption,omitempty"`
    // ...
}

JSON tag 是 json:"users,omitempty"——这和官方文档一致。但本机版本为什么不是这样?

字段名在 2026 年 5 月被重命名

通过 Git 历史追踪,找到了决定性 commit:

c42deab55c  2026-05-07  Config: Rename inbounds' `clients`/`accounts` to `users` (#6083)

PR #6083 的作者(Meo597)将以下入站协议的字段统一重命名:

协议 旧字段名 新字段名 向后兼容
VLESS clients users 无别名,直接破坏
VMess clients users 同上
Trojan clients users 同上
Shadowsocks clients users 同上
Socks accounts users 保留别名
HTTP accounts users 保留别名

PR 讨论中明确了 VLESS/VMess/Trojan/Shadowsocks 不保留别名,这意味着旧配置必须手动修改字段名。

版本发布情况

PR 于 2026-05-07 合并。之后的发布记录:

版本 日期 类型 users 支持
v26.3.27 2026-03-27 稳定版 ❌ 只有 clients
v26.3.23 2026-03-23 pre-release ❌
v26.4.x 2026-04 pre-release ❌
v26.5.3 2026-05-03 pre-release ❌
v26.5.9 2026-05-09 pre-release ✅
v26.6.x 2026-06 pre-release ✅
v26.6.27 2026-06-27 pre-release ✅

v26.3.27 是最新的稳定版。 所有带 users 字段的版本(v26.5.9+)至今都是 pre-release。

为什么下载到的是 "旧版"

GitHub 的 /releases/latest API 返回 最新的非 pre-release 版本:

$ curl -s "https://api.github.com/repos/XTLS/Xray-core/releases/latest"
→ "tag_name": "v26.3.27"    (2026-03-27)

官方安装脚本默认调用此 API,因此任何用户通过标准方式安装都会得到 v26.3.27——即使有更新的 pre-release。

文件时间戳证实了这一点:

$ stat /tmp/xray
  Birth: 2026-06-27 00:01:29   ← 确实是昨天下载的
  Version: 26.3.27              ← 但版本是 3 月的

没有做错任何事——官方文档已经更新为 users,但官方稳定版还在用 clients,而安装脚本默认装稳定版。这是一个文档与稳定发布之间的同步滞后问题。


Protobuf 的静默忽略机制

一个关键问题:为什么用 users 字段时 Xray 不报错,而是静默失败?

Protobuf 的 JSON 解析器默认行为是忽略未知字段。在 v26.3.27 的代码中:

  1. JSON 中出现 "users" → Protobuf 在 Config 消息中查找字段名 users
  2. v26.3.27 的 Config 定义中,字段名叫 clients,没有 users
  3. Protobuf 将 "users" 视为未知字段,静默丢弃
  4. 结果:Config.Users(Go 字段)为空切片 → 零个合法用户
  5. 任何客户端连接都因 "invalid request user id" 被拒绝

这意味着用错字段名的配置可以正常启动、不报任何 warning,但功能完全失效。这对排查问题极为不利。


复现指南

以下步骤可在任何 Linux 环境复现本研究的结论。

环境准备

# 下载最新稳定版 Xray(将得到 v26.3.27)
bash -c "$(curl -sL https://raw.githubusercontent.com/XTLS/Xray-install/main/install-release.sh)" @ install

实验步骤

1. 创建 users 测试配置

cat > /tmp/srv_users.json <<'EOF'
{
  "log": {"loglevel": "debug"},
  "inbounds": [{
    "listen": "127.0.0.1", "port": 19997,
    "protocol": "vless",
    "settings": {
      "users": [{"id": "test-user-uuid-00000000000000"}],
      "decryption": "none"
    },
    "tag": "vless-in"
  }],
  "outbounds": [{"protocol": "freedom", "tag": "direct"}]
}
EOF

2. 启动服务器并观察日志

xray run -c /tmp/srv_users.json &
sleep 2

3. 用任意 VLESS 客户端连接,观察日志

# 服务器日志将显示:
# rejected  proxy/vless/encoding: invalid request user id

4. 将 users 改为 clients,重复测试

# 服务器日志将显示:
# accepted tcp:<target> [vless-in >> direct]

验证版本边界

# 检查本地版本
xray version

# 查看 GitHub 最新稳定版
curl -s https://api.github.com/repos/XTLS/Xray-core/releases/latest | jq '.tag_name'

# 查看所有版本(含 pre-release)
curl -s https://api.github.com/repos/XTLS/Xray-core/releases | jq '.[].tag_name'

解决方案

使用 clients

如果通过标准安装方式获取 Xray,版本就是 v26.3.27 稳定版,使用 clients。

{
  "inbounds": [{
    "protocol": "vless",
    "settings": {
      "clients": [
        {
          "id": "your-uuid-here",
          "flow": "xtls-rprx-vision"
        }
      ],
      "decryption": "none"
    }
  }]
}

方案二:升级到 pre-release 并使用 users

# 指定 pre-release 版本安装
XRAY_VERSION=v26.6.27 bash -c "$(curl -sL https://raw.githubusercontent.com/XTLS/Xray-install/main/install-release.sh)" @ install

然后配置文件使用 users。


时间线总结

2026-03-27  v26.3.27 稳定版发布(字段名: clients)
     │
     │  4 月期间多个 pre-release(仍为 clients)
     │
2026-05-07  PR #6083 合并 → main 分支字段名改为 users
     │
2026-05-09  v26.5.9 pre-release(首个使用 users 的版本)
     │
     │  5-6 月多个 pre-release(均为 users)
     │
2026-06-27  v26.6.27 pre-release 发布
     │          官方文档跟踪 main 分支 → 文档写 users
     │          GitHub API /releases/latest → 仍返回 v26.3.27
     │
2026-06-28  本文撰写日期
     │          稳定版用户 → 应用 clients
     │          官方文档   → 写的是 users
     │          ═══════════════════════════
     │          两者不一致,差距已达 52 天

参考资料

#2 ·

注:本文由deepseek创作

#3 ·

突然意识到为什么xjtu.app叫土原,大概相对于上交的水源吧?

💯️❤️
4
#4 ·

以前一直是x-ui一键配置,这次尝试手动写xray配置文件,方遇到问题

#5 ·

xray 文档有点神人,很多模块都没写清楚,也不知道是不是故意的(
不过写了的部分还挺清楚的

倒是现在可以直接让 agent explore 一下

❤️
1
#6 ·

我当时是真的一点都不想看,直接丢给AI然后让它帮我配了VLESS,最后还是成功了;但是因为我VPS本身烂,是香港的,啥AI服务都用不了,所以实际上没啥用。

❤️
1