☰
树莓派自建RustDesk远程桌面服务器:从内网到外网访问完整指南
2026/9/28 3:23:47 网站建设 项目流程

前阵子把一台吃灰的树莓派4B翻出来,本来是想着拿来当下载机,结果发现远程办公的场景比下载更刚需。公司电脑、家里台式机、笔记本之间来回倒文件,试过TeamViewer、AnyDesk,要么被限速要么商业授权弹窗烦人。后来自己部署了RustDesk服务器,把这台树莓派变成了纯私有的中继节点,内网延迟只有几毫秒,外网连回家里的体验也稳了不少。这篇就聊聊从零到外网可用的完整过程,全程命令可以直接抄。

我默认你有最基础的树莓派使用经验,比如会烧录系统、会用SSH登录。下面从选型原因开始讲,因为只有理解了每个环节背后的逻辑,遇到问题时才知道往哪个方向排查。

1. 为什么选树莓派4B + RustDesk自建:延迟、隐私和成本三个维度说清楚

很多人习惯直接用云服务器装RustDesk Server,我的建议是:如果只是给自己家里或者小团队用,树莓派4B放在家里反而更合适。这不是省钱强迫症,而是有几个实打实的原因。

1.1 自建中继省掉的其实是“绕路”

RustDesk的工作逻辑是:两台设备先尝试P2P直连,如果打洞成功,数据完全不走服务器;打洞失败,才走服务器中继。你自建服务器之后,P2P成功的情况流量不经过任何第三方,中继的情况数据也只从你自家服务器过一遍。

用官方服务器时,A地设备连B地设备,信令包先跑到海外数据中心绕一圈再回来,延迟高不说,还受官方服务器负载影响。自建后,信令和中继链路完全掌握在自己手里,尤其是同一运营商网络下,时延能明显降下来。我实测下来,同城跨运营商中继延迟从官方节点的80-120ms降到20ms以内。

1.2 树莓派4B的硬件完全足够跑这套服务

RustDesk Server其实非常轻。整套服务拆开就是两个二进制进程:

  • hbbs:ID注册和信令服务器,负责设备身份登记、建立会话、打洞协调
  • hbbr:中继服务器,负责P2P失败后的数据转发

树莓派4B用的是BCM2711四核A72处理器,内存2GB/4GB/8GB版本都能跑。我手头是一台4GB版本,同时跑hbbs + hbbr + Docker + 一个文件同步脚本,内存占用大概400MB左右,CPU平时1%都不到。满载中继时CPU也基本在10%以内。功耗就更不用说了,整机加电源适配器大约5W,一年365天开机,电费不到一台云服务器一个月租。

1.3 跟TeamViewer和云服务器对比,优势在哪

我整理过一张对比表,帮当时纠结方案的时候捋清思路:

方案典型成本数据链路主要短板
TeamViewer/AnyDesk免费版免费,但限制时长或弹窗第三方服务器商用检测、连接限速、不稳定
云服务器自建RustDesk轻量服务器月租约20-50元你的云服务器流量费另算,离你物理距离远
树莓派4B自建一次性约300元,电费可忽略完全私有需要公网IP和端口映射

隐私维度很关键。RustDesk的通信是端到端加密,服务器只做信令和中继,理论上服务器管理员拿不到你的屏幕内容。但你自建服务器之后,这个“理论上”直接变成“事实上”,密钥在自己手里,数据链路在自己机器上,不需要信任任何第三方。如果做企业内部远程支持,这一点尤其重要,毕竟谁也不想让员工的远程桌面流量绕道海外。

2. 部署前的准备工作:系统镜像、固定IP、Docker环境一次配齐

部署最烦的不是执行命令,而是环境没准备好。我踩过一次系统镜像版本不对导致内核模块缺失的坑,所以这里把前置工作拆细。

2.1 系统镜像选择:官方Lite版就是最优解

树莓派官方系统(Raspberry Pi OS)Lite版本是无桌面环境的,资源占用极低,我用的就是这个。你也可以用Ubuntu Server 22.04/24.04的64位版本,两者的区别不大。选Lite版本还有个隐形好处:系统里没有桌面环境,就不会有人误打误撞打开浏览器占内存。

烧录直接用官方Raspberry Pi Imager工具,烧录前在设置里提前开启SSH服务,减少一次插屏幕接键盘的操作。烧录完成后,第一次开机建议用网线连路由器,这样系统能自动拿到IP,然后用路由器后台找到树莓派的地址,SSH进去。

ssh pi@树莓派IP

默认用户名是pi,密码是raspberry,如果你用的是Imager的定制设置,用你自己设的用户名密码。

2.2 给树莓派设置固定IP

这一步看起来很基础,但特别影响后面外网配置。如果树莓派的IP是DHCP动态分配的,路由器重启或租约过期后IP一变,端口映射就全失效了。

最稳的方式是在路由器后台的“DHCP静态分配”里,把树莓派的MAC地址绑定到一个固定IP,比如192.168.1.100。也可以在树莓派系统里配置静态IP,两者选一个就行,不建议同时配置,否则容易出冲突。

树莓派官方系统改静态IP,编辑/etc/dhcpcd.conf:

sudo nano /etc/dhcpcd.conf

在文件末尾加:

interface eth0 static ip_address=192.168.1.100/24 static routers=192.168.1.1 static domain_name_servers=192.168.1.1 223.5.5.5

保存后重启网络:

sudo systemctl restart dhcpcd

用ip addr确认IP变更为192.168.1.100。

2.3 安装Docker和docker-compose

RustDesk Server有两种跑法,一种是直接跑官方Shell脚本,一种是用Docker跑。我强烈推荐Docker,因为官方脚本会从源码编译或者从GitHub拉取二进制,耗时和出错概率都高,而Docker镜像开箱即用,升级也方便。

树莓派上安装Docker不要用官方的curl脚本,用系统自带的软件源最省心:

sudo apt update sudo apt install -y docker.io docker-compose-v2 sudo usermod -aG docker $USER

装完后重新登录SSH,让用户组权限生效。验证一下:

docker --version docker compose version

看到版本号就说明环境好了。这里有个细节:现在的docker-compose命令是docker compose(带空格),不是老的docker-compose(带横线),网上很多教程还在用横线版,在新版Docker里可能会提示找不到命令。

3. 部署RustDesk Server:我实际跑通的Docker Compose方案

3.1 为什么不直接用官方install.sh脚本

RustDesk官方提供了install.sh一键安装脚本,思路是下载预编译的hbbs和hbbr二进制文件。看起来很方便,但实际用下来有几个问题:脚本默认从GitHub拉取文件,网络波动大时容易下载失败;装完没有systemd服务管理,重启树莓派后不会自动拉起;升级时要重新跑脚本,比较折腾。

我用Docker Compose方案,把hbbs和hbbr定义成两个容器,通过host网络模式直接复用树莓派物理网卡,省去端口映射容器端口的环节。

3.2 编写docker-compose.yml

先创建工作目录:

mkdir -p ~/rustdesk-server && cd ~/rustdesk-server

创建docker-compose.yml:

nano docker-compose.yml

内容如下:

services: hbbs: image: rustdesk/rustdesk-server:latest container_name: hbbs command: hbbs -r your-server.com:21117 volumes: - ./data:/root network_mode: host restart: unless-stopped hbbr: image: rustdesk/rustdesk-server:latest container_name: hbbr command: hbbr volumes: - ./data:/root network_mode: host restart: unless-stopped

解释几个关键点:

  • command: hbbs -r your-server.com:21117这里的-r参数告诉hbbs,向客户端广播的中继服务器地址是your-server.com:21117。这一步非常关键,如果填写的地址不对,客户端即使P2P直连成功,也无法获得正确的中继地址。还没申请域名的,先填“当前树莓派的外网IP:21117”,后面配置DDNS后再改。
  • network_mode: host让容器直接使用宿主机网络,RustDesk涉及UDP打洞和多端口通信,host模式最省心,不会有NAT转换问题。
  • ./data:/root持久化密钥文件。hbbs启动后会在/root目录下生成id_ed25519和id_ed25519.pub,这是客户端接入时要填的Key,必须持久化,否则容器重建后Key变了,所有客户端要重新配置。
  • restart: unless-stopped保证树莓派重启后两个服务自动拉起,不需要手动干预。

3.3 启动并验证服务状态

docker compose up -d docker compose ps

看到两个容器状态都是Up就成功了一半。再来确认密钥文件已经生成:

ls -l data/ cat data/id_ed25519.pub

cat出来的字符串就是后面客户端要用的Key,先复制保存好。我建议顺手把私钥id_ed25519也备份一份,后面换机器迁移服务器时能省大事。

到这里,内网部署已经完成。此时你可以在局域网内打开RustDesk客户端,把ID服务器填成192.168.1.100,Key填成刚复制的公钥,应该就能连上。如果你只在家里用,到这里就够了。但要做外网访问,还差最后一截路。

4. 客户端接入与验证:让所有设备都走自己的服务器

部署完服务端,下一步就是把电脑、手机上的RustDesk客户端指向你自己的服务器。

4.1 桌面端配置流程

以Windows客户端为例,打开主界面,点击右上角菜单(三条横线),选择“设置”,切到“网络”标签页。在“ID/中继服务器”一栏里,点右侧的“解锁”按钮(防止误改),然后把局域网内测试写的192.168.1.100和Key填进去:

  • ID服务器:192.168.1.100
  • 中继服务器:留空或填192.168.1.100:21117
  • Key:刚才cat出来的那一串

填完点“应用”,状态栏应该会从“未就绪”变成“就绪”。

手机端(Android/iOS)操作类似,在“设置 -> 网络”里填同样的内容。iPhone上需要对RustDesk授权本地网络权限,否则会一直显示连接中,这个问题我周围好几个朋友都遇到过。

4.2 怎么确认流量走了自己的服务器

填完之后不要急着连,先在树莓派上看日志,确认客户端确实注册到了你的服务器上:

docker logs -f hbbs

正常会看到类似这样的记录:

[INFO] new connection from 192.168.1.50:50001 [INFO] register peer: xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx

如果看到这种输出,说明客户端成功连上了你的hbbs。之后再进行一次远程桌面连接,如果日志里有hbbr的连接记录,说明P2P直连没打通,走了中继;如果只有hbbs的信令记录,说明打洞成功,数据完全直连。

4.3 端口清单,哪些必须开

先明确一下RustDesk Server需要哪些端口,这会影响你后面的防火墙和路由器配置:

端口协议用途是否必须
21115TCPNAT类型探测推荐打开
21116TCP客户端注册、心跳必须
21116UDP打洞、P2P协商必须
21117TCP中继服务必须
21118TCPWeb客户端非必须
21119TCPWeb客户端非必须

我自己实际只放开了21115、21116和21117。如果你不需要浏览器远程,21118和21119不映射也没问题。

5. 外网访问的完整链路:端口映射、DDNS与安全加固

树莓派在家里,外面要能连上,本质上就是“让外网能访问到树莓派的特定端口”。这一步有四个环节,任何一个断了都不行。

5.1 先确认有没有公网IP

登录路由器管理页面,查看WAN口的IP地址。如果WAN口IP是公网地址(不是192.168.x.x、10.x.x.x、172.16-31.x.x这些私网段),那恭喜你,可以直接做端口映射。如果WAN口IP是私网段,说明运营商没有给你分配公网IPv4,这种环境就要想别的办法。

比较常见的替代方案:

  • 运营商下发IPv6地址:树莓派和客户端都有IPv6地址时,直接把IPv6地址填到客户端的ID服务器里,也能实现外网访问。前提是路由器、光猫和系统防火墙都要放行对应端口。
  • 用组网工具(如Tailscale、ZeroTier)把树莓派和外部设备组成一个虚拟局域网,然后直接用虚拟局域网IP访问。这种方式适合“只有自己设备访问”的场景,配置简单,不需要公网IP,但如果你要把访问权分享给朋友或同事,就不太合适。

这部分在实际部署中最容易劝退人。我自己的情况是运营商分配了动态公网IPv4,但IP会变,所以后面必须上DDNS。

5.2 光猫和路由器的端口映射

大部分家庭网络是“光猫-路由器-电脑”的结构。做端口映射时,优先在路由器上做,但也要注意光猫如果处于路由模式,会拦截转发。最彻底的方案是把光猫改成桥接模式,让路由器来拨号,这样端口映射只在路由器上做一次。光猫桥接的设置需要找运营商要超级管理员密码,不同地区不太一样,这里不展开。

路由器后台找到“端口映射”或“虚拟服务器”功能,添加如下映射规则,把公网端口转发到树莓派内网IP 192.168.1.100:

外部端口内网IP内部端口协议
21115192.168.1.10021115TCP
21116192.168.1.10021116TCP
21116192.168.1.10021116UDP
21117192.168.1.10021117TCP

保存后,从外网用公网IP:21116测一下端口通不通。Windows上可以在本机用Test-NetConnection,或者用在线端口检测工具。如果测不通,先查路由器的防火墙规则,再查树莓派自己的ufw状态。

树莓派上如果开了系统防火墙ufw,放行命令:

sudo ufw allow 21115/tcp sudo ufw allow 21116/tcp sudo ufw allow 21116/udp sudo ufw allow 21117/tcp sudo ufw reload

5.3 DDNS绑定域名,解决动态IP问题

动态公网IP意味着今天可能是100.64.1.10,明天变成100.64.1.15。手动查IP再填到客户端里,太原始。用DDNS把一个域名动态绑定到你当前的IP上,一劳永逸。

DDNS有三种实现路径:

  1. 路由器自带DDNS功能:多数路由器支持Dyndns、花生壳、阿里云域名等,直接在路由器后台填账号密码就完事。
  2. 树莓派上跑inadyn:如果你的路由器不支持特定服务商,可以在树莓派上装inadyn:
sudo apt install inadyn

配置示例(以DuckDNS为例):

sudo nano /etc/inadyn.conf
provider duckdns { username = "你的token" password = "no-password-needed" hostname = "你的域名.duckdns.org" ddns-server = "www.duckdns.org" ddns-path = "/update?domains=mydomain&token=xxx&ip=" update-period = 600 }
  1. 利用域名服务商(如Cloudflare)的API,在定时任务里更新DNS记录。这个适合已注册自有域名、希望完全掌控解析的人。

配置好DDNS后,用ping 你的域名确认解析到的IP就是当前公网IP,再把RustDesk服务端命令里的-r参数从IP改成域名:

command: hbbs -r your-server.com:21117

然后:

docker compose up -d

客户端那边清除旧的ID服务器,重新填域名即可。

5.4 安全加固:改端口、最小化暴露、管好Key

RustDesk默认端口是公开规律,公网扫描器经常扫这些端口。如果直接把默认端口暴露在公网,一天下来防火墙日志里全是尝试连接的记录。我建议做三层加固。

第一,改默认端口。在docker-compose.yml里把端口换成不常用的高位端口。hbbs的监听端口用-p指定,中继端口hbbr也用-p指定,例如:

services: hbbs: command: hbbs -r your-server.com:22117 -p 22116 hbbr: command: hbbr -p 22117

对应的路由器端口映射也要全部改用22115、22116、22117。客户端ID服务器填your-server.com:22116,Key不变。

第二,只做必要的最小化映射。前面表格里我说过,21115只是NAT探测,21118/21119只给Web端用,如果你不用这些功能,就不要映射。少暴露一个端口,就少一份被扫描的风险。

第三,管好Key。RustDesk客户端接入需要填入id_ed25519.pub的公钥,这个Key就是你的门禁。不要把它贴在公共频道或发给不相干的人。万一Key泄露,重装服务端重新生成密钥并重置客户端,比换端口更有效。

6. 踩坑记录:我部署过程中遇到过的五个问题及解决过程

这个部分是我最想写的,因为我在部署过程中几乎把能踩的坑都踩了一遍。下面按排查链路整理,你照着顺序查就能省下半天时间。

6.1 客户端一直“连接中”,日志显示Failed to connect to rendezvous server

现象:内网都连不上,hbbs日志不断报失败。最终定位到树莓派系统防火墙ufw默认阻止了21116端口。当时我还没执行ufw放行命令,以为局域网内访问不需要防火墙,实际上一旦ufw enable,入站规则就会拦截所有非白名单端口。

排查思路:先在树莓派本机用ss -lunp | grep 21116确认hbbs在监听,再用curl或nc从另一台内网机器测端口:

nc -vz 192.168.1.100 21116

如果超时,八成是防火墙问题。ufw status查看规则,放行端口后再测。

6.2 内网通,外网连不上,但外网端口检测显示已开放

现象:用在线工具检测21116/21117端口,显示已经开放,但手机端用4G网络无法连接。

这个坑非常隐蔽:运营商分配的“公网IP”并不是真正的公网IP,家庭宽带很多时候分配的是100.64.0.0/10段地址(CGNAT),表面看IP不是192.168开头,但实际上你仍然处于运营商的内部网络。在线端口检测工具检测的是你的出口IP,检测结果看起来通,但实际上数据包根本到达不了树莓派。

解决方式:换一个方式验证真实公网属性。在路由器后台把WAN口IP抄下来,用手机流量ping一下这个IP,能通才有戏。如果是100.64.x.x,基本可以确定是CGNAT,只能找运营商开公网IPv4,或者走IPv6、组网工具方案。

6.3 外网能连上但特别卡,画面一直转圈

现象:外网远程桌面能连,但操作延迟高达1-2秒,画质模糊。

查了半天,最后发现是路由器端口映射里漏了UDP 21116,只映射了TCP。RustDesk的打洞协商依赖UDP 21116,UDP端口不通时,客户端直接放弃P2P直连,所有流量全部走TCP中继。中继转发本身有损耗,跨运营商网络后延迟就堆上去了。

把UDP 21116也映射到树莓派后,连接质量立即好转。这个案例说明,端口映射协议类型一定要跟服务端对齐,TCP和UDP不是一个概念。

6.4 客户端Key报错,提示“Key不匹配”

现象:换了台电脑在新客户端填了ID服务器,但状态一直显示未连接,或者连接时提示Key错误。

我排查后发现是自己复制失误:当时从服务器上cat公钥,不小心把结尾的换行符也复制进去了,客户端粘贴时多了一个空行,导致密钥校验失败。

处理方式:把公钥内容复制到文本编辑器里,确认首尾没有空格和换行,再粘贴到客户端。另一个常见错误是复制了id_ed25519(私钥)而不是id_ed25519.pub(公钥),这两个文件都在data目录里,别搞混。

6.5 树莓派运行一段时间后远程桌面中间断连

现象:跑了一周左右,某天突然连不上,去路由器后台看,树莓派IP还是通的,但RustDesk服务挂了。重启后能恢复,但过几天又挂。

定位后发现是SD卡的问题。树莓派长时间频繁写入,低质量SD卡容易出现I/O错误,Docker容器写日志时触发文件系统异常,服务进程被卡死。我换了一张A2速度等级的工业级SD卡,并把Docker的data目录挂到一个U盘上,问题才彻底解决。

这里给长期运行用户一个补充建议:在fstab里为/home/pi/rustdesk-server/data配置noatime挂载参数,减少不必要的写入次数。RustDesk服务本身写入不频繁,主要是系统日志和Docker日志在持续写盘,定期清理日志可以延长SD卡寿命。

6.6 性能实测数据

最后分享一组我的实测数据,帮你建立一个心理预期:

场景延迟体验
内网P2P直连1-3ms完全感觉不到延迟
外网同城、P2P成功3-8ms操作基本同步
外网同城、走中继15-25ms偶尔有轻微粘滞感
外网跨省、走中继30-60ms能完成任务,但不适合看视频

如果你发现自己长时间走中继而不是P2P,可以检查客户端双方的网络类型、路由器UPnP是否开启、UDP端口是否通畅。做这一步优化,比换更贵的服务器更有效。

最后分享一个我踩了坑之后形成的习惯:把data目录下的id_ed25519和id_ed25519.pub备份到U盘或网盘。后来有一次我把树莓派换成别的型号,直接把data目录整体拷过去,新服务器起来后输入原Key,所有客户端的配置一次都不用改。如果你也准备长期跑这套服务,建议每三个月重启一次树莓派,把碎片清理一下,顺手备份密钥。先说到这儿,祝你外网访问配置一次通过。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询