自建远控中继踩坑记:从一台轻量服务器说起
用一台低配轻量服务器自建 RustDesk 中继,摆脱免费通道排队。记录从选型到上线踩过的五个坑,以及一个反直觉的调试技巧。
这是一次「想要少受点气」的折腾记录。免费远控通道排队排到怀疑人生,于是决定自己搭一个中转。
为什么要自建
用远控不算高频,但每次遇到「免费通道排队中,您是第 3 位」就很烦。市面上的免费方案要么限速、要么限时长、要么隔三差五弹广告让你升级。
而远控这件事,本质上只需要一个东西:一个能让两端找到彼此、并帮忙转发数据的中间人。这个东西的开源自建方案早就很成熟了,一台最便宜的云服务器就够。
于是手上那台只跑了个静态站点的低配轻量服务器,就顺手多接了一份活。
先把架构想清楚
自建远控中继其实只有两个组件:
| 组件 | 干什么 |
|---|---|
| ID / 打洞服务 | 设备上线后向它登记「我是谁、在哪」,由它牵线做 NAT 打洞 |
| 中继服务 | 打洞失败时的备胎,帮忙转发数据流 |
关键在于连接是有优先级的:
两端都登记 → 尝试 P2P 打洞
├── 成功 → 数据直接在两端之间跑,服务器完全不参与 ✅
└── 失败 → 回落到中继,数据绕道服务器 ⚠️
这个优先级决定了整套方案是「免费好用」还是「带宽焦虑」——后面会看到,它也是最大的坑。
端口方面是固定的四个:三个 TCP 加一个 UDP。记住「有一个 UDP」,因为这是坑一号。
坑之一:那个被漏掉的 UDP 端口
配置防火墙的时候,我很自然地加了三个 TCP 端口。然后客户端连不上。
排查了半天才想起来:登记和心跳走的是 UDP,不是 TCP。
21115 TCP → NAT 类型测试
21116 TCP → 打洞
21116 UDP → ★ 设备注册与心跳(就是这条)
21117 TCP → 中继
为什么容易漏?因为前三个都是 TCP,第四行看上去像是前三行的重复(同一个端口号 21116),很容易在复制粘贴放行规则时被顺手忽略。
症状也很有迷惑性:客户端能启动、界面正常,但一直显示「未就绪 / 离线」。因为它在等一个永远没回来的 UDP 响应。
教训:端口清单要连协议一起抄,不要只抄端口号。看到「同号不同协议」的行,单独标出来。
坑之二:连上了 ≠ 直连
这是最阴的一个坑,因为它没有任何提示。
远控通了,画面流畅,你理所当然地认为走的是 P2P 直连。但实际上:
打洞失败会静默回落到中继,不中断会话、不弹任何提示。
也就是说,「能用」和「没花我的带宽」是两件事。而小带宽服务器的中继体验是:一旦回落,所有流量都要从这台机器绕一圈,速度和流量双杀。
判断方法有几个,最省事的两个:
方法一:悬停看提示。 远控窗口顶部有个连接状态小图标,鼠标悬停会显示 Direct / P2P(直连)还是 Relay(中继)。
⚠️ 这里有个细节:只看文字,别只看颜色。不同版本的图标配色居然不一样,甚至出现过「绿色代表中继、橙色代表直连」这种反直觉的配色。信文字。
方法二:用带宽上限反推。 这招我觉得挺巧妙——
中继速度不可能超过服务器带宽。所以:
| 服务器带宽 | 中继的理论上限 |
|---|---|
| 3 Mbps | ≈ 375 KB/s |
| 5 Mbps | ≈ 625 KB/s |
于是传一个几百兆的文件看速度:只要明显超过 375 KB/s,就绝对不可能是中继,必然是直连。不需要登服务器、不需要装工具,看进度条就行。
反过来,如果速度死死贴着 375 KB/s 上不去——那就是在走中继,别怀疑网速了,就是这个原因。
教训:任何「有降级路径」的系统,都要显式确认当前走在哪条路径上。默认值不适合拿来当结论。
坑之三:「托盘唤出才能连」
这个现象很具体,也很好复现:
远控软件开着放后台一段时间,就连不上了。必须双击托盘图标把窗口唤出来,才能重新连上。
看到这个症状,基本可以直接下结论:后台服务没在跑,是图形界面在硬撑。
原理不难推:远控软件分成两部分——
| 部分 | 身份 | 行为 |
|---|---|---|
| 服务 | 系统级身份运行 | 开机自启,登录前就可用,不受窗口状态影响 |
| 图形界面 | 当前登录用户 | 窗口最小化/关闭后,会被系统当成”后台应用”节流甚至挂起 |
服务没跑的时候,连接职责就落到了图形界面进程上。而它一旦被系统节流,就停止向服务器发心跳——在别人眼里,这台机器就「离线」了。双击托盘图标把窗口唤醒,心跳恢复,于是又能连上。
判别方法只有一个,但一锤定音:
任务管理器 → 详细信息 → 找到远控进程 → 看「会话 ID」列
必须存在 SessionId = 0 的进程 ← 这才是服务进程
如果全是非 0 的值 ← 服务没跑,连接是图形界面在撑
修复要先确认服务状态和启动类型,然后补上失败自动重启策略——大多数安装默认这条是空的,意味着服务一旦被停就再也不会自己起来。
还有一个必须记住的操作禁令:
永远不要从托盘右键菜单选「退出」。
这个操作会把服务一起停掉。此后即使托盘图标还挂在那儿,服务已经没了,连接又退回给图形界面——于是又进入「放一会儿就连不上」的循环。
要收起窗口就用「关闭窗口」或最小化到托盘,不要点「退出」。
坑之四:欢迎来到「现代待机」
修完服务,本以为稳了。结果发现这台机器只支持一种睡眠模式(现代待机 / Modern Standby),连传统的 S3 都不支持。
现代待机的特点是:睡觉时网络还连着,但后台应用会被挂起。
所以「插电不睡眠」这件事必须先确认。查一下电源计划里的睡眠超时:
- 交流(插电):建议设为从不
- 直流(电池):笔记本上别盲目设成从不,那会把电池耗干 —— 更合理的做法是被控机保持插电
顺手记一个冷知识:中文系统上查服务恢复策略时,那个「重启延迟」的单位会被显示成微秒。别慌,实际是毫秒,是翻译 bug。
坑之五:别在小带宽服务器上测「高画质」
带宽是硬约束。3 Mbps 的服务器做中继,满速也就 375 KB/s,换算下来:
0.375 MB/s × 3600 s ≈ 1.32 GB/小时
一个月 200 GB 的流量包,如果全程满速中继,只够约 151 小时。
所以正确的期待是:
| 用途 | 能不能行 |
|---|---|
| 看文档、点按钮、轻度运维 | ✅ 没问题 |
| 局域网内互控 | ✅ 走内网直连,完全不吃服务器 |
| 高清视频、大文件传输 | ❌ 别指望,换网盘 |
顺带一个反直觉点:设备变多不会线性加重服务器负担。因为服务器只在打洞牵线阶段参与,直连成功后数据根本不经过它。真正会累积的是「同时有几对连接在走中继」。
顺手学会的一个调试技巧
这次还有一个意外收获,是关于「怎么摸清一个没文档的接口」。
自建过程中需要调用服务器面板的 API 来创建容器编排,但这个接口的字段名没有文档。正常做法是去翻源码或者猜,但这两样都费劲。
后来用了一个零副作用的探测方法:拿校验类接口当探针,靠报错反推字段名。
具体就是:
- 先传一个不存在的字段名。如果报错说某个字段
required,说明那个字段名是对的、只是值没给;如果报的是别的错,说明你传的这个名字被忽略了。 - 再传一个非法的枚举值。报「取值不在允许集合内」说明字段名对了,把候选值逐个试到返回成功为止。
- 全程选那种只校验不落盘的接口,不产生任何实际变更。
用这招五分钟就摸清了:内容字段叫 file 而不是 fileContent(猜 fileContent 会报「空内容」),来源字段只接受 edit 或 template。
还有一条纪律,是从这次踩坑里总结出来的:
接口返回「成功」不算数,只认实际状态。
创建编排返回了成功码,但列表里查不到——一度以为是失败。回读磁盘才发现文件早就写好了,只是那个列表接口统计口径不同(未启动的编排不列出)。
后来凡是这类操作,一律回读落盘结果:文件读出来对不对、端口是不是真在监听、进程的会话 ID 是不是 0。
「配置已就绪」和「运行时已接通」永远是两件事。
一个容易被忽略的安全问题
后来有人问我:能不能在别人的电脑上,临时远控自己家里的机器?
技术上完全可以,而且架构本身是安全的——远控会话是端到端加密的,中继服务器即使被打穿也解不开内容,它只能看到加密后的数据流。这正是自建中继最大的价值。
但风险不在中继,在那台陌生的电脑。
| 风险 | 说明 |
|---|---|
| 键盘记录器 | 你的固定密码是敲键盘输进去的。被记录 → 机器永久暴露,不只是这一次 |
| 配置残留 | 服务器地址和密钥会留在那台机器的配置文件里 |
| 被安全软件拦 | 便携版远控工具是已知的常见攻击手法,企业网、网吧的安全策略经常拦截告警——你的行为看起来就像攻击者 |
关键认知是:接入密钥保护的是「中继不被陌生人白嫖」,它并不限制谁能连你的被控端。 后者的唯一门槛就是那把永久的固定密码。
所以从陌生电脑连一次,等于把这把永久钥匙暴露一次。
比较合理的做法是:
- 首选用自己的手机——零安装、零残留、不触发告警。只看状态、点几下操作完全够用。
- 非要用电脑时,U 盘带便携版,配置写在 U 盘上,用完拔走。
- 只能装在本机时,用完立刻改掉固定密码,再清历史记录和配置目录。
- 会话里关掉剪贴板同步和文件传输,并且不要在里面输入银行或主密码——远端那台你信得过,本地这台不一定。
收尾
回头看,这套东西真正花时间的不是搭建,而是排障。而且踩的坑全都不在”网络不通”这个层面:
- 漏了一个 UDP 端口
- 一条静默降级路径
- 一个没在跑的后台服务
- 一个没注意到的睡眠模式
四个问题,看起来都像「连不上」,但根因分属防火墙、协议协商、进程模型、电源管理四个完全不同的层。
所以如果让我总结一条经验:
遇到「连不上」,先确定问题在哪一层,再动手。 端口探测能区分「防火墙没放行」(超时)和「服务没启动」(快速拒绝)——这两个症状很像,但修法完全相反。 服务类问题看进程会话 ID 是不是 0,比看服务状态更准。 而性能类问题,先确认走的是哪条路径。
以及那个反复出现的教训:任何「返回成功」都不能当作完成,要回读真实状态。
折腾完的收益是:不用再排队了,而且数据完全在自己手里。至于那台只跑静态站点的服务器——现在它一天多干两份活,看起来毫无怨言。