本项目使用 Go 实现了 RustDesk 的 API,并包含了 Web Admin 和 Web 客户端。RustDesk 是一个远程桌面软件,提供了自托管的解决方案。
github
, google
和 OIDC
登录,支持web后台
授权登录因为server端相对于客户端落后版本,server不会响应客户端的secure_tcp
请求,所以客户端超时。
相关代码代码位置在https://github.com/rustdesk/rustdesk/blob/master/src/client.rs#L322
if !key.is_empty() && !token.is_empty() {
// mainly for the security of token
allow_err!(secure_tcp(&mut socket, key).await);
}
可看到当key
和token
都不为空时,会调用secure_tcp
,但是server端不会响应,所以客户端超时
secure_tcp
代码位置在 https://github.com/rustdesk/rustdesk/blob/master/src/common.rs#L1203
hbbs -r <relay-server-ip[:port]> -k <key>
hbbr -k <key>
比如
hbbs -r <relay-server-ip[:port]> -k abc1234567
hbbr -k abc1234567
secure_tcp
修改成直接返回,然后通过Github Actions
编译,下载编译后的客户端。
参考官方文档
secure_tcp
,可以直接下载使用,下载地址
Github Actions
编译,链接加密,直接下载使用对链接加密要求不高的可以使用1
,对链接加密要求高的可以使用3
或4
基本实现了PC端基础的接口。支持Personal版本接口,可以通过配置文件rustdesk.personal
或环境变量RUSTDESK_API_RUSTDESK_PERSONAL
来控制是否启用
github
, google
以及OIDC
授权登录,需要在后台配置好就可以用了,具体可看后台OAuth配置群组分为共享组
和普通组
,共享组中所有人都能看到小组成员的设备,普通组只有管理员能看到所有小组成员的设备
使用前后端分离,提供用户友好的管理界面,主要用来管理和展示。前端代码在rustdesk-api-web
后台访问地址是http://<your server>[:port]/_admin/
初次安装管理员为用户名密码为admin
admin
,请即时更改密码
管理员界面
普通用户界面
右上角可以更改密码,可以切换语言,可以切换白天/黑夜
模式
分组可以自定义,方便管理,暂时支持两种类型: 共享组
和 普通组
可以直接打开webclient,方便使用;也可以分享给游客,游客可以直接通过webclient远程到设备
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/developersAuthorization callback URL
填写http://<your server[:port]>/api/oauth/callback
,比如http://127.0.0.1:21114/api/oauth/callback
v2 Preview
,访问路径是/webclient2
v2 preview
部署
443
端口的https
部署,必须配置反向代理,可以参考官方文档http
或者其他的https
端口部署,则和v1
一样,配置好21118
,21119
即可<youer server[:port]>/admin/swagger/index.html
<youer server[:port]>/swagger/index.html
# 查看帮助
./apimain -h
./apimain reset-admin-pwd <pwd>
conf/config.yaml
配置文件,修改相关配置。gorm.type
是sqlite
,则不需要配置mysql相关配置。zh-CN
lang: "en"
app:
web-client: 1 # 1:启用 0:禁用
register: false #是否开启注册
gin:
api-addr: "0.0.0.0:21114"
mode: "release"
resources-path: 'resources'
trust-proxy: ""
gorm:
type: "sqlite"
max-idle-conns: 10
max-open-conns: 100
mysql:
username: "root"
password: "111111"
addr: "192.168.1.66:3308"
dbname: "rustdesk"
rustdesk:
id-server: "192.168.1.66:21116"
relay-server: "192.168.1.66:21117"
api-server: "http://192.168.1.66:21114"
key: "123456789"
personal: 1
logger:
path: "./runtime/log.txt"
level: "warn" #trace,debug,info,warn,error,fatal
report-caller: true
proxy:
enable: false
host: ""
变量名前缀是RUSTDESK_API
,环境变量如果存在将覆盖配置文件中的配置
变量名 | 说明 | 示例 |
---|---|---|
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 |
-----ADMIN配置----- | ---------- | ---------- |
RUSTDESK_API_ADMIN_TITLE | 后台标题 | RustDesk Api Admin |
RUSTDESK_API_ADMIN_HELLO | 后台欢迎语,可以使用html |
|
RUSTDESK_API_ADMIN_HELLO_FILE | 后台欢迎语文件,如果内容多,使用文件更方便。 会覆盖 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配置----- | --------------- | ---------- |
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 |
----PROXY配置----- | --------------- | ---------- |
RUSTDESK_API_PROXY_ENABLE | 是否启用代理:false , true |
false |
RUSTDESK_API_PROXY_HOST | 代理地址 | http://127.0.0.1:1080 |
直接docker运行,配置可以通过挂载配置文件/app/conf/config.yaml
来修改,或者通过环境变量覆盖配置文件中的配置
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
使用docker compose
简单示例
services:
rustdesk-api:
container_name: rustdesk-api
environment:
- TZ=Asia/Shanghai
- RUSTDESK_API_RUSTDESK_ID_SERVER=192.168.1.66:21116
- RUSTDESK_API_RUSTDESK_RELAY_SERVER=192.168.1.66:21117
- RUSTDESK_API_RUSTDESK_API_SERVER=http://192.168.1.66:21114
- RUSTDESK_API_RUSTDESK_KEY=<key>
ports:
- 21114:21114
image: lejianwen/rustdesk-api
volumes:
- /data/rustdesk/api:/app/data #将数据库挂载出来方便备份
networks:
- rustdesk-net
restart: unless-stopped
根据rustdesk官方提供的示例,加上自己的rustdesk-api
-k <key>
参数,在启动后运行docker-compose logs hbbs
或者cat ./data/id_ed25519.pub
查看KEY,然后再修改RUSTDESK_API_RUSTDESK_KEY=<key>
再执行docker-compose up -d
networks:
rustdesk-net:
external: false
services:
hbbs:
container_name: hbbs
ports:
- 21115:21115
- 21116:21116 # 自定义 hbbs 映射端口
- 21116:21116/udp # 自定义 hbbs 映射端口
- 21118:21118 # web client
image: rustdesk/rustdesk-server
command: hbbs -r <relay-server-ip[:port]> -k <key> # 填入个人域名或 IP + hbbr 暴露端口
volumes:
- ./data:/root # 自定义挂载目录
networks:
- rustdesk-net
depends_on:
- hbbr
restart: unless-stopped
deploy:
resources:
limits:
memory: 64M
hbbr:
container_name: hbbr
ports:
- 21117:21117 # 自定义 hbbr 映射端口
- 21119:21119 # web client
image: rustdesk/rustdesk-server
command: hbbr -k <key>
volumes:
- ./data:/root
networks:
- rustdesk-net
restart: unless-stopped
deploy:
resources:
limits:
memory: 64M
rustdesk-api:
container_name: rustdesk-api
environment:
- TZ=Asia/Shanghai
- RUSTDESK_API_RUSTDESK_ID_SERVER=192.168.1.66:21116
- RUSTDESK_API_RUSTDESK_RELAY_SERVER=192.168.1.66:21117
- RUSTDESK_API_RUSTDESK_API_SERVER=http://192.168.1.66:21114
- RUSTDESK_API_RUSTDESK_KEY=<key>
ports:
- 21114:21114
image: lejianwen/rustdesk-api
volumes:
- /data/rustdesk/api:/app/data #将数据库挂载出来方便备份
networks:
- rustdesk-net
restart: unless-stopped
S6的镜像
/etc/s6-overlay/s6-rc.d/hbbr/run
和/etc/s6-overlay/s6-rc.d/hbbr/run
hbbr/run
,自定义KEY才需要
#!/command/with-contenv sh
cd /data
PARAMS=
[ "${ENCRYPTED_ONLY}" = "1" ] && PARAMS="-k ${KEY}"
/usr/bin/hbbr $PARAMS
hbbs/run
,自定义KEY才需要
#!/command/with-contenv sh
sleep 2
cd /data
PARAMS=
[ "${ENCRYPTED_ONLY}" = "1" ] && PARAMS="-k ${KEY}"
/usr/bin/hbbs -r $RELAY $PARAMS
docker-compose.yml
中的s6
部分
networks:
rustdesk-net:
external: false
services:
rustdesk-server:
container_name: rustdesk-server
ports:
- 21115:21115
- 21116:21116
- 21116:21116/udp
- 21117:21117
- 21118:21118
- 21119:21119
image: rustdesk/rustdesk-server-s6:latest
environment:
- RELAY=192.168.1.66:21117
- ENCRYPTED_ONLY=1
- KEY=<key> #自定义KEY
volumes:
- ./data:/data
- ./hbbr/run:/etc/s6-overlay/s6-rc.d/hbbr/run
- ./hbbs/run:/etc/s6-overlay/s6-rc.d/hbbs/run
restart: unless-stopped
rustdesk-api:
container_name: rustdesk-api
ports:
- 21114:21114
image: lejianwen/rustdesk-api
environment:
- TZ=Asia/Shanghai
- RUSTDESK_API_RUSTDESK_ID_SERVER=192.168.1.66:21116
- RUSTDESK_API_RUSTDESK_RELAY_SERVER=192.168.1.66:21117
- RUSTDESK_API_RUSTDESK_API_SERVER=http://192.168.1.66:21114
- RUSTDESK_API_RUSTDESK_KEY=<key>
volumes:
- /data/rustdesk/api:/app/data #将数据库挂载
networks:
- rustdesk-net
restart: unless-stopped
如果使用系统生成的KEY或者自定义KEY_PUB,KEY_PRIV,不需要修改启动脚本,但要在生成KEY后获取到KEY再docker-compose up -d
networks:
rustdesk-net:
external: false
services:
rustdesk-server:
container_name: rustdesk-server
ports:
- 21115:21115
- 21116:21116
- 21116:21116/udp
- 21117:21117
- 21118:21118
- 21119:21119
image: rustdesk/rustdesk-server-s6:latest
environment:
- RELAY=192.168.1.66:21117
- ENCRYPTED_ONLY=1
volumes:
- ./data:/data
restart: unless-stopped
rustdesk-api:
container_name: rustdesk-api
ports:
- 21114:21114
image: lejianwen/rustdesk-api
environment:
- TZ=Asia/Shanghai
- RUSTDESK_API_RUSTDESK_ID_SERVER=192.168.1.66:21116
- RUSTDESK_API_RUSTDESK_RELAY_SERVER=192.168.1.66:21117
- RUSTDESK_API_RUSTDESK_API_SERVER=http://192.168.1.66:21114
- RUSTDESK_API_RUSTDESK_KEY=<key> #系统生成的KEY
volumes:
- /data/rustdesk/api:/app/data #将数据库挂载
networks:
- rustdesk-net
restart: unless-stopped
克隆仓库
git clone https://github.com/lejianwen/rustdesk-api.git
cd rustdesk-api
安装依赖
go mod tidy
#安装swag,如果不需要生成文档,可以不安装
go install github.com/swaggo/swag/cmd/swag@latest
编译后台前端,前端代码在rustdesk-api-web中
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/
运行
#直接运行
go run cmd/apimain.go
#或者使用generate_api.go生成api并运行
go generate generate_api.go
编译,如果想自己编译,先cd到项目根目录,然后windows下直接运行build.bat
,linux下运行build.sh
,编译后会在release
目录下生成对应的可执行文件。直接运行编译后的可执行文件即可。
打开浏览器访问http://<your server[:port]>/_admin/
,默认用户名密码为admin
,请及时更改密码。
在nginx
中配置反代
server {
listen <your port>;
server_name <your server>;
location / {
proxy_pass http://<api-server[:port]>;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
}
}