3x-ui 批量添加 Socks5 出站、客户端与 User 路由配置总结
生成内容:问题复盘、最终方案、运行步骤、最终版脚本说明
1. 最终结果
本次目标:将 socks.txt 中的 socks5 代理批量写入 3x-ui/Xray 配置,按每个出站 IP 创建对应客户端,并用 user 路由让对应客户端流量走对应 socks5 出站。
| 项目 | 结果 |
|---|---|
| socks.txt 数量 | 165 条 |
| 客户端创建 | 已创建;重复运行时会识别 email 已存在并跳过 |
| socks5 出站 | 已成功写入 165 个,tag 格式为 socks-<IP,点号替换为短横线> |
| user 路由规则 | 已成功写入 165 条,按客户端 email 匹配出站 |
| Xray 重启 | 已成功重启 |
| 验证结果 | 当前运行配置 socks 出站 165 个,socks 路由 165 条 |
2. 关键结论
- 客户端创建接口和 Xray 模板接口不是同一类接口。客户端使用 /panel/api/inbounds/addClient;出站和路由需要读取并更新 /panel/xray/ 的 Xray 模板。
- /panel/xray#outbound 和 /panel/xray#routing 只是浏览器前端锚点,# 后面的内容不会发送到服务器。脚本里应使用 /panel/xray/ 和 /panel/xray/update。
- Bearer Token 可用于多数 /panel/api/* 接口,但本次实例中 /panel/xray/ 使用 Bearer 访问返回 404,最终采用浏览器 Cookie + CSRF 成功。
- 该 3x-ui 版本的 /panel/xray/ 返回格式比较特殊:外层 obj 是字符串,字符串内部才是 JSON;其中 xraySetting 是对象,不是字符串。最终脚本已兼容这种返回格式。
- 路由规则必须放在 routing.rules 前面,避免被已有的 direct、blocked、proxy 等兜底规则提前匹配。
3. 实际使用到的接口
| 用途 | 接口 | 方法 | 说明 |
|---|---|---|---|
| 获取 CSRF | /csrf-token | GET | Cookie 登录状态下获取 X-CSRF-Token |
| 读取入站列表 | /panel/api/inbounds/list | GET | 用于检查客户端 email 是否已存在 |
| 批量添加客户端 | /panel/api/inbounds/addClient | POST | settings 字段是 JSON 字符串,内部为 clients 数组 |
| 读取 Xray 模板 | /panel/xray/ | POST | 返回 xraySetting、inboundTags、outboundTestUrl 等信息 |
| 保存 Xray 模板 | /panel/xray/update | POST | 表单提交 xraySetting 和 outboundTestUrl |
| 重启 Xray | /panel/api/server/restartXrayService | POST | 保存后重启让配置生效 |
| 验证运行配置 | /panel/api/server/getConfigJson | GET | 统计当前运行配置中的 socks 出站和路由数量 |
4. 数据映射规则
| 输入 socks 行 | 客户端 email | 出站 tag | 路由匹配 |
|---|---|---|---|
| 216.223.17.163:8022:user:pass | 216.223.17.163 | socks-216-223-17-163 | user=["216.223.17.163"] -> outboundTag=socks-216-223-17-163 |
生成的 socks5 出站结构:
{
"tag": "socks-216-223-17-163",
"protocol": "socks",
"settings": {
"servers": [
{
"address": "216.223.17.163",
"port": 8022,
"users": [{"user": "user", "pass": "pass"}]
}
]
}
}
生成的 user 路由结构:
{
"type": "field",
"user": ["216.223.17.163"],
"outboundTag": "socks-216-223-17-163"
}
5. 问题排查过程
| 现象 | 原因 | 处理 |
|---|---|---|
| Windows 报 No module named requests | 本地 Python 环境没有 requests 模块 | 改为服务器运行,或安装 python3-requests |
| 客户端添加成功,但出站/路由未添加 | 客户端接口成功,Xray 模板接口读取失败 | 单独写补救脚本,只处理出站和路由 |
| /panel/xray/ Bearer 返回 404 | 该页面接口不接受当前 Bearer 方式 | 切换浏览器 Cookie + CSRF |
| /login 返回 403 | 脚本登录方式或安全路径限制 | 直接复用浏览器已登录 Cookie |
| 误把 cat > ... 写进 py 文件 | 把 shell 命令当 Python 代码粘进文件 | 重新用 shell heredoc 覆盖脚本 |
| 识别不到 xraySetting | 返回 obj 是字符串,且 xraySetting 是对象 | 修补解析函数,先 json.loads(obj),再读取 xraySetting 对象 |
| 删除旧 socks 出站显示负数 | 统计删除数量时在新增后计算 | 最终版脚本已修复为新增前计算删除数量 |
6. 最终版运行步骤
1)安装依赖:
apt update && apt install -y python3 python3-requests
2)准备 socks.txt:
nano /root/socks.txt
# 每行格式:ip:端口:用户名:密码
216.223.17.163:8022:user:pass
3)从浏览器复制 Cookie:
- 登录 3x-ui 面板。
- 按 F12 打开开发者工具。
- 进入 Network,点 xray/ 这个状态 200、类型 xhr 的请求。
- 在 Request Headers 中复制 Cookie 后面的内容,不要复制 Cookie: 前缀。
4)编辑最终脚本顶部配置:
PANEL_ROOT = "https://你的面板IP或域名:端口/你的安全路径"
BROWSER_COOKIE = "浏览器复制的 Cookie 内容"
SOCKS_FILE = "/root/socks.txt"
INBOUND_ID = 1
ADD_CLIENTS = True
5)运行脚本:
python3 -m py_compile /root/3xui_socks_client_outbound_route_final.py
python3 /root/3xui_socks_client_outbound_route_final.py
7. 安全建议
- 本次过程中曾在聊天里暴露面板账号、密码和 API Token。建议处理完成后立即重置面板密码,并删除旧 API Token 后重新创建。
- Cookie 等同于已登录会话,不要长期保存到公开位置。脚本执行完成后可清空 BROWSER_COOKIE。
- 运行前脚本会备份 Xray 模板到 /root/xraySetting.backup.before_socks.json。出现异常时可用该文件人工恢复。
- 如果只想处理前 150 条,把 LIMIT_COUNT 改成 150;本次实际处理的是 165 条。
8. 最终成功日志摘要
[读取] socks 数量:165
[认证] Cookie + CSRF 成功
[Xray] 读取成功
[备份] 已保存 /root/xraySetting.backup.before_socks.json
[Xray] 新增 socks 出站:165
[Xray] 新增 user 路由:165
[Xray] 保存成功
[Xray] 已重启
[验证] 当前运行配置 socks 出站:165
[验证] 当前运行配置 socks 路由:165
[完成] socks5 出站和 user 路由规则已补齐

Comments NOTHING