一、为什么非得自建
远程桌面是单人工作者的刚需:在外地连回家里或公司的电脑,取个文件、跑个脚本、看一眼跑挂的服务。向日葵、ToDesk 这类商业产品用着顺手,但代价是持续的订阅费,以及你的画面要经第三方服务器中转。对单人、低频、又有点隐私洁癖的使用者来说,这笔账不划算。
我手头正好有一台带公网 IP 的轻量云服务器,常年跑着别的业务。既然有公网入口,最自然的想法就是:把「牵线 + 中继」这一层搬到自己的服务器上,客户端之间直接连,商业软件的那份月费和下撤风险就都不复存在了。
当时我第一个念头其实是:这玩意儿我一个非网工能搞定吗?答案是——比想象中简单,但有几个坑专门等着第一次做的人。下面把我从「怀疑」到「跑通」的完整过程记下来,包括那些卡了我半天的疑问。
本文结论
单人远程桌面,RustDesk 自建是目前最省心、最省钱、功能最全的开源方案。部署半小时,之后零成本、零隐私外泄。真正耗时间的是几个「第一次才会踩」的坑,和一堆「它到底怎么工作的」疑问——这篇就是为后者写的。
二、选型:RustDesk 还是 Tailscale
能自己掌控的路线其实有两条:
| 方案 | 优点 | 代价 |
|---|---|---|
| RustDesk 自建 | 功能最全:远程操控、文件传输、远程终端、剪贴板同步,几乎就是向日葵的开源翻版 | 要部署容器、开放端口、设密钥 |
| Tailscale + 系统自带远程桌面 | 零新增端口、单人免费且设备不限,最省心 | 体验依赖系统 RDP/VNC,缺文件/终端一体化 |
我选了 RustDesk。原因很简单:要的是「像向日葵那样一体化」的体验,而不是「能连上就行」。文件拖拽、远程终端、多显示器这些,RustDesk 原生就有,Tailscale 得自己拼。
我当初的疑问:开源的能像向日葵那样操作远程电脑吗?实测之后可以——键鼠、多显示器、文件传输、远程终端、剪贴板同步一个不少,被控端还能开机自启后台静默跑。唯一的差别是:它没有网页控制台和多用户管理(那是付费 Pro 的功能),但单人根本用不上。
三、部署:两个容器加五端口
RustDesk 的服务端叫 hbbs(负责信令 / ID 分配)和 hbbr(负责中继)。用 Docker Compose 一行命令就起来,走 host 网络,容器直接监听宿主机端口。需要放行的端口是:
# 服务端需开放 TCP 21115, 21116, 21117, 21118, 21119 UDP 21116
其中 21116 既是 TCP 也是 UDP,是核心端口(UDP 负责 NAT 打洞,决定能否 P2P 直连)。容器第一次启动会生成一对密钥,那串公钥就是客户端接入的「钥匙」,每个客户端都要填同样的地址和这串 Key。
这里有个容易忽略的点:防火墙是两层,缺一不可。服务器本机的 firewalld 要放行,云平台的防火墙也要放行。我这台恰好是阿里云「轻量应用服务器」,放行入口在页面顶部的「防火墙」标签,不是 ECS 那套安全组——第一次找错地方,折腾了好一会。
四、三个卡了我半天的坑
部署本身十分钟,真正耗时间的是这三个坑,几乎每个第一次做的人都会踩:
轻量应用服务器的「防火墙」里,TCP 五个端口用区间 21115/21119 一条搞定;但 UDP 只有一个端口,不能写成 21116/21116(首尾相等会被判「端口范围不合法」)。直接填单个数字 21116 即可。这个报错提示特别不直观,纯靠试。
下载安装后,客户端默认挂在 RustDesk 官方公共服务器上。必须在「设置 → 网络 → ID/中继服务器」里填你自己的服务器地址和那串 Key,然后完全退出(⌘Q)重开,它才会切到你的服务器。切成功的信号是:主界面底栏那句「建议自建服务器」的提示消失。我一开始没填 Key,结果 ID 一直注册不进自己的服务器。
开源版的「使用 WebSocket」开关必须关(我们用的是 OSS 服务器,不支持,开了反而连不上);「禁用 UDP」也别开——开了会强制全部走中继,延迟直接翻倍。另外被控端若是 macOS,第一次要授权「屏幕录制 / 辅助功能 / 输入监控」三项,否则连上没画面也动不了鼠标。
五、连上之后,我的疑问
跑通那一刻挺爽,但连上之后反而冒出一堆「它到底怎么工作的」疑问。这些才是这篇随笔最想记下来的东西。
P2P 不是两台电脑直连吗?那还要服务器干嘛?
这是我最开始的误解。我的理解是 P2P = 两台电脑直接连,那服务器岂不多余?后来才搞明白:「直连」说的是数据通路,「需要服务器」说的是找到彼此并打通 NAT。
你两台设备都在家里路由器后面,没有固定公网 IP,今天拨号拿到的地址明天就变。没有服务器,你光知道对方 ID,根本不知道它现在 IP 是多少。所以服务器干三件事:
| 服务器职责 | 干嘛用的 |
|---|---|
| 注册(hbbs) | 像实时通讯录,记住「这个 ID 此刻在哪台机器、哪个端口」 |
| 信令 / 打洞 | 把对方的公网地址发给彼此,并协调两边同时发包,在 NAT 上凿出临时通道——这步必须有中立第三方 |
| 兜底中继(hbbr) | 遇到打不穿的严格 NAT,数据绕道服务器转发,保证连得上 |
关键分界:上面这些始终走服务器;只有打洞成功之后,画面数据才端到端直连、彻底绕过服务器。所以你连 autumn 时延迟 35ms,是因为数据根本没经过服务器,它只是个「介绍人」。这也正好解释为什么自建——介绍人和兜底中转都在自己机器上,隐私彻底攥在自己手里。
延迟到底怎么样?
我实测了 Mac 到服务器的 RTT 约 41ms,但这不代表远程桌面的延迟。桌面延迟取决于控制端 ↔ 被控端这条链路,不是到服务器的链路:
| 场景 | 预计延迟 | 说明 |
|---|---|---|
| P2P 直连(同运营商打洞成功) | 10–50 ms | 数据两台设备直传,服务器只管牵线;国内基本都能直连,和向日葵一个水平 |
| 中继回退(打洞失败才走) | ~80–120 ms | 两段 RTT 叠加,明显变卡但仍可用 |
RustDesk 自己会先试 P2P、失败再走中继,不用手动切。实测两块设备都在国内时,体感就是 35ms 上下,相当顺。
FPS 能高点吗?画面为啥不是全屏?
两个小疑问一起答。RustDesk 的 FPS 是自适应的——画面静止时它只发变化帧,所以静止桌面看到 29 FPS 不代表上限。想拉高:连接后点顶部工具栏「显示 → 画质 → 自定义」,帧率滑块直接拉到 60,再把硬件编码打开。代价是带宽和编码负载上升,但 P2P 直连扛得住。
至于「画面跟着鼠标动、不是全屏」:那是默认的滚动/平移模式,远程分辨率比窗口大就靠鼠标挪着看。解决办法是工具栏里把视图改成「适应窗口大小」铺满,或点系统绿点真正全屏;嫌模糊就把图像质量调高。
我之前用 GitHub 登录的账户,切到自建后怎么没了?
这个疑问也挺让人慌。结论是:正常现象,不用管。RustDesk 的账户体系(GitHub/Google 登录、通讯录、设备云同步)依赖的是官方 API 服务器 + 网页控制台,那套东西只在官方公共服务器或付费 Pro 上才有。开源自建版根本没有账户系统,所以切过来显示「未登录」是必然的。
而且单人使用根本不需要它——账户带来的是跨设备通讯录、云端设备列表这类团队功能。连接靠的是「ID + 访问密码 + 密钥」三件套,和账户零关系。直接把弹窗关掉即可,不影响任何功能。
折腾完最大的体会:自建的本质不是「省钱」,而是把控制权收回来——连得上连不上、卡不卡、数据去哪,规则由你定。而真正难的从来不是部署命令,是搞懂「它为什么这么设计」。
六、一句话总结
如果你只是单人、偶尔连一下自己的电脑,RustDesk 自建是用一顿饭的时间,换掉一份持续订阅和一份隐私外包。服务器我本来就有,算下来这笔远程桌面的边际成本就是零。数据握在自己手里,这种踏实感,是商业软件给不了的。
当然也有代价:它多开了几个公网端口,和现有业务共跑一台机器。如果哪天想把暴露面收干净,最干净的做法是把 RustDesk 挪到一台闲置小机器或 NAS 上——但对单人低频使用来说,现在这样就挺好。
返回随笔