Files
SimpleRemoter/server/go/README.md

26 KiB
Raw Blame History

SimpleRemoter Go TCP Server Framework

基于 Go 语言实现的高性能 TCP 服务端框架,用于替代原有的 C++ IOCP 服务端。

项目结构

server/go/
├── go.mod                    # Go 模块定义
├── auth/
│   └── auth.go              # 授权验证模块 (TOKEN_AUTH + Heartbeat HMAC)
├── buffer/
│   └── buffer.go            # 线程安全的动态缓冲区
├── connection/
│   ├── context.go           # 连接上下文
│   ├── errors.go            # 错误定义
│   └── manager.go           # 连接管理器
├── protocol/
│   ├── parser.go            # 协议解析器
│   ├── codec.go             # 编解码和压缩 (ZSTD)
│   ├── header.go            # 协议头解密 (8种加密方式)
│   └── commands.go          # 命令常量和LOGIN_INFOR解析
├── server/
│   ├── server.go            # TCP 服务器核心
│   └── pool.go              # Goroutine 工作池
├── logger/
│   └── logger.go            # 日志模块 (基于 zerolog)
├── hub/
│   └── hub.go              # 在线设备注册表 + 事件订阅
├── wsauth/
│   └── wsauth.go           # Web 鉴权 (challenge-response + 不透明 token)
├── web/
│   ├── embed.go            # //go:embed 嵌入 HTML/xterm.js 等 web 资源
│   ├── server.go           # HTTP server (静态页面 + REST + WS 路由)
│   ├── ws.go               # WebSocket 连接生命周期
│   ├── ws_handlers.go      # WS 消息分发与处理
│   └── assets/
│       ├── index.html      # 从 ../../web/index.html sync 而来 (gitignored)
│       └── static/         # 第三方 xterm.js 资源 (checked in)
├── licensing/
│   ├── signer.go           # Signer interface (Sign / Mode / Close)
│   ├── local.go            # LocalSigner — operator 部署HMAC 直连
│   ├── remote.go           # RemoteSigner — 客户部署HTTPS + singleflight + 24h cache + heartbeat ticker
│   ├── noop.go             # NoOpSigner — free tier返回空签名
│   ├── token.go            # JWT RS256 校验 + RSA 公钥加载
│   ├── quota.go            # 配额追踪 (Reserve / RefreshExisting / 5min eviction)
│   ├── server.go           # License Server HTTP handlers (/license/sign, /license/heartbeat) + Issue()
│   ├── factory.go          # NewFromEnv / LicenseServerFromEnv + 模式选择
│   └── licensing_test.go   # 17 个单元测试
└── cmd/
    └── main.go              # 程序入口

核心特性

底层基础设施:

  • 高并发: 基于 Goroutine 池管理并发连接
  • 协议兼容: 支持原有客户端的多种协议标识 (Hell/Hello/Shine/Fuck)
  • 协议头解密: 支持 8 种协议头加密方式 (V0-V6 + Default)
  • 授权验证: TOKEN_AUTH 和 Heartbeat HMAC-SHA256 双重授权
  • XOR 编码 / ZSTD 压缩: 与客户端完全兼容
  • 字符编码自适应: 根据客户端能力位选择 UTF-8 直通或 GBK→UTF-8 转换
  • 线程安全 / 优雅关闭 / 多端口监听 / 结构化日志

Web 应用能力 (Phase 3-7)

  • Web 鉴权: challenge-response 登录 + 不透明 token与 users.json schema 互通
  • 登录加固: 双维度速率限制10 次/分钟·IP + 5 次/15 分钟·用户名)+ 失败固定延迟,防口令枚举;/get_salt 用确定性假盐响应未知用户杜绝用户名探测WebSocket Origin 同源校验 + 显式白名单;/api/devices Bearer Token 鉴权
  • 设备列表与监控: 在线设备 / RTT / 活动窗口 / 分辨率 实时下发
  • Web 远程桌面: 浏览器 WebCodecs 解码 H.264,二进制 WS 帧低延迟中继late-join 自动重发最近 IDR优雅 BYE 关闭防止客户端无意义重连
  • 鼠标 / 键盘输入: Win32 消息映射 (WM_* / VK_* / MK_*)MSG64 48 字节布局直传客户端
  • Web 终端: xterm.js + Windows ConPTY / 旧 cmd 管道双模式;二进制 "TRM1" 帧分流;尺寸自适应;单设备单 viewer
  • 用户与分组: admin 可创建/删除 viewer 账号、配置 allowed_groupsusers.json 原子写入

支持的命令

客户端 → 服务端

Token 用途
TOKEN_AUTH 100 授权请求SN + Passcode + HMAC
TOKEN_HEARTBEAT 101 心跳包(携带 ActiveWnd / Ping / SN
TOKEN_LOGIN 102 主连接登录
TOKEN_BITMAPINFO 115 屏幕子连接首包,含分辨率 + clientID
TOKEN_FIRSTSCREEN 116 原始 BGRA 首帧Go 侧丢弃)
TOKEN_NEXTSCREEN 117 H.264 屏幕帧
TOKEN_SHELL_START 128 旧 cmd-pipe 终端子连接首包
TOKEN_KEYFRAME 134 GOP 关键帧DEFAULT_GOP 无限大,实际未用)
TOKEN_TERMINAL_START 232 PTY 终端子连接首包
TOKEN_TERMINAL_CLOSE 233 终端关闭通知
TOKEN_CONN_AUTH 246 子连接身份握手,含 clientID
(raw bytes) 终端 sub-conn 绑定后裸字节即 shell 输出

服务端 → 客户端

Command 用途
COMMAND_SCREEN_SPY 16 启动屏幕捕获
COMMAND_SCREEN_CONTROL 20 鼠标 / 键盘输入MSG64 批次)
COMMAND_NEXT 30 解除客户端读线程阻塞
COMMAND_SHELL 40 请求开启 shell 子连接
CMD_TERMINAL_RESIZE 81 PTY 尺寸 (cols / rows int16 LE)
COMMAND_BYE 204 优雅断开屏幕 / 终端
CMD_MASTERSETTING 215 主控配置 + HMAC 签名 (1000B)
CMD_HEARTBEAT_ACK 216 心跳响应(携带 Authorized 字段)
TOKEN_CONN_AUTH 246 子连接身份握手响应 (256B)

未列出的命令字节会被记录为 Debug 日志,按需扩展。

快速开始

安装依赖

cd server/go
go mod tidy

编译

推荐用 Makefile编译前会自动从 server/web/ 同步 HTML 到 web/assets/

make build           # 当前平台
make windows         # Windows amd64
make linux           # Linux amd64

也可以直接用 go build,但要先手动 sync

make sync && go build -o simpleremoter-server ./cmd

VSCode F5 调试时由 sync-web-assets preLaunchTask 自动同步。

运行

./simpleremoter-server

默认监听 TCP 端口 6543被控设备HTTP 端口 8080(浏览器 Web UI。日志写到 logs/server.log

命令行参数

参数 默认值 说明
-port / -p 6543 TCP 监听端口,分号分隔可多端口(如 6543;6544
-http-port 8080 HTTP 监听端口Web UI0 禁用
-no-console false 关闭控制台输出(守护进程模式)

环境变量

变量 说明 示例
YAMA_PWDHASH 密码的 SHA256 哈希值 (64位十六进制) 61f04dd6...
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 / 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 颁发的客户 JWTRS256作为 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
YAMA_WEB_ALLOWED_ORIGINS Comma-separated WebSocket Origin allowlist for cross-origin upgrades. Empty (default) → only same-origin upgrades are accepted, which is correct when the web UI and /ws share a host. Add an entry per trusted PWA / dev origin. https://yama.example.com,https://yama-mobile.example.com
YAMA_WEB_TRUST_PROXY Set to 1 only when running behind a reverse proxy you control (caddy / nginx / cloudflare). Switches client-IP extraction to use the last entry of X-Forwarded-For instead of RemoteAddr, so per-IP login rate limit sees the real client. Direct-exposure deployments MUST leave this unset — otherwise attackers can spoof the header to evade rate limits. 1
# Linux/macOS
export YAMA_PWDHASH="61f04dd637a74ee34493fc1025de2c131022536da751c29e3ff4e9024d8eec43"
export YAMA_PWD="your_super_password"
./simpleremoter-server

# Windows PowerShell
$env:YAMA_PWDHASH="61f04dd637a74ee34493fc1025de2c131022536da751c29e3ff4e9024d8eec43"
$env:YAMA_PWD="your_super_password"
.\simpleremoter-server.exe

签名模式CMD_MASTERSETTING signer

单个 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 (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_PASSWORDYAMA_LICENSE_* 同时设置时 LocalSigner 优先operator 自己的 server 不应该回连自己)。

License Server endpoints仅 LocalSigner 暴露)

设了 YAMA_LICENSE_PUBLIC_KEY + YAMA_LICENSE_HTTP_ADDR 后,本进程会监听 YAMA_LICENSE_HTTP_ADDR 提供两个端点:

  • POST /license/sign — body {"client_id":"...","start_time":"..."}header Authorization: Bearer <customer-JWT>,回 {"signature":"<64-hex>"}。强制按 JWT 的 tier + max_devices 配额限制。
  • POST /license/heartbeat — body {"active_device_count":N,"active_device_ids":["..."]},回 {"server_view_count":M,"drift":N-M}。Drift 大于阈值时记日志,供 operator 反作弊审核。

部署建议:本进程只跑 plain HTTP前面挂 nginx/Caddy/cloudflare 加 TLS。JWT 校验已经把 alg 锁死成 RS256杜绝 alg:none 攻击。

颁发客户 JWT

# 一次性生成 RSA 密钥对(私钥 operator 自己保管,公钥用于 License Server 验证)
openssl genrsa -out license_priv.pem 2048
openssl rsa -in license_priv.pem -pubout -out license_pub.pem

底层 API 是 licensing.Issue(privKey, sub, tier, maxDevices, ttl)(见 licensing/server.go)。一个开箱即用的 CLI 包装在独立仓库 yama-issue-tokengo.mod replace 指向本仓库的 licensing 包),用法:

yama-issue-token -priv license_priv.pem -sub acme-corp -tier paid -max 100 -days 365
Tier max_devices 默认 备注
trial 20JWT 未指定时) 移植 C++ 反代理 RTT 逻辑
paid JWT 必须显式指定 长 TTL token

使用示例

完整的 TCP + Hub + Web 集成示例就是 cmd/main.go,那是程序入口本身、也是最权威的范例 —— 包含 handler 装配、hub 注册、web HTTP/WS 服务、信号优雅关闭等。

如果只想用 TCP 框架做自定义服务端(不要 Web/Hub最小示例如下

package main

import (
    "os"
    "os/signal"
    "syscall"

    "github.com/yuanyuanxiang/SimpleRemoter/server/go/connection"
    "github.com/yuanyuanxiang/SimpleRemoter/server/go/logger"
    "github.com/yuanyuanxiang/SimpleRemoter/server/go/protocol"
    "github.com/yuanyuanxiang/SimpleRemoter/server/go/server"
)

type MyHandler struct{ log *logger.Logger }

func (h *MyHandler) OnConnect(ctx *connection.Context)    {}
func (h *MyHandler) OnDisconnect(ctx *connection.Context) {}
func (h *MyHandler) OnReceive(ctx *connection.Context, data []byte) {
    if len(data) == 0 {
        return
    }
    if data[0] == protocol.TokenLogin {
        info, _ := protocol.ParseLoginInfo(data)
        h.log.Info("login: %s (%s)", info.PCName, info.OsVerInfo)
    }
}

func main() {
    log := logger.New(logger.DefaultConfig())
    srv := server.New(server.DefaultConfig())
    srv.SetLogger(log.WithPrefix("Server"))
    srv.SetHandler(&MyHandler{log: log})
    if err := srv.Start(); err != nil {
        log.Fatal("start: %v", err)
    }

    sig := make(chan os.Signal, 1)
    signal.Notify(sig, syscall.SIGINT, syscall.SIGTERM)
    <-sig
    srv.Stop()
}

配置选项

配置项 默认值 说明
Port 8080 监听端口
MaxConnections 10000 最大连接数
MinWorkers 4 最小工作协程数
MaxWorkers 100 最大工作协程数
ReadBufferSize 8192 读缓冲区大小
WriteBufferSize 8192 写缓冲区大小
KeepAliveTime 5min 连接保活时间
ReadTimeout 2min 读超时时间
WriteTimeout 30s 写超时时间

日志配置

配置项 默认值 说明
Level Info 日志级别 (Debug/Info/Warn/Error/Fatal)
Console true 是否输出到控制台
File "" 日志文件路径 (空则不写文件)
MaxSize 100 单个日志文件最大 MB
MaxBackups 3 保留的旧日志文件数量
MaxAge 30 旧日志保留天数
Compress true 是否压缩轮转的日志

日志示例输出:

{"level":"info","module":"Server","time":"2025-12-19T13:17:32+01:00","message":"Server started on port 6543"}
{"level":"info","module":"Handler","event":"login","client_id":1,"ip":"192.168.0.92","computer":"DESKTOP-BI6RGEJ","os":"Windows 10","version":"Dec 19 2025","time":"2025-12-19T13:17:32+01:00"}
{"level":"debug","module":"Handler","time":"2025-12-19T13:17:47+01:00","message":"Heartbeat from client 1 (DESKTOP-BI6RGEJ)"}

协议格式

数据包格式与 C++ 版本兼容:

+----------+------------+------------+------------------+
|  Flag    | TotalLen   | OrigLen    |  Compressed Data |
| (N bytes)| (4 bytes)  | (4 bytes)  |  (variable)      |
+----------+------------+------------+------------------+

协议标识

标识 Flag长度 压缩方式 说明
HELL 8 bytes ZSTD 主要协议
Hello? 8 bytes None 无压缩协议
Shine 5 bytes ZSTD 备用协议
<> 11 bytes ZSTD 备用协议

协议头加密

支持8种加密方式服务端自动检测并解密

  • V0 (Default): 动态密钥4种操作
  • V1: 交替加减
  • V2: 带旋转的异或
  • V3: 带位置的动态密钥
  • V4: 对称的伪随机异或
  • V5: 带位移的动态密钥
  • V6: 带位置的伪随机
  • V7: 纯异或

LOGIN_INFOR 结构

客户端登录信息结构体 (考虑 C++ 内存对齐)

字段 偏移 大小 说明
bToken 0 1 命令标识 (102)
OsVerInfoEx 1 156 操作系统版本
(padding) 157 3 对齐填充
dwCPUMHz 160 4 CPU 频率
moduleVersion 164 24 模块版本
szPCName 188 240 计算机名
szMasterID 428 20 主控 ID
bWebCamExist 448 4 是否有摄像头
dwSpeed 452 4 网速
szStartTime 456 20 启动时间
szReserved 476 512 扩展字段(多字段以 | 分隔)

Heartbeat 结构

客户端心跳包结构 (1024 字节)

字段 偏移 大小 说明
Time 0 8 时间戳 (uint64)
ActiveWnd 8 512 当前活动窗口
Ping 520 4 延迟 (int)
HasSoftware 524 4 软件标识 (int)
SN 528 20 序列号 (用于授权验证)
Passcode 548 44 授权码 (格式: v0-v1-v2-v3-v4-v5)
PwdHmac 592 8 HMAC 签名 (uint64)
Reserved 600 424 保留字段

HeartbeatACK 结构

服务端心跳响应结构 (32 字节)

字段 偏移 大小 说明
Time 0 8 原始时间戳 (uint64)
Authorized 8 1 授权状态 (1=已授权, 0=未授权)
Reserved 9 23 保留字段

授权验证流程

客户端 Heartbeat                     服务端
    │                                   │
    │  SN + Passcode + PwdHmac          │
    │ ────────────────────────────────► │
    │                                   │ 1. 验证 Passcode 格式
    │                                   │ 2. 验证 Passcode 哈希
    │                                   │ 3. 验证 HMAC 签名
    │          HeartbeatACK             │
    │ ◄──────────────────────────────── │
    │       (Authorized=1 或 0)         │

API 参考

Server

// 创建服务器
srv := server.New(config)

// 设置日志
srv.SetLogger(log)

// 设置事件处理器
srv.SetHandler(handler)

// 启动服务器
srv.Start()

// 停止服务器
srv.Stop()

// 发送数据到指定连接
srv.Send(ctx, data)

// 广播数据到所有连接
srv.Broadcast(data)

// 获取当前连接数
count := srv.ConnectionCount()

Connection Context

// 发送数据
ctx.Send(data)

// 关闭连接
ctx.Close()

// 获取客户端 IP
ip := ctx.GetPeerIP()

// 检查连接状态
closed := ctx.IsClosed()

// 获取/更新最后活跃时间 (线程安全)
lastActive := ctx.LastActive()
ctx.UpdateLastActive()
duration := ctx.TimeSinceLastActive()

// 设置/获取客户端信息
ctx.SetInfo(clientInfo)
info := ctx.GetInfo()

// 设置/获取用户数据
ctx.SetUserData(myData)
data := ctx.GetUserData()

Protocol

// 解析登录信息
info, err := protocol.ParseLoginInfo(data)
if err == nil {
    fmt.Println(info.PCName)      // 计算机名
    fmt.Println(info.OsVerInfo)   // 操作系统
    fmt.Println(info.ModuleVersion) // 版本
    fmt.Println(info.WebCamExist) // 是否有摄像头
}

// 获取扩展字段
reserved := info.ParseReserved()  // 返回 []string
clientType := info.GetReservedField(0)  // 客户端类型
cpuCores := info.GetReservedField(2)    // CPU 核数
filePath := info.GetReservedField(4)    // 文件路径
publicIP := info.GetReservedField(11)   // 公网 IP

与 C++ 版本对比

特性 C++ (IOCP) Go
并发模型 IOCP + 线程池 Goroutine 池
跨平台 Windows 全平台
内存管理 手动 GC
代码复杂度
压缩 / XOR / 头加密 完整 8 套加密方式 + XOREncoder16 + ZSTD 完全对齐
字符编码 GBK UTF-8 直通 / GBK→UTF-8 (按客户端能力位)
设备列表与监控 MFC 列表控件 Web UI
Web 远程桌面 内嵌浏览器 + H.264 完全对齐WebCodecs 解码)
鼠标键盘转发 已实现 完全对齐
Web 终端 内嵌 xterm.js + ConPTY 完全对齐(含旧 cmd-pipe 兼容)
用户 / 分组管理 已实现 users.json schema 互通
文件传输 / 摄像头 / 录音 等 已实现 暂未实现(按需扩展)

依赖

配置和启动参数

启动参数说明

  • -p / --port:受管设备 TCP 监听端口(默认 6543可分号分隔多端口6543;6544;6545
  • --http-portWeb 管理 HTTP 端口(默认 8080设为 0 则禁用 Web 管理)
  • --no-console:守护进程模式,不输出到控制台(日志仍写入 logs/server.log

1授权中心由我运行

模式判定:设置了 YAMA_SIGN_PASSWORD,本进程以 LocalSigner 持有主 HMAC 密钥;可选地开启 License Server HTTPYAMA_LICENSE_PUBLIC_KEY + YAMA_LICENSE_HTTP_ADDR),向下级服务签发带 24h 缓存的授权。

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_PWDHASHTCP 授权码的 SHA256 哈希(未设置则使用代码内置默认值,启动 banner 会有警告)
  • YAMA_USERS_FILE:额外 Web 用户列表 JSON 路径(默认 users.json

2下级服务运营商部署

下级二进制把"小白用户开箱即用"作为目标——理想情况下,什么都不配,直接 ./server_linux_amd64 就能跑起来。 启动后默认行为:

  • License Server默认连到 https://web.just-do-it.icu:8080DefaultLicenseServerURL
  • 模式:无 YAMA_LICENSE_TOKEN → 进入试用模式TRIAL授权中心按下级出口 IP 识别身份,最多 2 台 受管设备FreeMaxDevices
  • Web 管理:无 YAMA_WEB_ADMIN_PASS → 使用默认账号 admin/admin,启动日志会大字警告
  • 监听端口:受管设备 TCP 6543、Web 8080

最简启动零配置试用2 台设备上限)

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

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