清乐云 · 官方文档
企业级网络授权 / 卡密分销 / 代码防破解一体化平台 · 自部署 · 5 种 SDK · 一行接入
1. 产品介绍#
清乐云 面向软件开发商,把「网络授权 + 反破解 + 卡密分销 + 云端下发」打包成一套自部署平台。你的软件(PC / 移动 / 工具 / 游戏辅助等)接入后可获得:
- 授权变现:时长卡 / 次数卡 / 永久卡 + 面额与推荐价,代理商 3 层分销
- 反破解:X0 HMAC 签名 + X1 响应签名 + X2 应用层加密 + X3 加壳反调试 + CloudGate 逻辑云保护
- 实时控制:一键封号 / 强制下线 / 拉黑机器 / 灰度版本 / 远程变量 / 云公告
- 免管理:Docker Compose 一键启动,2C/4G 单机可承载 100 万用户
产品形态
| 组件 | 作用 | 暴露端口 |
|---|---|---|
| server | Go REST + WebSocket API | 内部 8000 |
| admin | Vue 管理后台 + Nginx 静态 | 5173 (可改) |
| postgres / redis | 持久化 / 会话 / 心跳 / 限流 | 仅内网 |
2. 快速开始#
接入只有 3 步:创建应用 → 生成卡密 → 客户端调 SDK。
第一步 · 创建应用
- 进入 管理后台 → 应用管理,点「新增应用」
- 填名称、描述、版本号;机器码/多开/加密选项保持默认即可
- 保存后记录 AppKey 与 RSA 公钥(客户端 SDK 3 个必填参数)
第二步 · 生成一批卡密
- 进入 管理后台 → 卡密管理,点「批量生成」
- 选应用 → 类型(例:时长卡 · 30 天 · 5 张)→ 生成
- 弹窗点「导出本批次」拿到卡号 CSV,用于售卖或代理分发
第三步 · 客户端接入(5 行代码)
pythonfrom qingleyun import Client
c = Client(server="http://your-server:5173", app_key="AK_XXXX", version="1.0.0")
c.activate("CARD-CODE-HERE") # 第一次输入卡密激活
c.login() # 之后每次启动自动登录
c.start_heartbeat() # 后台线程心跳 (默认 60s)
typescriptimport { Client } from './qingleyun.mjs'
const c = new Client({ server: 'http://your-server:5173', appKey: 'AK_XXXX', version: '1.0.0' })
await c.activate('CARD-CODE-HERE')
await c.login()
c.startHeartbeat()
csharpusing 清乐云.SDK;
var c = new QingleyunClient("http://your-server:5173", "AK_XXXX", "1.0.0");
await c.ActivateAsync("CARD-CODE-HERE");
await c.LoginAsync();
c.StartHeartbeat();
cpp#include "qingleyun.hpp"
qly::Client c("http://your-server:5173", "AK_XXXX", "1.0.0");
c.activate("CARD-CODE-HERE");
c.login();
c.start_heartbeat();
3. 管理端功能#
侧栏按 概览 / 经营 / 发布 / 系统 4 组呈现;超管 标记的仅超级管理员可见。所有高危操作会二次密码 sudo。
3.1 概览
3.2 经营
3.3 发布
3.4 系统
3.5 全局能力(非独立菜单)
- 头部工具区:主题(浅/深/跟随系统)、中/英双语、全屏、官方文档
- 服务条款:首次登录强制同意 TosModal,未接受不能进后台
- Sudo 二次密码:删除应用 / 删卡 / 导出 PII / 轮换密钥等操作 5 分钟内需再次输入密码
- 代登录 Banner:impersonate 期间顶栏红条持续提示,全操作审计,一键切回超管
- 响应式布局:桌面 (≥1024px) 全展开侧栏 / 平板 (768-1023px) 侧栏 icon-only / 手机 (<767px) hamburger + drawer
views/user/Index.vue)、TOTP 2FA、修改密码 UI — 通过在线客户 / 卡密 / 黑名单页可间接达成同等操作。
4. 代理商门户#
代理商独立子站,路由前缀 /agent,JWT 与管理端账号完全隔离。入口:代理商登录。
| 页面 | 路径 | 能干什么 |
|---|---|---|
| 仪表盘 | /agent/dashboard | 余额 / 历史充值 / 消费 / 生卡总数;权限套餐摘要;近 30 天销售曲线(销售额 / 佣金 / 生卡数);最近流水与生卡 |
| 生成卡密 | /agent/generate | 选授权应用 → 时长/次数/永久 → 预设时长 → 面额(推荐价一键应用)→ 扣余额生成;受套餐限制(卡类型、日配额、单次上限、允许 app、最低售价系数) |
| 我的卡密 | /agent/cards | 只看自己生成的;高级筛选;复制卡号;若管理员授予 can_freeze_own_cards 可自助冻结/解冻 |
| 资金流水 | /agent/transactions | 充值 / 生卡 / 佣金 / 退款 / 调整等流水按类型筛选 |
| 提现 | /agent/withdrawals | 发起提现(支付宝 / 微信 / 银行卡)→ 冻结对应余额;查状态;等审批打款 |
5. REST API#
Base URL:http://your-server:5173/api(Nginx 反代到内部 8000)。所有 POST 请求 body 为 JSON,Content-Type 必须 application/json。
5.1 客户端签名规则
所有客户端 POST 必带以下三 header,服务端 HMAC-SHA256 校验:
| Header | 说明 |
|---|---|
X-App-Key | 应用 AppKey,管理后台可看 |
X-Timestamp | Unix 秒,服务端容忍 ±300s |
X-Nonce | 32 位随机 hex;10 分钟内不能重放 |
X-Sign | HMAC_SHA256(secret, method|path|timestamp|nonce|body_sha256),hex 小写 |
pythonmsg = f"{method}|{path}|{ts}|{nonce}|{sha256(body).hexdigest()}"
sign = hmac.new(secret.encode(), msg.encode(), sha256).hexdigest()
5.2 客户端接口 /api/client/*
| Method | Endpoint | 说明 |
|---|---|---|
| GET | /info | 应用元信息 + RSA 公钥(X1 验签用) |
| GET | /notice | 启动公告(Markdown) |
| GET | /version | 检查更新 / 拿最新版直链 |
| GET | /variables | 远程变量(带 version 增量) |
| GET | /build/:id/download | 加壳产物下载 |
| GET | /ws | WebSocket 长连接(见 §6) |
| POST | /handshake | X2:RSA-OAEP 换 AES session |
| POST | /integrity | X3:上报 EXE 完整性 hash |
| POST | /free_trial | 免费试用(1h 临时 session,同机 24h 冷却) |
| POST | /activate | 卡密激活 |
| POST | /register | 账号自助注册(App 开启注册码通道后可用) |
| POST | /login | 账号登录,拿 access_token |
| POST | /heartbeat | 心跳(默认 60s,超时自动踢线) |
| POST | /logout | 退出,token 立即失效 |
| POST | /rebind | 客户端自助换机器码(受 rebind_max_count 限制) |
| POST | /check | 通用授权判定(DRM) |
| POST | /resource/get | 受保护数据资源下发(AES 一次性 key) |
| POST | /codeblock/get | CloudGate μVM 字节码下发 |
| POST | /codeblock/hostcall | CloudGate Tier B 服务端计算 |
5.3 管理端接口 /api/admin/*
公开:POST /auth/login、POST /auth/refresh、POST /auth/register-send-code、POST /auth/register-verify、GET /tos。
需登录(按模块,仅列核心):
| 模块 | Endpoint 示例 |
|---|---|
| 认证 | /auth/me · /auth/logout · /auth/change-password · /auth/totp/* · /auth/sudo |
| 服务条款 | /tos/status · /tos/accept |
| 应用 | /apps CRUD · /apps/:id/rotate-key |
| 远程变量 | /apps/:id/variables CRUD |
| 受保护资源 | /apps/:id/resources CRUD(含 type=xvm) |
| 卡密 | /cards · /cards/generate · /cards/import · /cards/extend · /cards/freeze-batch · /cards/:code/freeze |
| 黑名单 | /blacklist CRUD · 支持 kick_online / freeze_cards 联动 |
| 在线 | /online · /online/kick-session · /online/kick-user |
| 代理 | /agents CRUD · /agents/:id/recharge · /agents/:id/permissions |
| 提现 | /withdrawals · /withdrawals/:id/{approve,reject,pay} |
| 版本 / 产物 | /versions CRUD · /builds 上传/签发 |
| 公告 / 审计 | /notices · /audit |
| SDK / Tools | /sdks · /tools/list |
| 导出 sudo | /export/cards · /export/users · /export/agents |
| 超管 super | /admins/* · /admins/:id/impersonate · /tenants/* · /system/health |
5.4 代理商接口 /api/agent/*
| Method | Endpoint | 说明 |
|---|---|---|
| POST | /auth/login · /auth/refresh | 代理登录 |
| GET | /me · /apps · /recommended-prices | 身份 + 授权 app + 推荐价 |
| GET | /cards · /transactions · /withdrawals | 只看自己名下 |
| GET | /stats/overview · /stats/daily | 仪表盘数据源 |
| POST | /cards/generate | 扣余额生成 |
| POST | /cards/:id/{freeze,unfreeze} | 需 can_freeze_own_cards 权限 |
| POST | /withdrawals | 提交提现 |
公开运维:GET /health(健康检查)· GET /metrics(Prometheus,默认仅 loopback)· GET /api/tools/{list,download/:filename,health}(工具包公开下载)。
6. WebSocket 实时通道#
客户端 GET /api/client/ws?token=<access_token> 建立 WSS 长连接,用于:
- 踢线通知:管理端踢线后服务端主动下发
{"type":"kick","reason":"..."},客户端立即退出 - 变量热更新:远程变量表变化推
{"type":"var_update","version":"..."},客户端重新拉/variables - 公告即时推送:新发布公告直接推
{"type":"notice","title":"...","content":"..."}
心跳:客户端每 30s 发 {"type":"ping"},服务端回 {"type":"pong"};90s 无 pong 视为断开重连。
7. SDK 使用#
5 套 SDK 协议层与服务端 字节级一致,每种 SDK 提供:源码 + Demo + 离线签名一致性自检 + README。管理后台 → SDK 下载 一键打包。
Python
单文件 qingleyun.py;标准库为主;可选装 cryptography 支持 X1 验签 / X2 加密。
pythonfrom qingleyun import Client, NetworkError, AuthError
c = Client(server="http://your-server:5173", app_key="AK_XXXX", version="1.0.0")
try:
c.activate("CARD-CODE") # 首次激活;已激活的直接 login
c.login()
c.start_heartbeat(interval=60)
var = c.get_variables()["discount_pct"] # 远程变量
data = c.get_resource("vip_config") # DRM 数据
except AuthError as e:
print("卡密无效或过期", e)
except NetworkError as e:
print("网络失败", e)
TypeScript / JavaScript
支持 Node ≥ 18;qingleyun.ts(源码)+ qingleyun.mjs(编译产物);含 codegate.ts Tier B async 支持。
typescriptimport { Client } from './qingleyun.mjs'
const c = new Client({ server: 'http://your-server:5173', appKey: 'AK_XXXX', version: '1.0.0' })
await c.activate('CARD-CODE')
await c.login()
c.startHeartbeat()
const { discountPct } = await c.getVariables()
C# / .NET
单文件 QingleyunClient.cs;.NET 6+;只依赖 BCL;含 CodeGate.cs 与 WinForms / WPF / Console Demo。
csharpusing 清乐云.SDK;
var c = new QingleyunClient("http://your-server:5173", "AK_XXXX", "1.0.0");
try
{
await c.ActivateAsync("CARD-CODE");
await c.LoginAsync();
c.StartHeartbeat();
}
catch (AuthException ex) { Console.WriteLine($"卡密无效: {ex.Message}"); }
C++
Header-only qingleyun.hpp;Windows Only(Vista+);只依赖 WinHTTP + BCrypt;含 xvm.hpp(μVM 解释器)。
cpp#include "qingleyun.hpp"
qly::Client c("http://your-server:5173", "AK_XXXX", "1.0.0");
try {
c.activate("CARD-CODE");
c.login();
c.start_heartbeat();
} catch (const qly::AuthError& e) {
MessageBoxA(nullptr, e.what(), "授权失败", MB_ICONERROR);
}
易语言
提供 清乐云.ec 模块 + demo;仅 Windows 核心库;无第三方依赖。
e清乐云.初始化 ("http://your-server:5173", "AK_XXXX", "1.0.0")
如果真 (清乐云.激活卡密 ("CARD-CODE") = 真)
清乐云.登录 ()
清乐云.启动心跳 ()
如果真结束
8. 加壳工具(PackerX32)#
官方工具包提供两条加壳路线,从 管理后台 → 工具下载 获取 zip 后本地运行。
| 方案 | 可执行文件 | 定位 |
|---|---|---|
| pe_patcher(推荐生产) | patcher.exe | 注入 .qly 节 + 运行时 DLL;可勾选 VMProtect 二次加壳;支持 X3 完整性预生成 |
| PackerX32 经典 | packer.exe + stub.exe | 把目标 EXE 嵌入 stub RCDATA;运行时先弹卡密,再解压启动 |
加壳流程(pe_patcher)
- 解压 zip,双击
patcher.exe(qly_runtime*.dll / vmp 目录须同级) - 首次输入管理员账号密码(在 管理员 页创建);勾「记住本机」加密保存本地
- 选目标 EXE → 自动识别 x86/x64 → 选 AppKey、客户端版本、安全 flags(反调试 / 反 Hook / 完整性 / 字符串混淆)
- 点「加壳」→ 输出
原名_qly.exe - 可勾 VMProtect 双层(轻度 / 标准 / 极度 preset 或自定义
.vmp) - 加壳完成后可算 X3 expected hash 写入 sidecar,供管理端 应用管理 一键 promote
patcher.exe --input app.exe --appkey AK_XXX --version 1.0.0 --sec-flags 0x07 --vmp
安全选项 (X3)
| flag | 能力 | 命中后 |
|---|---|---|
0x01 | 反调试(5 层) | ExitProcess(0xDEAD0001) |
0x02 | 反 Hook(12 关键 API) | ExitProcess(0xDEAD0002) |
0x04 | 完整性校验 | ExitProcess(0xDEAD0003) |
0x08 | 字符串混淆 | — |
9. CloudGate 代码保护#
CloudGate 把 1-3 个关键函数编译成 μVM 字节码(XVM) 存服务端,客户端 CodeGate.invoke(name, args) 凭 valid token 拉取 → 内存里解释执行 → 用完清零。反破解者反编译本地二进制看不到这段逻辑,无 token 拿不到字节码。
与普通 DRM 的区别
| 特性 | 受保护资源(DRM 数据) | CloudGate(代码保护) |
|---|---|---|
| 保护对象 | 字符串 / JSON / binary | 代码逻辑 |
| 接口 | POST /resource/get | POST /codeblock/get |
| 执行位置 | 客户端拿明文使用 | 客户端 μVM 解释;Tier B 关键步骤在服务端 |
| 抗静态逆向 | 只能防抓包 | 逻辑不在本地二进制 |
使用步骤
- 进入 XVM 编译器,用类 C 高级语言或 XVM 汇编写核心函数
- 点「编译」→「测试运行」验证结果(Tier B 的
server(...)调用需部署后测) - 点「保存为受保护资源」,选目标应用 + 资源名 + 访问权限(任意登录 / 已激活 / VIP)
- 去 应用管理 打开 CloudGate 代码块下发 开关
- 客户端 SDK 里调
CodeGate.invoke("license_gate", [seed])
两档模式
- Tier A · 全客户端:字节码整段发下去,本地 μVM 解释。快,适合轻量算法。
- Tier B · 服务端计算:字节码含
CALLH SERVER指令,遇到该指令客户端调/codeblock/hostcall让服务端算完再返回。最秘密的一步不出客户端。
详见 CLOUDGATE_GUIDE.md(工程完整版)。
10. 安全体系#
清乐云采用 5 层纵深防御:从传输层到应用层到客户端二进制到代码逻辑,逐层加固。
| 层 | 机制 | 作用 | 可选/默认 |
|---|---|---|---|
| 传输 | HTTPS + Nginx | 加密链路防中间人 | 生产必需 |
| X0 | HMAC-SHA256 请求签名 + Nonce 防重放 | 防篡改、防重放、防伪造客户端 | 默认全开 |
| X1 | RSA-PSS 响应签名(X-Resp-Sign) | 客户端用 App 公钥验签,防伪造服务端响应 | 默认全开 |
| X2 | 应用层 Body 加密(RSA-OAEP 握手 + AES-256-GCM) | 抓包也看不到明文(含 HTTPS 被 MitM 场景) | App 级开关 |
| X3 | 加壳反调试 / 反 Hook / 完整性 hash | 客户端二进制反破解 | 加壳时勾选 |
| 业务 | 机器码黑名单(3 级 severity) | 拉黑破解者机器;可踢线 + 冻卡 | 手动或联动 |
| 逻辑 | CloudGate μVM 字节码 + Tier B | 关键函数不在本地二进制里 | App 级开关 |
认证与鉴权
- JWT 双 Token:access 2h + refresh 7d;密钥 ≥ 32 字符且不含 placeholder 词
- JWT 撤销:logout / 改密时 jti 加 Redis 黑名单,立即失效
- Sudo:删除、重置密码、轮换密钥、导出 PII 等操作 5 分钟内需再输密码
- 登录锁定:5 次失败锁 15 分钟,按 username+IP 维度
- TOTP 2FA:管理员可绑 Google Authenticator(API 已就绪,UI 待开)
- 用户名枚举防御:错误信息统一
invalid credentials
数据与运行时
- PII 字段 AES 入库:邮箱、手机号、代理付款账号等以
NETAUTH_AES_FIELD_KEY加密存储(key 与 JWT 独立) - RSA 密钥独立持有:每 App 一对独立 2048 密钥,私钥仅服务端持有;一键轮换
- 审计全量:所有写操作
audit_logs全量记录,可溯源 - Metrics 隔离:
/metrics默认仅 loopback;/health不暴露版本 footprint
11. 部署运维#
官方仅支持 Docker Compose 部署。参考 docker-compose.yml + docs/deployment.md。
一键启动
bash# 1. 克隆代码
git clone https://your-repo/qingleyun.git && cd qingleyun
# 2. 配置环境变量
cp .env.example .env
vim .env # 必填 POSTGRES_PASSWORD / REDIS_PASSWORD / JWT_SECRET / NETAUTH_AES_FIELD_KEY / ADMIN_INIT_PASSWORD
# 3. 启动全部服务
docker compose up -d
# 4. 打开管理后台
open http://$(hostname -I | awk '{print $1}'):5173
核心环境变量
| 变量 | 要求 | 说明 |
|---|---|---|
POSTGRES_PASSWORD | 强密码 | Postgres root |
REDIS_PASSWORD | 强密码 | Redis auth |
JWT_SECRET | ≥ 32 字符 | JWT 签名,不能含 changeme 等占位词 |
NETAUTH_AES_FIELD_KEY | ≥ 32 字符,≠ JWT | PII 字段加密 |
ADMIN_INIT_PASSWORD | ≥ 12 字符 | 首个 super admin 初始密码,登录后立即改 |
ADMIN_HTTP_PORT | 默认 5173 | admin 容器映射端口 |
NETAUTH_SDK_DIR | 路径 | SDK 下载源目录 |
NETAUTH_TOOLS_DIR | 路径 | 工具包公开下载目录 |
生产建议
- HTTPS 反代:外面套 Nginx + Let's Encrypt / 商业证书;
/api/反代 server - 水平扩容:
docker compose up -d --scale server=3;server 无状态可任意伸缩 - 备份:每日
pg_dump加异地 S3;RSA 私钥文件 单独异地备份(丢失所有客户端握手/签名全废) - 监控:
/health接可用性探针;/metrics接 Prometheus;日志 JSON 接 Loki/ELK - 更新 SDK / 工具:改
sdk/或tools/目录后docker compose restart server即可
12. 常见问题#
客户换电脑了怎么办?
三条路:① 应用允许「客户端自助换绑」,客户端调 /rebind(扣配额);② 客服在 卡密管理 里点该卡「换绑机器码」(强制换绑不扣次数);③ 在应用配置里放宽 rebind_max_count。
支持哪些数据库?
官方支持 PostgreSQL 16+(15 也能跑)。MySQL / SQLite 未适配。
能扛多少并发?
单实例(2C/4G)实测:100 万注册用户 + 1000 万卡密 + 10000 并发心跳。瓶颈基本在 Postgres;上 3 副本 + Redis Sentinel 后可到 10 万并发。
能不能让用户在线买卡?
系统本身不含收银台,但代理商门户 /agent-login 就是"卡商门户";配合微信/支付宝面对面收款或对接你自己的 CDK 站,让下级代理买卡后代客户激活即可。
远程变量更新客户端要等多久?
接了 WebSocket 的客户端 即时收到 var_update 推送;未接 WS 的下次心跳(默认 60s)会带 version 增量拉取。
能不能强制下架某版本?
可以。版本管理 → 找到那版本 → 点「停用」;下次客户端 GET /version 会自动回退到上一个可用版本。
X2 应用层加密开了之后老 SDK 客户端会不会挂?
会。X2 开启前请确认所有客户端都升级到支持 /handshake 的版本;旧 SDK 会握手失败。建议先灰度:新版 SDK 发布 → 观察 30 天 → 后台开 X2。
怎么防止软件被破解?
五层组合拳:① 加壳勾选反调试 + 反 Hook + 完整性(X3);② 上 VMP 双层;③ 开 X2 加密通道;④ 核心算法搬到 CloudGate;⑤ 及时把发现的破解机器加黑名单。任何单层都不是银弹,堆叠才有威慑力。
调试器检测触发后用户看到啥?
进程被 ExitProcess(0xDEAD000X) 静默结束,不弹窗。0xDEAD0001=调试器 / 0xDEAD0002=Hook / 0xDEAD0003=完整性。排查建议:让用户关杀软 / 关 Wireshark / 关 Fiddler 后重试。
数据安全怎么保证?
- PII 字段(邮箱 / 手机 / 付款账号)AES 入库,泄库看到密文
- 密码 bcrypt(cost=12)
- JWT + Redis 黑名单双保险
- 日备 + 异地 S3
- 所有写操作 audit_logs 全量
数据存哪里?会传到你们服务器吗?
不会。清乐云是自部署 SaaS,服务器完全在你自己名下(云主机或机房),数据从来不出你的服务器。我们不接触任何用户数据。
13. 联系我们#
技术咨询 / 商业授权 / 私有定制 / SLA 服务:
© 清乐云 · 官方文档 v2.0 · 最后更新