Files
Xboard/docs/v2bx-integration.zh-CN.md
T
2026-02-22 02:52:32 +08:00

328 lines
8.7 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# Xboard 对接 V2bX 完整文档
本文基于以下两套源码交叉整理:
- 面板端:`Xboard-new`
- 节点端:`E:/code/go/V2bX`
适用目标:让 `V2bX` 节点稳定对接 `Xboard`,完成配置拉取、用户同步、流量上报、在线设备上报。
## 1. 对接结论(先看这个)
1. `V2bX` 当前固定请求 `Xboard``V1 UniProxy` 路径(不是 `V2` 路径):
- `GET /api/v1/server/UniProxy/config`
- `GET /api/v1/server/UniProxy/user`
- `GET /api/v1/server/UniProxy/alivelist`
- `POST /api/v1/server/UniProxy/push`
- `POST /api/v1/server/UniProxy/alive`
2. 鉴权依赖 URL Query 参数:`token``node_id``node_type`
3. `Xboard``server_token` 长度需要 >= 16。
4. `V2bX` 启动时如果拉不到可用用户会直接报错退出:`add users error: not have any user`
5. 在线设备数据写入由队列任务处理,面板端必须保证队列消费者(通常 `horizon`)在运行。
## 2. 源码级接口对齐
## 2.1 V2bX 侧(请求方)
关键实现:
- `api/panel/panel.go`:初始化 Query 参数(`node_type/node_id/token`),并限制 `NodeType` 枚举。
- `api/panel/node.go`:拉取节点配置(`/api/v1/server/UniProxy/config`)。
- `api/panel/user.go`:拉取用户、在线列表,上报流量和在线 IP。
- `node/controller.go`:启动时先拉配置和用户,再注册节点。
- `node/task.go`:按 `pull_interval/push_interval` 定时同步与上报。
## 2.2 Xboard 侧(服务方)
关键实现:
- `app/Http/Routes/V1/ServerRoute.php``/api/v1/server/UniProxy/*` 路由定义。
- `app/Http/Middleware/Server.php`:校验 `token/node_id/node_type`,并注入 `node_info`
- `app/Http/Controllers/V1/Server/UniProxyController.php`:实现 `config/user/push/alive/alivelist/status`
- `app/Services/ServerService.php`:按 `node_id`(支持 `code``id`)和 `node_type` 查节点,按权限组取可用用户。
- `app/Jobs/UpdateAliveDataJob.php`:异步写在线设备计数。
## 3. 类型与协议兼容要点
`V2bX` 允许的 `NodeType``api/panel/panel.go`):
- `vmess`
- `vless`
- `trojan`
- `shadowsocks`
- `hysteria`
- `hysteria2`
- `tuic`
- `anytls`
- 兼容别名:`v2ray -> vmess`
`Xboard` 节点类型(`app/Models/Server.php`)有别名:
- `v2ray -> vmess`
- `hysteria2 -> hysteria`
建议:
1. 绝大多数场景按面板节点真实类型填写 `NodeType`
2. Hysteria v2 场景建议仍使用 `NodeType: "hysteria"`,在面板协议设置里把 `version` 设为 `2`,避免类型语义混乱。
3. `V2bX` 并不对接 `Xboard``socks/naive/http/mieru` 这几类。
## 4. Xboard 面板端配置步骤
## 4.1 全局通信参数
后台系统配置里设置:
- `server_token`:与 V2bX 的 `ApiKey` 完全一致,长度建议 32+。
- `server_pull_interval`:节点拉配置周期(秒)。
- `server_push_interval`:节点推送流量周期(秒)。
- `device_limit_mode`:设备限制统计策略(按你的业务选)。
源码依据:
- `app/Http/Controllers/V2/Admin/ConfigController.php`
- `app/Http/Requests/Admin/ConfigSave.php`
## 4.2 创建节点(每个 NodeID 对应一个节点)
至少需要正确配置:
- `type`
- `name`
- `host`
- `port`
- `server_port`
- `group_ids`
- `rate`
- `protocol_settings`(按协议必填项)
源码依据:`app/Http/Requests/Admin/ServerSave.php`
## 4.3 用户可用性条件(非常关键)
节点可拉到的用户必须同时满足(`ServerService::getAvailableUsers`):
- 用户 `group_id` 在节点 `group_ids`
- `u + d < transfer_enable`
- 未过期
- 未被禁用
否则 `V2bX` 首次启动可能直接失败(无可用用户)。
## 4.4 队列进程
`/alive` 上报会派发 `UpdateAliveDataJob``online_sync` 队列。
若没有队列消费者,在线设备统计会滞后或不更新。
建议至少保证:
- `php artisan horizon` 正常运行
## 5. V2bX 配置(可直接改)
参考 `E:/code/go/V2bX/example/config.json`
## 5.1 单节点最小可用示例
```json
{
"Log": {
"Level": "info",
"Output": ""
},
"Cores": [
{
"Type": "sing",
"Log": {
"Level": "info",
"Timestamp": true
},
"OriginalPath": "/etc/V2bX/sing_origin.json"
}
],
"Nodes": [
{
"Core": "sing",
"ApiHost": "https://panel.example.com",
"ApiKey": "请填写与Xboard一致的server_token",
"NodeID": 1,
"NodeType": "vmess",
"Timeout": 30,
"ListenIP": "0.0.0.0",
"SendIP": "0.0.0.0",
"DeviceOnlineMinTraffic": 200,
"MinReportTraffic": 0
}
]
}
```
## 5.2 字段说明(高频踩坑项)
- `ApiHost`:必须是面板根地址,不要写成 `.../api/v1`
- `ApiKey`:对应 `Xboard server_token`
- `NodeID`:对应面板节点 `id`(或数值型 `code`)。
- `NodeType`:必须是 V2bX 支持的枚举。
- `Timeout`HTTP 超时秒数。
- `ApiSendIP`(可选):多网卡时指定请求源 IP。
源码依据:`E:/code/go/V2bX/conf/node.go`
## 6. 启动与热重载
## 6.1 启动命令
```bash
V2bX server -c /etc/V2bX/config.json
```
默认支持 `--watch`(开启配置监听),配置文件变化后会自动重载核心和节点。
源码依据:`E:/code/go/V2bX/cmd/server.go`
## 6.2 建议运行形态
- 使用 `systemd` 托管 `V2bX`
- 配置 `Restart=always`
- 单独落日志文件,便于排错
## 7. 联调验证(建议按顺序)
## 7.1 手工验证面板接口可达
在节点机执行(把参数换成你的真实值):
```bash
curl -sS "https://panel.example.com/api/v1/server/UniProxy/config?node_type=vmess&node_id=1&token=YOUR_TOKEN"
```
预期:返回 JSON,包含 `base_config.push_interval``base_config.pull_interval`
```bash
curl -sS "https://panel.example.com/api/v1/server/UniProxy/user?node_type=vmess&node_id=1&token=YOUR_TOKEN"
```
预期:返回 `users` 列表,且非空(至少有一个可用用户)。
## 7.2 启动后看 V2bX 日志
应出现这类信息:
- `Core ... started`
- `Nodes started`
- 周期性 `Report N users traffic`
- 周期性在线用户上报日志
## 7.3 面板侧确认
- 节点状态 `last_check_at``last_push_at` 持续刷新
- 用户流量持续累加
- `online_count` 有变化(需要队列正常)
## 8. 常见问题与处理
## 8.1 `unsupported Node type`
原因:`NodeType` 不在 V2bX 白名单。
处理:改为支持值(如 `vmess/vless/trojan/shadowsocks/hysteria/tuic/anytls`)。
## 8.2 `Invalid token`
原因:`ApiKey != server_token`
处理:面板与节点统一同一密钥,并确认没有前后空格。
## 8.3 `Server does not exist`
原因:
- `NodeID` 错误
- `NodeType` 与面板节点类型不匹配
处理:先在面板确认节点 ID/类型,再校正 V2bX 配置。
## 8.4 `add users error: not have any user`
原因:该节点按权限组筛选后没有可用用户。
处理:
1. 确认节点 `group_ids`
2. 确认至少一个用户满足流量/到期/禁用条件
## 8.5 在线设备不上报或不更新
原因:面板队列消费者未运行。
处理:启动并确认 `horizon` 正常消费(尤其 `online_sync` 队列)。
## 8.6 配置路径重复导致 404
原因:`ApiHost` 写成 `https://panel/api/v1`,最终拼接成重复路径。
处理:`ApiHost` 只保留根域名(如 `https://panel.example.com`)。
## 9. 请求/响应数据形状(排错用)
## 9.1 配置拉取
- 请求:`GET /api/v1/server/UniProxy/config?node_type=...&node_id=...&token=...`
- 响应:按协议字段 + `base_config`
## 9.2 用户拉取
- 请求:`GET /api/v1/server/UniProxy/user?...`
- 响应:`{"users":[{"id":1,"uuid":"...","speed_limit":0,"device_limit":0}]}`(也兼容 msgpack
## 9.3 流量上报
- 请求:`POST /api/v1/server/UniProxy/push?...`
- BodyV2bX 实际发送):
```json
{
"1001": [12345, 67890],
"1002": [11111, 22222]
}
```
## 9.4 在线上报
- 请求:`POST /api/v1/server/UniProxy/alive?...`
- Body
```json
{
"1001": ["1.1.1.1", "2.2.2.2"],
"1002": ["3.3.3.3"]
}
```
## 10. 安全建议
1. `ApiHost` 必须用 HTTPS。
2. `server_token` 使用高强度随机值并定期轮换。
3. 在反向代理/Nginx 层限制节点来源 IP 访问 `server/UniProxy` 接口。
4. 变更 `server_token` 后,面板与全部节点必须同时切换。
## 11. 代码参考索引
Xboard
- `app/Http/Routes/V1/ServerRoute.php`
- `app/Http/Middleware/Server.php`
- `app/Http/Controllers/V1/Server/UniProxyController.php`
- `app/Services/ServerService.php`
- `app/Jobs/UpdateAliveDataJob.php`
- `app/Http/Requests/Admin/ConfigSave.php`
- `app/Http/Requests/Admin/ServerSave.php`
V2bX
- `api/panel/panel.go`
- `api/panel/node.go`
- `api/panel/user.go`
- `node/controller.go`
- `node/task.go`
- `node/user.go`
- `conf/node.go`
- `cmd/server.go`
- `example/config.json`