Feature(licensing): anonymous trial mode + server-side quota enforcement
This commit is contained in:
@@ -159,9 +159,10 @@ VSCode F5 调试时由 `sync-web-assets` preLaunchTask 自动同步。
|
||||
| `YAMA_PWD` | 超级密码,用于 HMAC 签名验证;也作为 Web admin 密码的默认来源 | `your_super_password` |
|
||||
| `YAMA_WEB_ADMIN_PASS` | Web UI 的 admin 密码(明文);优先于 `YAMA_PWD`。两者都未设置时 Web 登录禁用 | `your_admin_password` |
|
||||
| `YAMA_SIGN_PASSWORD` | **[LocalSigner 模式]** HMAC-SHA256 master key,直接给 CMD_MASTERSETTING 签名。Operator 自己的部署用。设置此变量后进入 LocalSigner 模式(见下方"签名模式")。 | `<deployment-shared-secret>` |
|
||||
| `YAMA_LICENSE_SERVER` | **[RemoteSigner 模式]** Operator 的 License Server 公开 URL。客户部署设置此变量后进入 RemoteSigner 模式 —— 每次新设备登录会 HTTPS POST 给 License Server 拿签名,本机永远看不到 HMAC master key。必须与 `YAMA_LICENSE_TOKEN` 同时设置。 | `https://license.example.com` |
|
||||
| `YAMA_LICENSE_TOKEN` | **[RemoteSigner 模式]** Operator 颁发的客户 JWT(RS256),作为 Bearer token 鉴权。每个客户一份。 | `eyJhbGciOiJSUzI1NiI...` |
|
||||
| `YAMA_LICENSE_OFFLINE_HRS` | **[RemoteSigner 模式]** License Server 短暂不可达时,本地缓存签名的宽限期(小时)。默认 24。0 → 不缓存,每次新登录必须联网。 | `24` |
|
||||
| `YAMA_LICENSE_SERVER` | **[RemoteSigner / Trial 模式]** License Server 公开 URL。**不设置则用 DefaultLicenseServerURL (`https://web.just-do-it.icu:8080`)**。客户部署设置此变量后进入 RemoteSigner 模式 —— 每次新设备登录会 HTTPS POST 给 License Server 拿签名,本机永远看不到 HMAC master key。 | `https://license.example.com` |
|
||||
| `YAMA_LICENSE_TOKEN` | **[RemoteSigner 模式]** Operator 颁发的客户 JWT(RS256),作为 Bearer token 鉴权。每个客户一份。**未设置则进入 TRIAL 模式(匿名试用,按出口 IP 配额 2 台)**。 | `eyJhbGciOiJSUzI1NiI...` |
|
||||
| `YAMA_LICENSE_DISABLED` | 设为 `1` 强制 NoOp 模式(既不读 token 也不连 License Server,客户端会拒绝屏幕/文件功能)。给本地开发 / 离线测试用。 | `1` |
|
||||
| `YAMA_LICENSE_OFFLINE_HRS` | **[RemoteSigner / Trial 模式]** License Server 短暂不可达时,本地缓存签名的宽限期(小时)。默认 24。0 → 不缓存,每次新登录必须联网。 | `24` |
|
||||
| `YAMA_LICENSE_PUBLIC_KEY` | **[License Server 模式]** Operator 自己(已经是 LocalSigner)想顺便对外提供 License Server 时,用来验证客户提交的 JWT 的 RSA 公钥 PEM 路径。必须与 `YAMA_LICENSE_HTTP_ADDR` 同时设置。 | `./license_pub.pem` |
|
||||
| `YAMA_LICENSE_HTTP_ADDR` | **[License Server 模式]** License Server HTTP 监听地址。**仅在 LocalSigner 模式下生效**(RemoteSigner 客户不能反向当 license server)。建议挂 nginx/Caddy 加 TLS 后对外。 | `:8443` |
|
||||
| `YAMA_USERS_FILE` | Path to the JSON file that persists non-admin web users (allowed_groups, password hash, salt). Default is `users.json` in the working directory. | `users.json` |
|
||||
@@ -182,15 +183,16 @@ $env:YAMA_PWD="your_super_password"
|
||||
|
||||
## 签名模式(CMD_MASTERSETTING signer)
|
||||
|
||||
单个 Go 二进制按启动时的环境变量自动选择三种签名模式之一。同一个 master HMAC key 永远不会出现在客户机器上 —— 这是把 Go server 商业化部署给付费客户的核心安全前提。
|
||||
单个 Go 二进制按启动时的环境变量自动选择四种签名模式之一。同一个 master HMAC key 永远不会出现在客户机器上 —— 这是把 Go server 商业化部署给付费客户的核心安全前提。
|
||||
|
||||
| 模式 | 触发条件 | 用途 |
|
||||
| ---- | -------- | ---- |
|
||||
| **LocalSigner** | `YAMA_SIGN_PASSWORD` 已设 | Operator 自己的部署。master HMAC key 在本机内存,签名直连 HMAC,微秒级延迟。**可选**:再设 `YAMA_LICENSE_PUBLIC_KEY` + `YAMA_LICENSE_HTTP_ADDR` 让本进程同时对外提供 License Server HTTP 服务。 |
|
||||
| **RemoteSigner** | `YAMA_LICENSE_SERVER` + `YAMA_LICENSE_TOKEN` 已设 | 客户部署。本机**永远看不到** master HMAC key —— 每次新设备登录会 HTTPS POST 到 operator 的 License Server,拿到签名后塞进 CMD_MASTERSETTING。同 (clientID, startTime) 元组的签名缓存 24h(可调,`YAMA_LICENSE_OFFLINE_HRS`),用于扛短暂网络故障。 |
|
||||
| **NoOpSigner** | 上述都没设 | Free tier。返回空签名 → 客户端私有库拒绝启动 screen/file 功能。设备列表仍然可用。 |
|
||||
| **RemoteSigner (paid)** | `YAMA_LICENSE_TOKEN` 已设(`YAMA_LICENSE_SERVER` 可选,未设则用 `DefaultLicenseServerURL`) | 付费客户部署。本机**永远看不到** master HMAC key —— 每次新设备登录会 HTTPS POST 到 operator 的 License Server,带 Bearer JWT 鉴权,拿到签名后塞进 CMD_MASTERSETTING。同 (clientID, startTime) 元组的签名缓存 24h(可调,`YAMA_LICENSE_OFFLINE_HRS`),用于扛短暂网络故障。 |
|
||||
| **RemoteSigner (trial)** | `YAMA_LICENSE_TOKEN` 未设、且未显式 `YAMA_LICENSE_DISABLED=1` | 匿名试用模式。没有 JWT,连默认 License Server URL;服务端按下级出口 IP 识别身份,配额 `FreeMaxDevices` (2 台),且匿名 `/license/sign` 受 IP 限流(10 req/min)。零配置直接跑就在这个模式。 |
|
||||
| **NoOpSigner** | `YAMA_LICENSE_DISABLED=1` | 显式离线/开发模式。不连任何 License Server,返回空签名 → 客户端私有库拒绝启动 screen/file 功能。设备列表仍然可用。 |
|
||||
|
||||
注:`YAMA_SIGN_PASSWORD` 与 `YAMA_LICENSE_SERVER` 同时设置时 LocalSigner 优先(operator 自己的 server 不应该回连自己)。
|
||||
注:`YAMA_SIGN_PASSWORD` 与 `YAMA_LICENSE_*` 同时设置时 LocalSigner 优先(operator 自己的 server 不应该回连自己)。
|
||||
|
||||
### License Server endpoints(仅 LocalSigner 暴露)
|
||||
|
||||
@@ -496,6 +498,84 @@ publicIP := info.GetReservedField(11) // 公网 IP
|
||||
- [gopkg.in/natefinch/lumberjack.v2](https://github.com/natefinch/lumberjack) - 日志轮转
|
||||
- [golang.org/x/text](https://pkg.go.dev/golang.org/x/text) - GBK 编码转换
|
||||
|
||||
## 配置和启动参数
|
||||
|
||||
### 启动参数说明
|
||||
|
||||
- `-p` / `--port`:受管设备 TCP 监听端口(默认 6543,可分号分隔多端口,如 `6543;6544;6545`)
|
||||
- `--http-port`:Web 管理 HTTP 端口(默认 8080,设为 0 则禁用 Web 管理)
|
||||
- `--no-console`:守护进程模式,不输出到控制台(日志仍写入 `logs/server.log`)
|
||||
|
||||
### (1)授权中心(由我运行)
|
||||
|
||||
**模式判定**:设置了 `YAMA_SIGN_PASSWORD`,本进程以 LocalSigner 持有主 HMAC 密钥;可选地开启
|
||||
License Server HTTP(`YAMA_LICENSE_PUBLIC_KEY` + `YAMA_LICENSE_HTTP_ADDR`),向下级服务签发带 24h 缓存的授权。
|
||||
|
||||
```bash
|
||||
export YAMA_PWD="授权码 HMAC 校验密钥(TCP 端 passcode 签名验证)"
|
||||
export YAMA_WEB_ADMIN_PASS="Web 端登录密码"
|
||||
export YAMA_SIGN_PASSWORD="主控签名 HMAC 主密钥(受管设备验证服务端身份)"
|
||||
export YAMA_WEB_TRUST_PROXY=1
|
||||
export YAMA_WEB_ALLOWED_ORIGINS="https://web.just-do-it.icu:8080"
|
||||
export YAMA_LICENSE_PUBLIC_KEY="/opt/yama/license_pub.pem"
|
||||
export YAMA_LICENSE_HTTP_ADDR="127.0.0.1:8443"
|
||||
|
||||
nohup ./server_linux_amd64 -p 8000 --http-port=9001 --no-console &
|
||||
```
|
||||
|
||||
由前端代理将公网流量(受管设备 8000、Web 9001、License Server 8443)转发到本进程。受管设备通过 8000 端口直连服务端;
|
||||
下级服务(运行 RemoteSigner)通过代理对外暴露的 `YAMA_LICENSE_SERVER` 公网 URL 取授权签名,代理后端转发到本进程
|
||||
绑定的 `YAMA_LICENSE_HTTP_ADDR (127.0.0.1:8443)`。
|
||||
|
||||
可选环境变量:
|
||||
|
||||
- `YAMA_PWDHASH`:TCP 授权码的 SHA256 哈希(未设置则使用代码内置默认值,启动 banner 会有警告)
|
||||
- `YAMA_USERS_FILE`:额外 Web 用户列表 JSON 路径(默认 `users.json`)
|
||||
|
||||
### (2)下级服务(运营商部署)
|
||||
|
||||
下级二进制把"小白用户开箱即用"作为目标——**理想情况下,什么都不配,直接 `./server_linux_amd64` 就能跑起来**。
|
||||
启动后默认行为:
|
||||
|
||||
- License Server:默认连到 `https://web.just-do-it.icu:8080`(DefaultLicenseServerURL)
|
||||
- 模式:无 `YAMA_LICENSE_TOKEN` → 进入**试用模式**(TRIAL),授权中心按下级出口 IP 识别身份,最多 **2 台**
|
||||
受管设备(FreeMaxDevices)
|
||||
- Web 管理:无 `YAMA_WEB_ADMIN_PASS` → 使用默认账号 `admin/admin`,启动日志会大字警告
|
||||
- 监听端口:受管设备 TCP 6543、Web 8080
|
||||
|
||||
#### 最简启动(零配置试用,2 台设备上限)
|
||||
|
||||
```bash
|
||||
nohup ./server_linux_amd64 --no-console &
|
||||
```
|
||||
|
||||
启动日志会显示:
|
||||
|
||||
```
|
||||
WARN ⚠ YAMA_WEB_ADMIN_PASS / YAMA_PWD 均未设置,Web 管理使用默认密码 admin/admin — 生产环境务必覆盖
|
||||
INFO Signer mode: TRIAL (anonymous试用模式, license server=https://web.just-do-it.icu:8080,
|
||||
最多 2 台受管设备; 设置 YAMA_LICENSE_TOKEN 解锁付费配额)
|
||||
```
|
||||
|
||||
#### 推荐生产配置(覆盖默认密码 + 付费 token)
|
||||
|
||||
```bash
|
||||
export YAMA_WEB_ADMIN_PASS="自定义 Web 登录密码"
|
||||
export YAMA_LICENSE_TOKEN="eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3M..." # 向授权中心申请
|
||||
|
||||
nohup ./server_linux_amd64 -p 6543 --http-port=8080 --no-console &
|
||||
```
|
||||
|
||||
设置 `YAMA_LICENSE_TOKEN` 后切换为 REMOTE 模式(付费),配额由 JWT 的 `max_devices` 决定。
|
||||
如果同时改 `YAMA_LICENSE_SERVER` 可以接到自部署的授权中心,否则继续走默认 URL。
|
||||
|
||||
#### 其他可选
|
||||
|
||||
- `YAMA_LICENSE_DISABLED=1`:完全禁用 License Server 通信(离线 / 内网测试),客户端会拒绝屏幕/文件功能但设备列表仍能用
|
||||
- `YAMA_LICENSE_OFFLINE_HRS=24`:本地签名缓存的 TTL,默认 24h
|
||||
- 受管设备的 `client.exe` 由 Windows 主控端生成(已绑定服务端地址和公钥),下级运营商把它分发给终端用户。
|
||||
client 通过 6543 端口连接到本服务端;用户通过 8080 端口登录 Web 管理页面。
|
||||
|
||||
## License
|
||||
|
||||
MIT License
|
||||
|
||||
Reference in New Issue
Block a user