Files
rustdesk-api/README.md
T

633 lines
34 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 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)更改密码
![img.png](./docs/init_admin_pwd.png)
1. 管理员界面
![web_admin](docs/web_admin.png)
2. 普通用户界面
![web_user](docs/web_admin_user.png)
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控制
- `简易模式`,已经界面化了一些简单的指令,可以直接在后台执行
![rustdesk_command_simple](./docs/rustdesk_command_simple.png)
- `高级模式`,直接在后台执行指令
* 可以官方指令
* 可以添加自定义指令
* 可以执行自定义指令
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`
![api_swag](docs/api_swag.png)
### 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>