633 lines
34 KiB
Markdown
633 lines
34 KiB
Markdown
# RustDesk API
|
||
|
||
> **原始仓库**:https://github.com/lejianwen/rustdesk-api.git
|
||
> **克隆时间**:2026-09-16
|
||
> **镜像仓库**:https://gitea7.yangjieshao.work/rustdesk/rustdesk-api.git
|
||
|
||
[English Doc](README_EN.md)
|
||
|
||
本项目使用 Go 实现了 RustDesk 的 API,并包含了 Web Admin 和 Web 客户端。
|
||
|
||
|
||
---
|
||
|
||
# 本仓库修改
|
||
|
||
## 编译与打包步骤
|
||
|
||
> 完整的服务器编译与镜像打包步骤见 [lejianwen/rustdesk-server README](https://github.com/lejianwen/rustdesk-server)。
|
||
> 本节仅列出 API 侧(apimain + admin 前端 + 完整镜像)的编译步骤。
|
||
|
||
### 1. 编译 API 二进制(apimain)
|
||
|
||
```sh
|
||
# 启动 Go 编译容器
|
||
docker run -d --name gobuild --network host \
|
||
-v /root/rustdesk/build/apibuild:/srv -w /srv golang:1.23-alpine sleep infinity
|
||
|
||
# 安装 git + gcc(CGO 静态编译需要)
|
||
docker exec gobuild apk add --no-cache git gcc musl-dev
|
||
|
||
# 设置 Go 代理
|
||
docker exec gobuild go env -w GOPROXY=https://goproxy.cn,direct
|
||
|
||
# 编译(CGO 静态编译)
|
||
docker exec gobuild env CGO_ENABLED=1 GOOS=linux GOARCH=amd64 CC=gcc \
|
||
go build -ldflags '-s -w' -o ./amd64/release/apimain ./cmd/apimain.go
|
||
```
|
||
|
||
> 注意:仓库快照的 `go.mod` 与 `go.sum` 可能不同步。若编译报 `missing go.sum entry`,
|
||
> 把仓库复制到临时目录执行 `go mod tidy` 后再编译,不动原仓库。
|
||
|
||
### 2. 构建 admin 前端
|
||
|
||
```sh
|
||
git clone --depth 1 -b master https://gh-proxy.com/https://github.com/lejianwen/rustdesk-api-web
|
||
docker run --rm -v $PWD:/srv -w /srv node:20-alpine sh -c \
|
||
"npm config set registry https://registry.npmmirror.com && npm install && npm run build"
|
||
cp -a rustdesk-api-web/dist/. /root/rustdesk/build/apibuild/resources/admin/
|
||
```
|
||
|
||
> Go 二进制从磁盘读 `resources` 目录(不内嵌),所以无需重编 Go,重打镜像层即可。
|
||
|
||
### 3. 打完整镜像
|
||
|
||
```sh
|
||
# 修改 Dockerfile_full_s6 首行,指向本地 s6 基础镜像
|
||
cp /root/rustdesk/build/apibuild/Dockerfile_full_s6 /tmp/Dockerfile_full_s6
|
||
sed -i 's|FROM rustdesk/rustdesk-server-s6:latest AS server|FROM rustdesk-server-s6:1.1.17-forapi AS server|' /tmp/Dockerfile_full_s6
|
||
|
||
# 构建(context 必须含 amd64/release)
|
||
docker build -f /tmp/Dockerfile_full_s6 \
|
||
--build-arg BUILDARCH=amd64 \
|
||
-t yangjieshao/rustdesk-api:full-s6-amd64 \
|
||
/root/rustdesk/build/apibuild
|
||
```
|
||
|
||
### 4. 验证运行
|
||
|
||
```sh
|
||
docker run -d --name rustdesk-test -p 21114-21119:21114-21119 \
|
||
-p 21116:21116/udp \
|
||
-e RELAY=<IP[:21117]> \
|
||
-v <data>:/data -v <appdata>:/app/data \
|
||
yangjieshao/rustdesk-api:full-s6-amd64
|
||
|
||
curl -s http://127.0.0.1:21114/_admin/ -o /dev/null -w '%{http_code}\n'
|
||
```
|
||
|
||
|
||
## 感谢你的支持!如果这个项目对你有帮助,请点个⭐️鼓励一下,谢谢!
|
||
|
||
[lejianwen/rustdesk-server]: https://github.com/lejianwen/rustdesk-server
|
||
|
||
---
|
||
|
||
# 自连拦截(A 远程连 A)API 侧改动
|
||
|
||
> 日期:2026-09-06
|
||
> 关联文档:[lejianwen/rustdesk-server README](https://github.com/lejianwen/rustdesk-server)
|
||
> 说明:以下为自连拦截方案中涉及本仓库(rustdesk-api,Go)的代码改动,服务端(hbbs)改动见 [lejianwen/rustdesk-server README](https://github.com/lejianwen/rustdesk-server)。
|
||
|
||
## 改动清单
|
||
|
||
| 文件 | 改动 |
|
||
|---|---|
|
||
| `service/user.go` | 新增 `GetDeviceIdByToken(token)`:查 UserToken(校验 ExpiredAt)返回 DeviceId |
|
||
| `http/controller/api/internal.go` | 新增内部接口 `GET /api/internal/token-device?token=`:仅回环 IP + `X-Secret` 头必须等于 JWT 密钥,否则 403;查不到 404 |
|
||
| `http/router/api.go` | 注册路由(置于 RustAuth 中间件之前) |
|
||
| `lib/jwt/jwt.go` | GenerateToken 增加 jti(`ID: uuid.NewString()`),每次登录 token 唯一 |
|
||
|
||
## 运行配置
|
||
|
||
- API 内部地址可用 `RUSTDESK_API_INTERNAL_URL` 覆盖,默认 `http://127.0.0.1:21114`
|
||
- hbbs 与 API 同容器时,`RUSTDESK_API_JWT_KEY` 双方共享(hbbs 的 jwt::SECRET 即 API 的 jwt.key)
|
||
- ⚠️ **部署必设 `RUSTDESK_API_JWT_KEY`**(任意字符串)。未设置时 hbbs 的 JWT 密钥为空,
|
||
token 校验和自连拦截**整体静默关闭**(fail-open 设计)。修改该值后客户端需退出重新登录。
|
||
|
||
---
|
||
|
||
# RustDesk 服务器合并 1.1.17 与 Docker 镜像构建记录
|
||
|
||
> 日期:2026-09-05
|
||
> 目标:将官方 `rustdesk/rustdesk-server` 1.1.17 的更新合并到 `lejianwen/rustdesk-server`(forapi 分支,带账号 API 支持),并打包出可直接使用的完整 Docker 镜像。
|
||
|
||
## 1. 背景与仓库关系
|
||
|
||
| 仓库 | 说明 | 版本状态 |
|
||
|---|---|---|
|
||
| `/root/rustdesk/rustdesk/rustdesk-server` | 官方原版(只读,全程未改动) | 1.1.17(2026-08) |
|
||
| `/root/rustdesk/lejianwen/rustdesk-server` | 第三方修改版,`forapi` 分支持账号登录/API/JWT | 原基于 1.1.14(2025-09),本次合并到 1.1.17 |
|
||
| `/root/rustdesk/lejianwen/rustdesk-api` | Go 编写的 API 服务,`Dockerfile_full_s6` 打完整镜像 | 原样使用 |
|
||
|
||
两个 rustdesk-server 仓库在官方 1.1.14(merge-base `c650217`)处分叉:
|
||
官方之后有 43 个提交(1.1.15 → 1.1.17),lejianwen 有 38 个自己的提交。
|
||
|
||
**官方 1.1.15~1.1.17 的主要改动**(合并的重点):
|
||
|
||
- 安全:禁用 UDP 打洞反射/放大路径(`PunchHoleRequest`/`PunchHoleSent`/`LocalAddr` 只允许走 TCP/WS);中继 X-Real-IP 头欺骗风险注释;升级 mio 0.8.11、protobuf 3.7.2
|
||
- 功能:`-b/--bind` 绑定指定 IP;控制台监听独立绑到 127.0.0.1;`punch-requests(pr)` 连接日志控制台命令
|
||
- 修复:在线状态 `i32` 溢出(运行 24.9~49.7 天后误报在线);中继限速默认值 4Mb/s → 32Mb/s
|
||
- 依赖:`hbb_common` 子模块多次推进(最终 `69cea8d`)、新增 `flate2`
|
||
|
||
## 2. 合并过程与冲突处理
|
||
|
||
执行 `git merge upstream/master`(在 lejianwen 仓库本地添加 `upstream` 指向官方目录)。
|
||
|
||
| 冲突文件 | 处理方式 |
|
||
|---|---|
|
||
| `src/rendezvous_server.rs` | 保留 fork 的 JWT/必须登录/KeyExchange/加密 Sink/API 特性,叠加上游全部修复(bind、console listener、UDP 禁用、i64、PUNCH_REQS、`punch-requests` 命令等)。共 4 处冲突块手动合并 |
|
||
| `src/main.rs` | 双方参数合并:上游的 `--bind` + DEPRECATED 标注,保留 fork 的 `--must-login` |
|
||
| `libs/hbb_common`(子模块) | 从 fork 的旧提交直接指到官方 1.1.17 用的 `69cea8d`。先确认 fork 用到的 `tcp::Encrypt` 接口在新版仍存在 |
|
||
| `Cargo.toml` / `Cargo.lock` | git 自动合并成功(1.1.17 + flate2 + 保留 jsonwebtoken/headers);lock 文件 cargo 构建后未再变动,说明自动合并结果一致 |
|
||
| `README*.md`、`.github/workflows/*`、`docker-compose.yml`、`docker/Dockerfile` | 取 fork 版本(文档是 API 版、CI 是 lejianwen 自己的发布流程) |
|
||
|
||
**合并中发现的注意点**:
|
||
|
||
- 上游把 `handle_udp` 里的三个打洞消息改成"故意不支持",fork 的 `handle_udp_punch_hole_request` 变成死代码(仅编译警告),保留不影响行为;webclient 打洞走 TCP/WS 路径不受影响
|
||
- fork 侧 `check_cmd` 帮助文本比上游多一行 `must-login`,合并 `punch-requests` 时要同步把 format! 占位符从 7 个加到 8 个,**否则编译报 `argument never used`**(本次实际踩过)
|
||
- 上游的 `peers_online_state` 是内联代码,fork 抽成了 helper(`handle_online_request` 复用),合并时保留 helper 并把 `as i32` 改 `as i64`
|
||
|
||
## 3. 构建环境问题与解决(按时间顺序)
|
||
|
||
本机只有 `docker` 和 `gcc`,没有 rust/go 工具链,全部编译在容器中进行。
|
||
|
||
### 3.1 容器内访问 GitHub 失败
|
||
|
||
**现象**:容器内 `cargo build` 拉取 git 依赖(`confy` 等 3 个来自 github.com)时 `SSL routines::unexpected eof` / 连接超时,重试 10 次仍失败;直连 `git ls-remote github.com` 间歇性可用。
|
||
**原因**:到 GitHub 的连接被间歇性重置(典型网络环境问题),宿主机偶尔能通但容器内不稳定。
|
||
**解决**:
|
||
- 测试可用的加速代理:`gh-proxy.com`、`ghproxy.net`(`ghfast.top` 返回 403)
|
||
- 容器内配置系统级改写(注意写 `/etc/gitconfig`,`--global` 在某些 exec 环境不可靠):
|
||
|
||
```sh
|
||
git config --system url.'https://gh-proxy.com/https://github.com/'.insteadOf 'https://github.com/'
|
||
```
|
||
|
||
- s6-overlay 等构建期从 GitHub 下载的文件改为**宿主机预下载**(走代理)后 `COPY` 进镜像,见 3.6
|
||
|
||
### 3.2 Alpine apk 源问题
|
||
|
||
**现象**:`rust:alpine`(Alpine 3.24.1)内 `apk add` 卡住 10 分钟无进展;换清华源后 `HTTP 403: Forbidden`。
|
||
**原因**:官方 CDN 在当前网络环境慢;清华源对 v3.24 索引 403。
|
||
**解决**:使用阿里云源(与镜像版本匹配的 v3.24):
|
||
|
||
```sh
|
||
printf 'https://mirrors.aliyun.com/alpine/v3.24/main\nhttps://mirrors.aliyun.com/alpine/v3.24/community\n' > /etc/apk/repositories
|
||
```
|
||
|
||
注意先确认镜像的 Alpine 版本(`cat /etc/alpine-release`),不要照搬别的版本号。
|
||
|
||
### 3.3 挂载 CARGO_HOME 盖住了 Rust 工具链
|
||
|
||
**现象**:容器内 `cargo: not found`。
|
||
**原因**:把宿主目录挂载到 `/usr/local/cargo`(想持久化缓存),而 `rust:alpine` 的 cargo/rustc 就装在这个路径里,挂载把它们全遮住了。
|
||
**解决**:不挂载该路径,cargo 配置直接写容器内 `/usr/local/cargo/config.toml`;既然用持久化容器(`docker run -d ... sleep infinity` + `docker exec`),缓存本来就不会丢。
|
||
|
||
### 3.4 cargo 的 git-fetch-with-cli 需要 git 二进制
|
||
|
||
**现象**:`could not execute process 'git fetch ...' (never executed) - No such file or directory`。
|
||
**原因**:`rust:alpine` 不带 git,而 config 里设了 `git-fetch-with-cli = true`。
|
||
**解决**:`apk add git`。(该模式值得保留:CLI git 才能吃 `insteadOf` 改写,cargo 内置 libgit2 不认。)
|
||
|
||
### 3.5 Go 构建:go.sum 缺条目
|
||
|
||
**现象**:`missing go.sum entry for module providing package github.com/spf13/cobra`。
|
||
**原因**:仓库快照的 `go.mod` 与 `go.sum` 不同步(上游代码在 go.mod 里加了 cobra 但没提交 go.sum 条目)。
|
||
**解决**:把仓库**复制到临时目录**(不动原仓库)执行 `go mod tidy` 后再 `go build`。CGO 静态编译命令:
|
||
|
||
```sh
|
||
CGO_ENABLED=1 GOOS=linux GOARCH=amd64 CC=gcc CGO_LDFLAGS='-static' \
|
||
go build -ldflags '-s -w' -o ./amd64/release/apimain ./cmd/apimain.go
|
||
cp -ar resources docs conf amd64/release/ && mkdir -p amd64/release/{data,runtime}
|
||
```
|
||
|
||
(alpine 容器里 gcc 本身就是 musl-gcc,等价于官方 CI 的 musl-tools 静态构建;产物 `file` 确认 `statically linked`。)
|
||
|
||
### 3.6 docker build 阶段无法访问 GitHub(s6-overlay)
|
||
|
||
**现象**:官方 `docker/Dockerfile` 用 `ADD https://github.com/just-containers/s6-overlay/releases/download/...` 构建期联网下载。
|
||
**解决**:宿主机预下载(`curl -L https://gh-proxy.com/https://github.com/...`),复制官方 Dockerfile 后把两条 `ADD` 改成本地 `COPY`(不改动官方仓库)。下载物:
|
||
- `s6-overlay-noarch.tar.xz`
|
||
- `s6-overlay-x86_64.tar.xz`
|
||
- 版本 v3.2.0.0(与 Dockerfile 内 `S6_OVERLAY_VERSION` 一致)
|
||
|
||
### 3.7 没有 buildx,无法用 --build-context 覆盖 FROM
|
||
|
||
**现象**:本机 docker 26.1.4 无 buildx 插件,`docker build --build-context` 不可用。
|
||
**解决**:复制 `Dockerfile_full_s6` 到构建目录,sed 把首行 `FROM rustdesk/rustdesk-server-s6:latest AS server` 改为本地基础镜像名,构建时 `-f` 指向副本、context 指向含 `amd64/release` 的目录。
|
||
|
||
### 3.8 admin 面板 404:resources/admin 不在仓库里
|
||
|
||
**现象**:镜像跑起来后 `/_admin` 返回 404,release 目录里没有 `admin` 静态文件。
|
||
**原因**:admin 前端来自独立仓库 `lejianwen/rustdesk-api-web`,官方 CI 先 checkout 该仓库、`npm run build` 后把 `dist/*` 拷进 `resources/admin/`,这一步在本地打包时缺失。
|
||
**解决**:
|
||
|
||
```sh
|
||
git clone --depth 1 -b master https://gh-proxy.com/https://github.com/lejianwen/rustdesk-api-web
|
||
docker run --rm -v $PWD:/srv -w /srv node:20-alpine sh -c \
|
||
"npm config set registry https://registry.npmmirror.com && npm install && npm run build"
|
||
cp -a rustdesk-api-web/dist/. <api-release>/resources/admin/
|
||
```
|
||
|
||
Go 二进制从磁盘读 `resources` 目录(不内嵌),所以**无需重编 Go**,重打镜像层即可。
|
||
|
||
### 3.9 杂项
|
||
|
||
- **pkill 自杀**:`pkill -f cargo` 会匹配到承载它的 `sh -c "... pkill -f cargo ..."` 自身,返回 143。用 `pkill -f '[c]argo'` 括号模式规避
|
||
- **管道吞退出码**:`cargo build | tail` 拿到的是 tail 的退出码;busybox ash 不支持 bash 的 `PIPESTATUS`。判断成功与否要看日志里的 `Finished`/`error` 行,或不用管道
|
||
- **镜像标签冲突**:为避免与作者发布的 `lejianwen/rustdesk-api:full-s6-amd64` 撞名,最终镜像按需求改为 `yangjieshao/rustdesk-api:full-s6-amd64`(仅本地,未推送)
|
||
|
||
## 4. 产物与验证结果
|
||
|
||
### 4.1 镜像
|
||
|
||
| 镜像 | 说明 |
|
||
|---|---|
|
||
| `yangjieshao/rustdesk-api:full-s6-amd64` | 最终完整镜像(hbbs + hbbr + rustdesk-utils + apimain + admin 前端,s6 托管) |
|
||
| `rustdesk-server-s6:1.1.17-forapi` | 本地自建的 s6 基础镜像(对应官方 `rustdesk/rustdesk-server-s6`,内含合并后的 1.1.17 二进制,musl 静态链接) |
|
||
|
||
服务器二进制:`hbbs`/`hbbr`/`rustdesk-utils`,`file` 确认 `ELF x86-64 static-pie linked`。
|
||
|
||
### 4.2 实测结论
|
||
|
||
- 21114(API)/21115(NAT)/21116(tcp+udp hbbs)/21117(hbbr)/21118(ws)/21119(ws relay) 全部监听
|
||
- `POST /api/login` 返回业务校验 JSON(接口正常)
|
||
- `/_admin/` 返回 200(admin 面板正常)
|
||
- s6 healthcheck:3 个服务(hbbs、hbbr、api)全部 up
|
||
- `/data` 下正确生成 `id_ed25519(.pub)` 与 `db_v2.sqlite3`
|
||
- 日志出现 `LIMIT_SPEED: 32Mb/s`、`Listening on websocket :21119`,确认 1.1.17 代码与 fork 的 relay WS 支持同时生效
|
||
|
||
### 4.3 已知无害现象
|
||
|
||
- 启动日志 `ERROR ... Failed to get machine uid: No such file or directory`:busybox/alpine 容器内没有 dbus machine-id 所致,官方镜像同样存在,hbbs 自动生成 ID 兜底,不影响功能
|
||
- 对 21118/21119 用普通 curl 探测返回 000/连接重置:这两个端口只接受 WebSocket 握手,非 ws 请求被断开是预期行为
|
||
|
||
## 5. 注意事项
|
||
|
||
1. **远端未动**:全程未 push、未登录任何账号。本地仅有两个 git 操作:
|
||
- forapi 分支上一条本地合并提交(含格式串修复,已 amend 进合并提交)
|
||
- 备份分支 `forapi-backup-pre-merge`(合并前状态,`git reset --hard forapi-backup-pre-merge` 可整体还原)
|
||
2. **官方仓库 `/root/rustdesk/rustdesk/rustdesk-server` 全程只读**;镜像构建上下文是复制到 `/root/rustdesk/build/s6img` 后再改的
|
||
3. **代理配置时效性**:`gh-proxy.com`/`rsproxy.cn`/阿里云 apk 源均为当下可用的国内加速,失效时按 3.1/3.2/3.8 的思路换源
|
||
4. **目录占用**:`rustdesk-server/target/` 是编译缓存(数 GB,不需要可删);`/root/cargo-home` 是一次失败尝试的残留(可删);构建相关都在 `/root/rustdesk/build/`(`s6img/`、`fullimg/`、`apibuild/`、`rustdesk-api-web/`、`testdata/`)
|
||
5. **测试容器**:`rustdesk-test` 还在运行(测试数据在 `build/testdata`,admin 初始密码 `S2qAgqSw`),`docker rm -f rustdesk-test` 清理
|
||
6. **下次升级的路径**:本次做法可复用——`git fetch upstream && git merge upstream/master`,重点冲突仍会集中在 `src/rendezvous_server.rs`(fork 的 API 特性与上游安全修复叠加);hbb_common 子模块直接指到上游对应提交;编译用同样的容器方案
|
||
|
||
## 6. 常用命令备忘
|
||
|
||
```sh
|
||
# 服务器编译(持久容器方案)
|
||
docker run -d --name rustbuild --network host \
|
||
-v /root/rustdesk/lejianwen/rustdesk-server:/srv -w /srv rust:alpine sleep infinity
|
||
# 容器内:换阿里云 apk 源 → apk add build-base pkgconf openssl-dev openssl-libs-static git
|
||
# /usr/local/cargo/config.toml 配置 rsproxy-sparse + git-fetch-with-cli
|
||
# git config --system insteadOf 走 gh-proxy
|
||
docker exec rustbuild cargo build --release
|
||
|
||
# s6 基础镜像
|
||
docker build -f /root/rustdesk/build/s6img/Dockerfile.local -t rustdesk-server-s6:1.1.17-forapi /root/rustdesk/build/s6img
|
||
|
||
# 最终镜像(context 必须含 amd64/release)
|
||
docker build -f /root/rustdesk/build/fullimg/Dockerfile \
|
||
--build-arg BUILDARCH=amd64 -t yangjieshao/rustdesk-api:full-s6-amd64 /root/rustdesk/build/apibuild
|
||
|
||
# 验证
|
||
docker run -d --name rustdesk-test -p 21114-21119:21114-21119 -p 21116:21116/udp \
|
||
-e RELAY=<IP[:21117]> -v <data>:/data -v <appdata>:/app/data \
|
||
yangjieshao/rustdesk-api:full-s6-amd64
|
||
curl -s http://127.0.0.1:21114/_admin/ -o /dev/null -w '%{http_code}\n'
|
||
```
|
||
---
|
||
|
||
# 原始 README 内容
|
||
|
||
> 以下为 `lejianwen/rustdesk-api` 原始仓库的 README,本仓库在此基础上增加了
|
||
> 自连拦截(A 远程连 A)API 侧支持。
|
||
|
||
|
||
<div align=center>
|
||
<img src="https://img.shields.io/badge/golang-1.22-blue"/>
|
||
<img src="https://img.shields.io/badge/gin-v1.9.0-lightBlue"/>
|
||
<img src="https://img.shields.io/badge/gorm-v1.25.7-green"/>
|
||
<img src="https://img.shields.io/badge/swag-v1.16.3-yellow"/>
|
||
<img src="https://goreportcard.com/badge/github.com/lejianwen/rustdesk-api/v2"/>
|
||
<img src="https://github.com/lejianwen/rustdesk-api/actions/workflows/build.yml/badge.svg"/>
|
||
</div>
|
||
|
||
## 搭配[lejianwen/rustdesk-server]使用更佳。
|
||
> [lejianwen/rustdesk-server]fork自RustDesk Server官方仓库
|
||
> 1. 解决了使用API链接超时问题
|
||
> 2. 可以强制登录后才能发起链接
|
||
> 3. 支持客户端websocket
|
||
|
||
|
||
|
||
# 特性
|
||
|
||
- PC端API
|
||
- 个人版API
|
||
- 登录
|
||
- 地址簿
|
||
- 群组
|
||
- 授权登录
|
||
- 支持`github`, `google` 和 `OIDC` 登录,
|
||
- 支持`web后台`授权登录
|
||
- 支持`LDAP`(AD和OpenLDAP已测试), 如果API Server配置了LDAP
|
||
- i18n
|
||
- Web Admin
|
||
- 用户管理
|
||
- 设备管理
|
||
- 地址簿管理
|
||
- 标签管理
|
||
- 群组管理
|
||
- Oauth 管理
|
||
- 配置LDAP, 配置文件或者环境变量
|
||
- 登录日志
|
||
- 链接日志
|
||
- 文件传输日志
|
||
- 快速使用web client
|
||
- i18n
|
||
- 通过 web client 分享给游客
|
||
- server控制(一些官方的简单的指令 [WIKI](https://github.com/lejianwen/rustdesk-api/wiki/Rustdesk-Command))
|
||
- Web Client
|
||
- 自动获取API server
|
||
- 自动获取ID服务器和KEY
|
||
- 自动获取地址簿
|
||
- 游客通过临时分享链接直接远程到设备
|
||
- CLI
|
||
- 重置管理员密码
|
||
|
||
## 功能
|
||
|
||
|
||
### API 服务
|
||
基本实现了PC端基础的接口。支持Personal版本接口,可以通过配置文件`rustdesk.personal`或环境变量`RUSTDESK_API_RUSTDESK_PERSONAL`来控制是否启用
|
||
|
||
<table>
|
||
<tr>
|
||
<td width="50%" align="center" colspan="2"><b>登录</b></td>
|
||
</tr>
|
||
<tr>
|
||
<td width="50%" align="center" colspan="2"><img src="docs/pc_login.png"></td>
|
||
</tr>
|
||
<tr>
|
||
<td width="50%" align="center"><b>地址簿</b></td>
|
||
<td width="50%" align="center"><b>群组</b></td>
|
||
</tr>
|
||
<tr>
|
||
<td width="50%" align="center"><img src="docs/pc_ab.png"></td>
|
||
<td width="50%" align="center"><img src="docs/pc_gr.png"></td>
|
||
</tr>
|
||
</table>
|
||
|
||
### Web Admin:
|
||
|
||
* 使用前后端分离,提供用户友好的管理界面,主要用来管理和展示。前端代码在[rustdesk-api-web](https://github.com/lejianwen/rustdesk-api-web)
|
||
|
||
* 后台访问地址是`http://<your server>[:port]/_admin/`
|
||
* 初次安装管理员为用户名为`admin`,密码将在控制台打印,可以通过[命令行](#CLI)更改密码
|
||
|
||

|
||
|
||
1. 管理员界面
|
||

|
||
2. 普通用户界面
|
||

|
||
|
||
3. 每个用户可以多个地址簿,也可以将地址簿共享给其他用户
|
||
4. 分组可以自定义,方便管理,暂时支持两种类型: `共享组` 和 `普通组`
|
||
5. 可以直接打开webclient,方便使用;也可以分享给游客,游客可以直接通过webclient远程到设备
|
||
6. Oauth,支持了`Github`, `Google` 以及 `OIDC`, 需要创建一个`OAuth App`,然后配置到后台
|
||
- 对于`Google` 和 `Github`, `Issuer` 和 `Scopes`不需要填写.
|
||
- 对于`OIDC`, `Issuer`是必须的。`Scopes`是可选的,默认为 `openid,profile,email`. 确保可以获取 `sub`,`email` 和`preferred_username`
|
||
- `github oauth app`在`Settings`->`Developer settings`->`OAuth Apps`->`New OAuth App`
|
||
中创建,地址 [https://github.com/settings/developers](https://github.com/settings/developers)
|
||
- `Authorization callback URL`填写`http://<your server[:port]>/api/oidc/callback`
|
||
,比如`http://127.0.0.1:21114/api/oidc/callback`
|
||
7. 登录日志
|
||
8. 链接日志
|
||
9. 文件传输日志
|
||
10. server控制
|
||
|
||
- `简易模式`,已经界面化了一些简单的指令,可以直接在后台执行
|
||

|
||
|
||
- `高级模式`,直接在后台执行指令
|
||
* 可以官方指令
|
||
* 可以添加自定义指令
|
||
* 可以执行自定义指令
|
||
|
||
|
||
11. **LDAP 支持**, 当在API Server上设置了LDAP(已测试AD和LDAP),可以通过LDAP中的用户信息进行登录 https://github.com/lejianwen/rustdesk-api/issues/114 ,如果LDAP验证失败,返回本地用户
|
||
|
||
### Web Client:
|
||
|
||
1. 如果已经登录了后台,web client将自动直接登录
|
||
2. 如果没登录后台,点击右上角登录即可,api server已经自动配置好了
|
||
3. 登录后,会自动同步ID服务器和KEY
|
||
4. 登录后,会将地址簿自动保存到web client中,方便使用
|
||
|
||
|
||
### 自动化文档: 使用 Swag 生成 API 文档,方便开发者理解和使用 API。
|
||
|
||
1. 后台文档 `<youer server[:port]>/admin/swagger/index.html`
|
||
2. PC端文档 `<youer server[:port]>/swagger/index.html`
|
||

|
||
|
||
### CLI
|
||
|
||
```bash
|
||
# 查看帮助
|
||
./apimain -h
|
||
```
|
||
|
||
#### 重置管理员密码
|
||
```bash
|
||
./apimain reset-admin-pwd <pwd>
|
||
```
|
||
|
||
## 安装与运行
|
||
|
||
### 相关配置
|
||
|
||
* [配置文件](./conf/config.yaml)
|
||
* 参考`conf/config.yaml`配置文件,修改相关配置。
|
||
* 如果`gorm.type`是`sqlite`,则不需要配置mysql相关配置。
|
||
* 语言如果不设置默认为`zh-CN`
|
||
|
||
### 环境变量
|
||
环境变量和配置文件`conf/config.yaml`中的配置一一对应,变量名前缀是`RUSTDESK_API`
|
||
下面表格并未全部列出,可以参考`conf/config.yaml`中的配置。
|
||
|
||
| 变量名 | 说明 | 示例 |
|
||
|--------------------------------------------------------|--------------------------------------------------------------------------------|------------------------------|
|
||
| TZ | 时区 | Asia/Shanghai |
|
||
| RUSTDESK_API_LANG | 语言 | `en`,`zh-CN` |
|
||
| RUSTDESK_API_APP_WEB_CLIENT | 是否启用web-client; 1:启用,0:不启用; 默认启用 | 1 |
|
||
| RUSTDESK_API_APP_REGISTER | 是否开启注册; `true`, `false` 默认`false` | `false` |
|
||
| RUSTDESK_API_APP_SHOW_SWAGGER | 是否可见swagger文档;`1`显示,`0`不显示,默认`0`不显示 | `1` |
|
||
| RUSTDESK_API_APP_TOKEN_EXPIRE | token有效时长 | `168h` |
|
||
| RUSTDESK_API_APP_DISABLE_PWD_LOGIN | 是否禁用密码登录; `true`, `false` 默认`false` | `false` |
|
||
| RUSTDESK_API_APP_REGISTER_STATUS | 注册用户默认状态; 1 启用,2 禁用, 默认 1 | `1` |
|
||
| RUSTDESK_API_APP_CAPTCHA_THRESHOLD | 验证码触发次数; -1 不启用, 0 一直启用, >0 登录错误次数后启用 ;默认 `3` | `3` |
|
||
| RUSTDESK_API_APP_BAN_THRESHOLD | 封禁IP触发次数; 0 不启用, >0 登录错误次数后封禁IP; 默认 `0` | `0` |
|
||
| -----ADMIN配置----- | ---------- | ---------- |
|
||
| RUSTDESK_API_ADMIN_TITLE | 后台标题 | `RustDesk Api Admin` |
|
||
| RUSTDESK_API_ADMIN_HELLO | 后台欢迎语,可以使用`html` | |
|
||
| RUSTDESK_API_ADMIN_HELLO_FILE | 后台欢迎语文件,如果内容多,使用文件更方便。<br>会覆盖`RUSTDESK_API_ADMIN_HELLO` | `./conf/admin/hello.html` |
|
||
| -----GIN配置----- | ---------- | ---------- |
|
||
| RUSTDESK_API_GIN_TRUST_PROXY | 信任的代理IP列表,以`,`分割,默认信任所有 | 192.168.1.2,192.168.1.3 |
|
||
| -----GORM配置----- | ---------- | --------------------------- |
|
||
| RUSTDESK_API_GORM_TYPE | 数据库类型sqlite或者mysql,默认sqlite | sqlite |
|
||
| RUSTDESK_API_GORM_MAX_IDLE_CONNS | 数据库最大空闲连接数 | 10 |
|
||
| RUSTDESK_API_GORM_MAX_OPEN_CONNS | 数据库最大打开连接数 | 100 |
|
||
| RUSTDESK_API_RUSTDESK_PERSONAL | 是否启用个人版API, 1:启用,0:不启用; 默认启用 | 1 |
|
||
| -----MYSQL配置----- | ---------- | ---------- |
|
||
| RUSTDESK_API_MYSQL_USERNAME | mysql用户名 | root |
|
||
| RUSTDESK_API_MYSQL_PASSWORD | mysql密码 | 111111 |
|
||
| RUSTDESK_API_MYSQL_ADDR | mysql地址 | 192.168.1.66:3306 |
|
||
| RUSTDESK_API_MYSQL_DBNAME | mysql数据库名 | rustdesk |
|
||
| RUSTDESK_API_MYSQL_TLS | 是否启用TLS, 可选值: `true`, `false`, `skip-verify`, `custom` | `false` |
|
||
| -----RUSTDESK配置----- | ---------- | ---------- |
|
||
| RUSTDESK_API_RUSTDESK_ID_SERVER | Rustdesk的id服务器地址 | 192.168.1.66:21116 |
|
||
| RUSTDESK_API_RUSTDESK_RELAY_SERVER | Rustdesk的relay服务器地址 | 192.168.1.66:21117 |
|
||
| RUSTDESK_API_RUSTDESK_API_SERVER | Rustdesk的api服务器地址 | http://192.168.1.66:21114 |
|
||
| RUSTDESK_API_RUSTDESK_KEY | Rustdesk的key | 123456789 |
|
||
| RUSTDESK_API_RUSTDESK_KEY_FILE | Rustdesk存放key的文件 | `./conf/data/id_ed25519.pub` |
|
||
| RUSTDESK_API_RUSTDESK_WEBCLIENT<br/>_MAGIC_QUERYONLINE | Web client v2 中是否启用新的在线状态查询方法; `1`:启用,`0`:不启用,默认不启用 | `0` |
|
||
| RUSTDESK_API_RUSTDESK_WS_HOST | 自定义Websocket Host | `wss://192.168.1.123:1234` |
|
||
| ----PROXY配置----- | ---------- | ---------- |
|
||
| RUSTDESK_API_PROXY_ENABLE | 是否启用代理:`false`, `true` | `false` |
|
||
| RUSTDESK_API_PROXY_HOST | 代理地址 | `http://127.0.0.1:1080` |
|
||
| ----JWT配置---- | -------- | -------- |
|
||
| RUSTDESK_API_JWT_KEY | 自定义JWT KEY,为空则不启用JWT<br/>如果没使用`lejianwen/rustdesk-server`中的`MUST_LOGIN`,建议设置为空 | |
|
||
| RUSTDESK_API_JWT_EXPIRE_DURATION | JWT有效时间 | `168h` |
|
||
|
||
|
||
### 运行
|
||
|
||
#### docker运行
|
||
|
||
1. 直接docker运行,配置可以通过挂载配置文件`/app/conf/config.yaml`来修改,或者通过环境变量覆盖配置文件中的配置
|
||
|
||
```bash
|
||
docker run -d --name rustdesk-api -p 21114:21114 \
|
||
-v /data/rustdesk/api:/app/data \
|
||
-e TZ=Asia/Shanghai \
|
||
-e RUSTDESK_API_LANG=zh-CN \
|
||
-e RUSTDESK_API_RUSTDESK_ID_SERVER=192.168.1.66:21116 \
|
||
-e RUSTDESK_API_RUSTDESK_RELAY_SERVER=192.168.1.66:21117 \
|
||
-e RUSTDESK_API_RUSTDESK_API_SERVER=http://192.168.1.66:21114 \
|
||
-e RUSTDESK_API_RUSTDESK_KEY=<key> \
|
||
lejianwen/rustdesk-api
|
||
```
|
||
|
||
2. 使用`docker compose`,参考[WIKI](https://github.com/lejianwen/rustdesk-api/wiki)
|
||
|
||
#### 下载release直接运行
|
||
|
||
[下载地址](https://github.com/lejianwen/rustdesk-api/releases)
|
||
|
||
#### 源码安装
|
||
|
||
1. 克隆仓库
|
||
```bash
|
||
git clone https://github.com/lejianwen/rustdesk-api.git
|
||
cd rustdesk-api
|
||
```
|
||
|
||
2. 安装依赖
|
||
|
||
```bash
|
||
go mod tidy
|
||
#安装swag,如果不需要生成文档,可以不安装
|
||
go install github.com/swaggo/swag/cmd/swag@latest
|
||
```
|
||
|
||
3. 编译后台前端,前端代码在[rustdesk-api-web](https://github.com/lejianwen/rustdesk-api-web)中
|
||
```bash
|
||
cd resources
|
||
mkdir -p admin
|
||
git clone https://github.com/lejianwen/rustdesk-api-web
|
||
cd rustdesk-api-web
|
||
npm install
|
||
npm run build
|
||
cp -ar dist/* ../admin/
|
||
```
|
||
4. 运行
|
||
```bash
|
||
#直接运行
|
||
go run cmd/apimain.go
|
||
#或者使用generate_api.go生成api并运行
|
||
go generate generate_api.go
|
||
```
|
||
> 注意:使用 `go run` 或编译后的二进制时,当前目录下必须存在 `conf` 和 `resources`
|
||
> 目录。如果在其他目录运行,可通过 `-c` 和环境变量
|
||
> `RUSTDESK_API_GIN_RESOURCES_PATH` 指定绝对路径,例如:
|
||
> ```bash
|
||
> RUSTDESK_API_GIN_RESOURCES_PATH=/opt/rustdesk-api/resources ./apimain -c /opt/rustdesk-api/conf/config.yaml
|
||
> ```
|
||
5. 编译,如果想自己编译,先cd到项目根目录,然后windows下直接运行`build.bat`,linux下运行`build.sh`,编译后会在`release`
|
||
目录下生成对应的可执行文件。直接运行编译后的可执行文件即可。
|
||
|
||
6. 打开浏览器访问`http://<your server[:port]>/_admin/`,默认用户名密码为`admin`,请及时更改密码。
|
||
|
||
|
||
#### 使用`lejianwen/server-s6`镜像运行
|
||
|
||
- 已解决链接超时问题
|
||
- 可以强制登录后才能发起链接
|
||
- github https://github.com/lejianwen/rustdesk-server
|
||
|
||
```yaml
|
||
networks:
|
||
rustdesk-net:
|
||
external: false
|
||
services:
|
||
rustdesk:
|
||
ports:
|
||
- 21114:21114
|
||
- 21115:21115
|
||
- 21116:21116
|
||
- 21116:21116/udp
|
||
- 21117:21117
|
||
- 21118:21118
|
||
- 21119:21119
|
||
image: lejianwen/rustdesk-server-s6:latest
|
||
environment:
|
||
- RELAY=<relay_server[:port]>
|
||
- ENCRYPTED_ONLY=1
|
||
- MUST_LOGIN=N
|
||
- TZ=Asia/Shanghai
|
||
- RUSTDESK_API_RUSTDESK_ID_SERVER=<id_server[:21116]>
|
||
- RUSTDESK_API_RUSTDESK_RELAY_SERVER=<relay_server[:21117]>
|
||
- RUSTDESK_API_RUSTDESK_API_SERVER=http://<api_server[:21114]>
|
||
- RUSTDESK_API_KEY_FILE=/data/id_ed25519.pub
|
||
- RUSTDESK_API_JWT_KEY=xxxxxx # jwt key
|
||
volumes:
|
||
- /data/rustdesk/server:/data
|
||
- /data/rustdesk/api:/app/data #将数据库挂载
|
||
networks:
|
||
- rustdesk-net
|
||
restart: unless-stopped
|
||
|
||
```
|
||
|
||
|
||
## 其他
|
||
|
||
- [WIKI](https://github.com/lejianwen/rustdesk-api/wiki)
|
||
- [链接超时问题](https://github.com/lejianwen/rustdesk-api/issues/92)
|
||
- [修改客户端ID](https://github.com/abdullah-erturk/RustDesk-ID-Changer)
|
||
- [webclient来源](https://hub.docker.com/r/keyurbhole/flutter_web_desk)
|
||
|
||
|
||
## 鸣谢
|
||
|
||
感谢所有做过贡献的人!
|
||
|
||
<a href="https://github.com/lejianwen/rustdesk-api/graphs/contributors">
|
||
<img src="https://contrib.rocks/image?repo=lejianwen/rustdesk-api" />
|
||
</a>
|