Administrator
Published on 2025-07-08 / 118 Visits
0
0

RustDesk 开源远程桌面软件系统,自建服务器部署(审计)、发布和使用教程

前言

RustDesk 是一个强大的开源远程桌面软件,是中国开发者的作品,它使用 Rust 编程语言构建,提供安全、高效、跨平台的远程访问体验。可以说是目前全球最火的开源远程桌面软件了,GitHub 收藏数量达到了惊人的 92k!

教程功能

  1. 简单介绍RustDesk ,对RustDesk 原理进行简单说明

  2. 提供linux原生安装和docker安装两种方式自建RustDesk服务器

  3. 第三方开源web-api服务(RustDesk开源版本没有权限用户相关管理权限控制,pro版本才有)

  4. 如何发布RustDesk 服务端(主要为开放端口说明)

  5. 客户端简单使用RustDesk

视频比较细,时长较长,已经分段完成,各位小伙伴可以选择分段观看。

TeamViewerToDesk向日葵等专有远程访问解决方案相比,RustDesk 作为一个开源软件,提供了几个显著的优势:

  1. RustDesk 完全免费使用,没有任何隐藏费用或订阅计划。

  2. 由于其开源特性,RustDesk 的代码是透明的,可以由社区审计,从而提供更高的安全性和可信度。

  3. 由于RustDesk 允许自建服务器,隐私性更高

  4. RustDesk 自建服务器硬件需求非常低官方说法如下:

    硬件要求非常低;基本云服务器的最低配置就足够了,CPU和内存要求极低。您也可以使用树莓派或类似设备。关于网络规模,如果TCP打洞直连失败,将消耗中继流量。中继连接的流量根据分辨率设置和屏幕更新在30 K/s到3 M/s(1920x1080屏幕)之间。如果仅用于办公需求,流量约为100 K/s。

由于被诈骗分子频繁使用,该项目现已暂停国内服务。即国内无法通过公共服务器连接

技术架构对比

维度

TeamViewer

RustDesk

传输协议

私有协议(优化带宽和延迟)

WebRTC + 自定义协议(依赖P2P/UDP打洞)

中继服务器

全球分布式商业服务器(强制中转)

可选自建中继服务器(开源实现)

连接方式

优先P2P,失败时自动中转

强制尝试P2P,失败后走自建/官方中继

代码可控性

闭源

完全开源(MIT许可)

功能差异对比

功能

TeamViewer

RustDesk

多平台支持

✔️ (Win/macOS/Linux/iOS/Android/Web)

✔️ (全平台+浏览器客户端)

多显示器切换

✔️ (无缝切换)

✔️

文件传输

✔️ (拖拽/管理界面)

✔️ (基础拖拽)

会议功能

✔️ (最多300人,企业版)

❌ (仅1对1控制)

远程打印

✔️ (虚拟驱动)

无人值守访问

✔️ (设备分组/批量部署)

✔️ (需手动设置密码)

命令行控制

✔️ (TV CLI)

✔️ (命令行参数)

移动设备控制

✔️ (Android/iOS反向控制)

✔️ (Android/iOS反向控制)

RustDesk 架构概述

RustDesk 采用了经典的客户端-服务器模型,其中涉及三个主要组件:RustDesk 客户端、RustDesk 服务器和 ID Server。

  1. 客户端-服务器模型

    在 RustDesk 的架构中,客户端是运行在用户设备 (如笔记本电脑、平板电脑或智能手机) 上的应用程序。它提供了一个图形界面,允许用户发起远程访问请求并与远程计算机进行交互。另一方面,服务器组件运行在要远程访问的目标计算机上。它负责监听来自客户端的连接请求,并在建立连接后向客户端发送屏幕更新和接收输入事件。

  2. ID Server 的角色

    ID Server 在 RustDesk 的生态系统中扮演着重要的角色。它的主要职责是促进客户端和服务器之间的初始连接建立。当 RustDesk 服务器启动时,它会连接到 ID Server 并注册自己,提供如服务器 ID 和公网 IP 地址等信息。类似地,当客户端想要连接到特定的 RustDesk 服务器时,它会向 ID Server 查询目标服务器的连接信息。

    ID Server 维护了一个已注册的 RustDesk 服务器目录,并充当客户端和服务器之间的中介,帮助它们建立直接的点对点 (P2P) 连接。一旦客户端从 ID Server 获得了服务器的连接信息,它就可以尝试直接连接到服务器,而无需进一步通过 ID Server 中继数据。

  3. Relay Server 的角色

    在某些网络环境下,RustDesk 客户端和服务器可能无法直接建立 P2P 连接,例如当它们位于 NAT (网络地址转换) 或防火墙后时。为了克服这一挑战,RustDesk 引入了 Relay Server。

    如果客户端无法直接连接到服务器,它会向 ID Server 请求一个 Relay Server。然后,客户端和服务器都连接到指定的 Relay Server,并通过它来中继所有的网络通信。Relay Server 在这种情况下充当客户端和服务器之间的桥梁,转发来自一方的数据包到另一方。

    值得注意的是,即使通过 Relay Server 进行通信,RustDesk 也会维护端到端加密,确保中继服务器无法访问明文数据。Relay Server 只是盲目地转发加密的数据包,而不能查看或修改其内容。

RustDesk 部署教程

linux原生部署

服务器配置说明:

配置项

参数

cpu

1C

内存

1G

系统

Ubuntu 24.04 任意linux系统

下载 Rustdesk Server

方法1 本站直接下载

rustdesk-server-linux-amd64.zip

方法2 直接前往官方页面下载

https://github.com/rustdesk/rustdesk-server/releases

方法3 服务器直接或者代理下载

docker github代理地址:https://www.cnproxy.top/

使用githuab代理或者直接下载

wget https://ghproxy.cnproxy.top/https://github.com/rustdesk/rustdesk-se
rver/releases/download/1.1.14/rustdesk-server-linux-amd64.zip

解压Rustdesk Server

apt install unzip
​
unzip rustdesk-server-linux-amd64.zip

解压完成后会出现hbbr,hbbs,rustdesk-utils三个文件

hbbr

  • hbbr是RustDesk Relay Server,即RustDesk中继服务器,当客户端之间无法直接建立P2P连接时,会通过hbbr中继服务器进行数据传输hbbr允许无法直接建立P2P连接的客户端通过中继服务器进行通信。

hbbs

  • hbbs代表RustDesk ID / Rendezvous Server,即RustDesk ID注册服务器。它用于分配和注册ID,并且是RustDesk的中介服务器(Broker Server),用于管理和协调客户端连接。hbbs帮助客户端找到并建立P2P连接,负责维护客户端的在线状态,并处理连接请求。当客户端A希望连接客户端B时,它会向hbbs发送请求,hbbs会帮助它们建立连接。

rustdesk-utils

  • rustdesk-utils是RustDesk的命令行工具,提供了一些管理和操作RustDesk服务器端的工具和命令。

配置系统服务且加入开机自启动

执行vim hbbr.service 配置系统级服务

[Unit]
Description=RustDesk Relay Server
After=network.target
​
[Service]
Type=simple
ExecStart=/opt/rustdesk/hbbr
Restart=on-failure
WorkingDirectory=/opt/rustdesk
​
[Install]
WantedBy=multi-user.target
​

执行vim hbbs.service 配置系统级服务

[Unit]
Description=RustDesk Relay Server
After=network.target
​
[Service]
Type=simple
ExecStart=/opt/rustdesk/hbbs
Restart=on-failure
WorkingDirectory=/opt/rustdesk
​
[Install]
WantedBy=multi-user.target
​

将服务添加到系统服务,且加入开机自启动

//将当前路径服务以软连接加入系统服务中
ln -s /opt/rustdesk/hbbr.service /etc/systemd/system/
ln -s /opt/rustdesk/hbbs.service /etc/systemd/system/
//重载服务
systemctl daemon-reload
//启动并且加入开机自启动
​
systemctl enable --now hbbs.service 
systemctl enable --now hbbr.service
总结
  1. 解压完成后hbbr与hbbs可以移动位置,但是两个文件需放在同一目录中。

  2. 首次需要先启动hbbs在启动hbbr

docker部署教程

安装docker

见本站docker安装教程https://halo.blog360.sbs/archives/dockeran-zhuang-jiao-cheng

运行容器

docker 直接运行
# hbbs (id服务)
# -v:挂载文件目录。[本机目录]:[容器目录]
# --net=host:容器应用使用宿主机网络,不需要再配置docker的端口映射或者进行端口映射
# -r [服务器公网IP或域名]:对应当前服务器的地址,例如123.123.123.123,或域名mydomain.com
docker run --restart=always  --name hbbs  -v /opt/rustdesk:/root -td --net=host rustdesk/rustdesk-server  hbbs  -r [服务器公网IP或域名]  
​
# hbbr (中继服务)
docker run  --restart=always --name hbbr   -v /opt/rustdesk:/root -td  --net=host rustdesk/rustdesk-server  hbbr

docker compose运行
version: '3'
​
networks:
  rustdesk-net:
    external: false
​
services:
  hbbs:
    container_name: hbbs
    ports:
      - 21115:21115
      - 21116:21116
      - 21116:21116/udp
      - 21118:21118
    image: rustdesk/rustdesk-server:latest
    command: hbbs -r rustdesk.example.com:21117 # 公网ip或者域名,为中继连接节点
    volumes:
      - ./data:/root
    networks:
      - rustdesk-net
    depends_on:
      - hbbr
    restart: unless-stopped
​
  hbbr:
    container_name: hbbr
    ports:
      - 21117:21117
      - 21119:21119
    image: rustdesk/rustdesk-server:latest
    command: hbbr
    volumes:
      - ./data:/root
    networks:
      - rustdesk-net
    restart: unless-stopped

总结

1. 注意配置公网访问中继节点

rustdesk-web-API-server 部署

首先我们为什么要部署rustdesk-API-server,我们需要指定rustdesk开源版本与pro版本的区别,其核心区别主要有下:

功能

开源自托管版

Pro 自托管版

Web 管理控制台

❌ 无

✅ 完整图形化界面(设备/用户/权限管理)

API 接口

❌ 无

✅ RESTful API(自动化集成)

审计日志

❌ 仅基础连接日志

✅ 完整操作审计(登录/会话/文件传输)

设备分组/标签

❌ 手动管理

✅ 可视化批量管理

企业级安全

❌ 基础密码验证

✅ TOTP 两步验证 (2FA)

会议功能

❌ 仅一对一连接

✅ 支持多人会议(≤10人)

安卓隐私黑屏

❌ 无

✅ 被控时屏幕自动黑屏

商业授权

❌ AGPLv3 (有传染性)

✅ 商业许可(规避开源风险)

官方技术支持

❌ 仅社区支持

✅ 订阅用户专属支持

对应企业而言,前五条还是比较重要的,而pro版本的订阅价格还比较贵,我们可以通过自行部署其他第三方rustdesk-web-API来解决,当然第三方肯定无法和官方的pro比较,如果权限要求比较细也可以购买pro版本支持一下

那么我们本次部署所使用的第三方rustdesk-web-API可以提供哪些功能呢?基本如下

功能

详情

Web 管理控制台

提供了一个完整图形化界面(设备/用户/权限管理)

API 接口

RESTful API 并且提供了swagger接口,可以自行定制开发

设备分组/标签

可视化批量管理

安全提升

可强制要求登录后才允许使用远程

项目地址:https://github.com/lejianwen/rustdesk-api

安装docker

见本站docker安装教程

docker compose运行

添加docker-compose.yml文件

version: '3'  # 必须声明版本(推荐 ≥3.5)
​
services:
  rustdesk:
    image: lejianwen/rustdesk-server-s6:latest
    container_name: rustdesk-server
    ports:
      - "21114:21114"    # 注意:所有端口必须加引号(YAML规范)
      - "21115:21115"
      - "21116:21116"    # TCP端口
      - "21116:21116/udp" # UDP端口(无需重复定义TCP)
      - "21117:21117"
      - "21118:21118"
      - "21119:21119"
    environment: 
      - RELAY=rustdesk.domain.com:21117 # 默认的中继服务器
      - ENCRYPTED_ONLY=1
      - MUST_LOGIN=Y  # 是否强制登陆才运行使用
      - TZ=Asia/Shanghai # 时区
     # - RUSTDESK_API_GORM_TYPE=mysql
     # - RUSTDESK_API_MYSQL_USERNAME=root
     # - RUSTDESK_API_MYSQL_PASSWORD=123456
     # - RUSTDESK_API_MYSQL_ADDR=192.168.1.1
     # - RUSTDESK_API_MYSQL_DBNAME=rustdesk_db
      - RUSTDESK_API_APP_SHOW_SWAGGER=0 # 是否启用swagger 
      - RUSTDESK_API_RUSTDESK_KEY=1222112= #jwt key
      - RUSTDESK_API_RUSTDESK_API_SERVER=https://rustdesk.domain.com # 默认访问的api路径
      - RUSTDESK_API_RUSTDESK_RELAY_SERVER=rustdesk.domain.com:21117
      - RUSTDESK_API_RUSTDESK_ID_SERVER=rustdesk.domain.com:21116
    volumes:
      - ./data:/data
      - ./data/api:/app/data #将数据库挂载 sqlite 数据库文件挂载 为mysql时可以不配置
    restart: unless-stopped
    networks:
      - rustdesk-net
​
networks:  # 顶级配置(顶格书写)
  rustdesk-net:
    driver: bridge

完整参数配置

变量名

说明

示例

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

后台欢迎语文件,如果内容多,使用文件更方便。 会覆盖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

RUSTDESK_API_RUSTDESK_WEBCLIENT MAGICQUERYONLINE

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 如果没使用lejianwen/rustdesk-server中的MUST_LOGIN,建议设置为空

RUSTDESK_API_JWT_EXPIRE_DURATION

JWT有效时间

168h

查看密码

执行

docker logs -f docker容器ID

查看密码

总结

  1. 注意这个服务包已经包含了hbbr与hbbs,可以不用再部署了。

  2. 默认超管密码将会在容器日志中输出。

  3. 默认容器已经禁用了注册功能。

RustDesk 发布教程

在发布之前,我们需要了解rustdesk各个端口的作用:

了解端口,确认发布端口

hbbs 服务所需端口

协议

端口号

说明

TCP

21114

用于 Web 控制台(可选)

TCP

21115

用于 NAT 类型测试

TCP/UDP

21116

必须同时启用 TCP 和 UDP,用于 ID 注册、心跳服务(UDP)以及 TCP 打洞、连接服务(TCP)

TCP

21118

用于支持 Web 客户端(可选)

hbbr 服务所需端口

协议

端口号

说明

TCP

21117

用于中继服务

TCP

21119

用于支持 Web 客户端(可选)

那么可以根据一下需求来

RustDesk 官方开源版本

端口

是否必须

21116 tcp/udp

21117 tcp

建议开放,用于在p2p失败后中继

21115 tcp

建议不开放

rustdesk-web-API-server 第三方带服务版本

端口

是否必须

21116 tcp/udp

21114(443 or 80) tcp

开放 将web 使用443或者80发布

21117 tcp

建议开放,用于在p2p失败后中继

21115 tcp

建议不开放

21119 tcp

建议不开放

21118

建议不开放

使用nginx代理发布端口

非web端口nginx stream 发布·

  1. 修改nignx配置文件,设置stream模块

    stream {
        include /etc/nginx/stream.d/*;
    }
    # 注意与http模块同级别

  2. 添加stream 代理端口

​
    server {
        listen 21116;
        proxy_pass 172.30.0.2:21116;
        proxy_connect_timeout 5s;
    }
​
    # UDP端口代理(P2P打洞)
    server {
        listen 21116 udp reuseport;
        proxy_pass 172.30.0.2:21116;
        proxy_timeout 3s;
    }
​
    server {
        listen 21117;
        proxy_pass 172.30.0.2:21117;
    }
​

web端口发布

在/etc/nginx/sites-available添加新域名配置文件,vim 你的域名

server {
​
    listen 80;
    server_name test.blog360.sbs;
    #    return 404; # managed by Certbot
​
     location / {
                client_max_body_size 50m;
                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_pass http://172.30.0.2:21114/; #后端 真实服务器
     
                index index.html index.htm A1-index.html;
​
  }
​
​
}

建立软连接

ln -s /etc/nginx/sites-available/你的域名 /etc/nginx/sites-enabled/你的域名

web端口申请免费证书(ssl证书可选)

安装Certbot工具

# Ubuntu/Debian
sudo apt update
sudo apt install certbot python3-certbot-nginx
​
# CentOS/RHEL
sudo yum install epel-release
sudo yum install certbot python3-certbot-nginx

申请ssl证书(nginx)

sudo certbot --nginx -d your-domain.com
  • 替换 your-domain.com 为你的域名

总结

1. 注意stream 与http同级。

2.发布尽量使用标准端口,若rustdesk-web-API-server使用非标端口注意启动容器配置

RustDesk 使用教程

RustDesk 开源社区版本使用

  1. 打开设置

  2. 配置网络

  3. 配置对应的id,中继服务器和key

    key的配置在

    1.服务器docker logs -f 容器id日志中查看

    2在服务器安装,目录查看一个为 id_ed------.pub文件

    完成配置后,回到主页,显示就绪即可正常使用

pro版本或者rustdesk-web-API-server版本

swagger使用

在配置启用swagger后,打开

  1. 后台文档 /admin/swagger/index.html

  2. PC端文档 /swagger/index.html

即可进入对应swagger文档

用户初始化

未开放注册,若用户初始用户过多,可以通过调用api方式添加用户,这里提供一个Java 同步启用微信用户的方法

/**
 * @program: fd-system
 * @description:
 * @author: Mr.ChangHao
 * @create: 2025-07-09 11:33
 **/
​
import cn.hutool.http.HttpRequest;
import cn.hutool.http.HttpResponse;
import cn.hutool.json.JSONArray;
import cn.hutool.json.JSONObject;
import cn.hutool.json.JSONUtil;
​
import java.util.HashMap;
import java.util.Map;
​
public class WeComUserSync {
​
    // 企业微信API参数(需替换实际值)
    public static final String QY_HOST = "企业微信url路径";
    public static final String QY_CORP_ID = "企业id";
    public static final String QY_CORP_SECRET = "企业微信密钥";
​
    public static final String RUST_DESK_HOST = "http://192.168.73.129:21114/api";
    public static final String RUST_DESK_TOKEN = "430b712ba7ef99da742c9c15bc5ae4c0";
​
​
    public static void syncUsers() {
        String weComAccessToken = getWeComAccessToken();
        // 1. 获取企业微信所有用户
        JSONArray wecomUsers = getWeComUsers(weComAccessToken);
​
        // 2. 转换数据并调用创建接口
        for (Object user : wecomUsers) {
            JSONObject wecomUser = (JSONObject) user;
            JSONObject targetUser = convertToTargetFormat(wecomUser);
            createUser(targetUser);
        }
    }
​
    public static String getWeComAccessToken() {
        // 构建请求参数
        Map<String, Object> params = new HashMap<>();
        params.put("corpid", QY_CORP_ID);
        params.put("corpsecret", QY_CORP_SECRET);
​
        // 发送GET请求
        HttpResponse response = HttpRequest.get(QY_HOST +"/cgi-bin/gettoken")
                .form(params)
                .execute();
​
        // 解析响应
        JSONObject result = JSONUtil.parseObj(response.body());
​
        // 检查错误码
        if (result.getInt("errcode") != 0) {
            throw new RuntimeException("获取access_token失败: " + result.getStr("errmsg"));
        }
​
        return result.getStr("access_token");
    }
​
​
    public static JSONArray getWeComUsers(String weComAccessToken) {
​
        String departmentId = "1"; // 根部门ID 注意权限范围
        String fetchChild = "1";   // 递归获取子部门
​
        // 构建请求URL
        String url = String.format(QY_HOST +"/cgi-bin/user/list?access_token=%s&department_id=%s&fetch_child=%s",
                weComAccessToken, departmentId, fetchChild);
​
​
        // 发送GET请求
        HttpResponse response = HttpRequest.get(url).execute();
        String body = response.body();
        JSONObject result = JSONUtil.parseObj(body);
​
        // 检查响应状态
        if (result.getInt("errcode") != 0) {
            throw new RuntimeException("企业微信API调用失败: " + result.getStr("errmsg"));
        }
​
        return result.getJSONArray("userlist");
    }
​
    public static JSONObject convertToTargetFormat(JSONObject wecomUser) {
        // 企业微信字段到目标字段的映射
        Map<String, Object> map = new HashMap<>();
        map.put("group_id", 2);                             // 默认分组ID
        map.put("is_admin", false);             // 管理员标识
        map.put("nickname", wecomUser.getStr("name"));       // 昵称
        map.put("status", 1); // 状态转换
        map.put("username", wecomUser.getStr("userid"));     // 用户名
​
        return JSONUtil.parseObj(map);
    }
​
​
    public static void createUser(JSONObject userData) {
​
​
        HttpResponse response = HttpRequest.post(RUST_DESK_HOST +"/admin/user/create")
                .body(userData.toString())   // JSON请求体
                .header("api-token", RUST_DESK_TOKEN)
                .contentType("application/json")
                .execute();
​
        // 检查响应状态(根据实际接口规范调整)
        if (response.getStatus() != 200) {
            System.out.println("用户创建失败: HTTP " + response.getStatus());
        }
​
        JSONObject result = JSONUtil.parseObj(response.body());
        System.out.println("添加响应结果:"+result);
    }
​
​
    public static void updateAllUsersPassword() {
        int page = 1;
        int pageSize = 100; // 每页大小,可根据实际情况调整
        int totalPages = 1; // 初始值,会在循环中更新
​
        while (page <= totalPages) {
            // 1. 分页获取用户
            JSONObject userListResponse = getUserList(page, pageSize);
​
            // 检查响应是否成功
            if (userListResponse == null || userListResponse.getInt("code") != 0) {
                System.err.println("获取用户列表失败,页码: " + page);
                page++;
                continue;
            }
​
            JSONObject data = userListResponse.getJSONObject("data");
            JSONArray users = data.getJSONArray("list");
​
            // 更新总页数
            totalPages = (int) Math.ceil((double) data.getInt("total") / pageSize);
​
            // 2. 遍历用户并更新密码
            for (Object userObj : users) {
                JSONObject user = (JSONObject) userObj;
                updateUserPassword(user);
            }
​
            page++;
        }
    }
​
    public  static JSONObject getUserList(int page, int pageSize) {
        String url = RUST_DESK_HOST + "/admin/user/list"; // 假设用户列表接口路径是基础URL
​
        try {
            HttpResponse response = HttpRequest.get(url)
                    .header("api-token", RUST_DESK_TOKEN)
                    .form("page", page)
                    .form("page_size", pageSize)
                    .execute();
​
            String body = response.body();
​
            return JSONUtil.parseObj(body);
        } catch (Exception e) {
            System.err.println("获取用户列表异常: " + e.getMessage());
            return null;
        }
    }
​
    public static void updateUserPassword(JSONObject user) {
        int userId = user.getInt("id");
        String username = user.getStr("username");
        String newPassword = username + "!@#123"; // 生成密码
​
        String url = RUST_DESK_HOST + "/admin/user/changePwd"; // 假设修改密码接口路径
​
        try {
            if (userId >1) {
                JSONObject requestBody = new JSONObject();
                requestBody.set("id", userId);
                requestBody.set("password", newPassword);
​
                HttpResponse response = HttpRequest.post(url)
                        .body(requestBody.toString())
                        .header("api-token", RUST_DESK_TOKEN)
                        .contentType("application/json")
                        .execute();
​
                JSONObject result = JSONUtil.parseObj(response.body());
​
                if (result.getInt("code") == 0) {
                    System.out.println("用户密码更新成功: " + username);
                } else {
                    System.err.println("用户密码更新失败: " + username +
                            " | 错误信息: " + result.getStr("message"));
                }
            }
        } catch (Exception e) {
            System.err.println("更新密码异常: " + username + " | " + e.getMessage());
        }
    }
​
    public static void main(String[] args) {
//        syncUsers(); 同步企业微信用户
        updateAllUsersPassword(); //批量初始化用户密码
    }
}

Oauth2接入(GitHub)演示

添加对应Oauth2配置

  • 对于GoogleGithub, IssuerScopes不需要填写.

  • 对于OIDC, Issuer是必须的。Scopes是可选的,默认为 openid,profile,email. 确保可以获取 sub,emailpreferred_username

  • github oauth appSettings->Developer settings->OAuth Apps->New OAuth App 中创建,地址 https://github.com/settings/developers callback URL 填写{uri}/api/oauth/callback

  • Authorization callback URL填写http:///api/oidc/callback ,比如http://127.0.0.1:21114/api/oidc/callback

前往GitHub oauth app配置 https://github.com/settings/developers

rustdesk 页面配置

这样是存在bug

我们直接调用api添加该字段也不行,这个bug应该是由于使用sqlite会出现,mysql正常

curl --location --request POST 'http://192.168.73.129:21114/api/admin/oauth/create' \
--header 'api-token: 60aca81100daccf883c66f32b45d7b72' \
--header 'Content-Type: application/json' \
--data '{
    "id": 0,
    "op": "",
    "oauth_type": "github",
    "issuer": "",
    "client_id": "2221",
    "client_secret": "1123",
    "redirect_url": "",
    "scopes": "",
    "auto_register": true,
    "pkce_enable": false,
    "pkce_method": "S256"
}'

完成后页面展示

第三方接入与OIDC 接入

根据up主的查阅OIDC 算比较前沿的,国内支持厂商并不多,好像企业微信在23年已经内测了,如果内部业务系统支持可以对接,或者查询所使用的系统看有没有对接的可能,或者直接简单开发对接api实现自定义Oauth2登录

其他权限管理

这里的话各位小伙伴可以自行探索,根据自己的需求来使用地址簿、标签、分组等等


Comment