为什么选择自建 RustDesk?
在远程控制需求日益增长的当下,商业远程桌面软件往往伴随着画质压缩、带宽限速或连接配额限制。RustDesk 是一款优秀的开源远程桌面替代方案。通过自建 ID 与中继服务器,不仅能将控制权与数据隐私完全掌握在自己手中,还能充分利用自家的公网带宽与 IPv6 直连优势,实现超低延迟的流畅体验。
GitHub地址:https://github.com/rustdesk/rustdesk
本文基于 Docker 环境,完整记录从服务端部署、路由器端口映射、路由冲突排查、无头(Headless)虚拟机显示驱动配置到性能优化的全套落地实操。
一、Docker Compose 服务端部署
推荐使用 host 网络模式部署 RustDesk 服务端,避免 Docker 虚拟网桥带来的 NAT 损耗,使服务端能直接捕获客户端的真实源 IP。
1. 编写配置文件
创建 docker-compose.yml 文件:
YAML
version: '3'
services:
hbbs:
container_name: rustdesk-hbbs
image: rustdesk/rustdesk-server:latest
# 替换 yourdomain.com 为实际绑定的 DDNS 域名或公网 IP
command: hbbs -r yourdomain.com:21117 -k _
volumes:
- rustdesk-data:/root
network_mode: "host"
depends_on:
- hbbr
restart: unless-stopped
hbbr:
container_name: rustdesk-hbbr
image: rustdesk/rustdesk-server:latest
command: hbbr -k _
volumes:
- rustdesk-data:/root
network_mode: "host"
restart: unless-stopped
volumes:
rustdesk-data:
2. 参数解析与安全建议
-r yourdomain.com:21117:指定中继服务器地址及端口。-k _:强制启用 Key 公钥验证机制。未填写正确公钥的外来客户端将无法借用你的服务端,杜绝被公网扫描盗用流量。- 避免强制中继:切勿在环境变量中添加
ALWAYS_USE_RELAY=Y,否则会阻断客户端间的 P2P 直连(UDP 打洞及 IPv6 直连),导致不必要的转发延迟与卡顿。
3. 启动并获取公钥
Bash
# 启动容器
docker compose up -d
# 查看生成的公钥 Key
docker logs rustdesk-hbbs | grep "Key:"
二、OpenWrt 路由器防火墙与端口转发
为了让外网客户端正常访问内网的 RustDesk 实例,需要在主路由上放行并映射对应端口。
1. 端口映射规则汇总
| 端口范围 | 协议 | 用途说明 |
| 21115 | TCP | NAT 类型测试与握手 |
| 21116 | TCP / UDP | ID 注册、心跳与 UDP 打洞通信(核心) |
| 21117 | TCP | 中继数据转发(Relay) |
| 21118 – 21119 | TCP | 网页端 Web Client 支持(可选) |

2. OpenWrt 转发配置规范
在 OpenWrt 的 网络 -> 防火墙 -> 端口转发 中新建规则:
- 名称:
rustdesk - 协议:
TCP + UDP - 源区域:
wan - 外部端口:
21114-21119 - 目标区域:
lan - 内部 IP 地址:填写运行 Docker 的服务器内网 IP(例如
192.168.0.7) - 内部端口:直接留空(系统默认 1:1 映射)或填
21114-21119 - 高级设置:勾选 启用 NAT 环回

三、避坑实录:外网无法连接与常见故障排查
若内网连接正常但外网无法建立握手,通常由以下两类经典网络架构问题引起:
1. 双网卡同网段导致的“非对称路由”断流
在 ESXi / PVE 虚拟化环境中,如果虚拟机同时挂载了直通物理网卡和虚拟网卡,且两者处于同一子网并各自获取了默认网关:
- 故障机理:外网请求从直通网卡进入,而虚拟机内核根据路由表将回包从另一张 DHCP 网卡发出。源 IP 不一致触发了防火墙状态表校验失败(RP_Filter),连接被直接丢弃。
- 排查命令:Bash
ip route - 解决办法:清理多余的默认路由,编辑 Netplan 配置文件(
/etc/netplan/*.yaml),注释多余网卡的 DHCP 默认路由,仅保留唯一的静态网关配置后执行sudo netplan apply。
2. 启用 OpenWrt LAN 口 IP 动态伪装 (SNAT)
若内网网络拓扑较复杂,可在 OpenWrt 网络 -> 防火墙 -> 常规设置 中,找到 lan 区域并勾选 IP 动态伪装 (Masquerading)。这样路由器在转发外网请求时,会将源地址伪装为路由器的内网 IP,避开目标服务器的默认网关路由偏差。
四、无头虚拟机解决“没有显示器 (No Displays)”报错
在无物理显示器的 Windows 虚拟机或工控机中,RustDesk 提示“No Displays”是因为 Windows 原生 RDP 独占了虚拟显示通道,或者系统缺少活跃的桌面渲染输出。

1. 部署 IddSampleDriver 虚拟显示驱动
- 下载开源虚拟显示驱动源码包(如
IddSampleDriver)。 - 在
C:\根目录创建名为IddSampleDriver的文件夹,将配置文件option.txt放入其中(用于定义虚拟屏幕的分辨率列表,如1920 1080 60)。 - 右键以管理员身份运行
installCert.bat导入驱动签名证书。 - 打开 设备管理器 -> 操作 -> 添加过时硬件 -> 手动从列表选择 -> 从磁盘安装,选中
iddsampledriver.inf完成安装。
2. 强制切回物理控制台
如果之前使用了 Windows 自带远程桌面(RDP),退出前必须在管理员终端中执行以下命令交还桌面控制权,避免系统挂起:
DOS
tscon 1 /dest:console
五、低延迟与画质性能调优
针对无独立显卡硬件编码单元的虚拟机,需调整配置以获得最佳流畅度:
- 关闭被控端「启用硬件编解码」:缺少独立显卡时,强开硬编解码会引发丢帧和进程死锁;关闭后采用 CPU 软解(VP9/AV1)体验更为平稳。
- 保持「启用 UDP 打洞」与「IPv6 P2P」:允许客户端在移动 5G 与家庭宽带间建立端到端直连,避开中继转发的带宽瓶颈。
- 开启「移除桌面壁纸」:减少静态画面的冗余数据传输,降低编码负载。
- 主控端限制 30 FPS:在主控端将帧率上限设为 30 FPS 并选择“平衡”画质,可显著降低虚拟机 CPU 占用。

常见问题解答 (FAQ)
Q1:RustDesk 客户端如何实现免配置一键安装?
Windows 官方安装包支持根据文件名自动载入配置。将安装包重命名为 rustdesk-host=域名,key=公钥.exe,双击打开即自动填入服务器与公钥。
Q2:自建定制包之后,后续客户端升级会丢失服务器配置吗?
不会。RustDesk 的程序逻辑与用户配置文件相互独立。客户端的服务器与公钥信息存储在 %APPDATA%\RustDesk\config\RustDesk2.toml 中,覆盖升级新版本不会重置该文件。
Q3:为什么打开客户端后长时间显示“连接中”或提示网络错误?
请依次检查:① 域名 DDNS 是否准确解析到当前公网 IP;② 21116 端口的 UDP 协议是否在路由器上成功放行;③ 服务端 Docker 容器是否正常运行且日志无报错。