RustDesk 部署在家庭 NAS 上:IPv6 + DDNS 零成本公网远程

前言

之前写过一篇 RustDesk 自建的通用指南,Docker 一条命令部署,没什么难度。

但那篇有个隐含前提:你有台有公网 IP 的云服务器。随便买台腾讯云轻量也得几十块一个月,虽然不贵,但如果你家宽带本身就有公网 IPv6—— 为什么还要多花这笔钱?

事情是这样的。我想从公司电脑远程连家里的几台机器,Win/Mac/Linux 都有,单一个 ToDesk 虽然顺手但免费版有设备数限制,而且数据走第三方服务器始终不太舒服。

手头刚好有台飞牛 NAS,7×24 小时开机,Docker 随手可用。家里宽带是移动的,有公网 IPv6,DDNS 也早就配好了。等于基础全齐,缺的只是把 RustDesk 服务端扔上去、串起来。

为什么用 IPv6 而不是买 VPS

先算一笔账:

VPS 方案IPv6 方案
月费≥30 元0
带宽受限(轻量 3-5Mbps)宽带上行(通常 30-100Mbps)
延迟VPS 位置决定走自家宽带,P2P 后基本局域网延迟
维护要管一台云服务器NAS 本来就开着

当然前提是你家宽带确实有公网 IPv6。现在三大运营商家宽基本都给了,光猫改桥接、路由器拨号就能拿到。如果你还不确定,打开 test-ipv6.com 看一眼就知道了。

网络拓扑

整个链路的走向:

rdv6.example.com (DDNS → AAAA 记录)
路由器公网 IPv6
┌───端口转发───┐
│ 21116 TCP+UDP │
│ 21115 TCP │
│ 21117 TCP │
└──────┬────────┘
飞牛 NAS (<NAS_IP>)
┌──────────────────┐
│ Docker Compose │
│ ├─ hbbs (host) │
│ └─ hbbr (host) │
1 collapsed line
└──────────────────┘

一层一层来。

第一层:NAS 上跑 Docker Compose

RustDesk 服务端就两个组件:hbbs(ID 服务器)和 hbbr(中继服务器)。用 Docker Compose 一把起:

services:
hbbs:
container_name: hbbs
image: rustdesk/rustdesk-server:latest
command: hbbs
volumes:
- ./data:/root
network_mode: "host"
depends_on:
- hbbr
restart: unless-stopped
hbbr:
container_name: hbbr
image: rustdesk/rustdesk-server:latest
5 collapsed lines
command: hbbr
volumes:
- ./data:/root
network_mode: "host"
restart: unless-stopped
Terminal window
docker compose up -d

启动后拿 Key:

Terminal window
docker logs hbbs | grep Key
# Key: <YOUR_RUSTDESK_KEY>

这串 Key 是服务端的公钥,客户端必须填对才能跟你的服务器注册。

第二层:路由器 IPv6 端口转发

RustDesk 需要三个端口:

端口协议用途
21115TCPNAT 类型检测
21116TCP + UDPID 注册、心跳、打洞
21117TCP中继转发

注意:21116 必须同时开 TCP 和 UDP。这是踩坑最多的地方 —— 只开 TCP 会导致设备能注册但 P2P 打洞永远失败,每次都走中继。

在路由器上,把这三个端口转发到 NAS 的内网 IP(<NAS_IP>)。不是 IPv4 的端口映射,是 IPv6 防火墙规则里放行入站流量。具体操作取决于你的路由器固件:

  • OpenWrt:网络 → 防火墙 → 通信规则 → 新建,目标选 NAS 的 IPv6 地址
  • 原厂固件(小米/TP-Link):安全设置 → IPv6 防火墙 → 添加规则
  • 飞牛自带防火墙:系统设置 → 防火墙 → 放行端口

第三层:DDNS 绑定域名

IPv6 地址是动态的,运营商隔段时间可能给你换一个。所以需要一个 DDNS 服务,定期检测 IPv6 变化并更新 DNS 记录。

我用的工具是 DDNS - GO(跑在 NAS 上),填好域名服务商的 API Key 之后,每 5 分钟自动向 DNS 推送一条 AAAA 记录。飞牛 NAS 的 IPv6 地址变了,域名最多 5 分钟就跟上。

核心配置项:

DNS 服务商:阿里云 / Cloudflare / DNSPod
IPv4:不启用
IPv6:通过接口获取(选 NAS 的网卡)
域名:rdv6.example.com

配好之后 dig AAAA rdv6.example.com 应该返回你的路由器 IPv6 地址。

客户端配置

所有设备装好 RustDesk 客户端(GitHub Releases ),进设置 → 网络:

ID 服务器: rdv6.example.com ← 注意:不要加端口!
中继服务器: rdv6.example.com
Key: xxxxxxxxxxx(上面 docker logs 拿到的那串)

重点:不要加端口号。

为什么加了端口反而不行

这是本次部署最大的教训。

当你填 rdv6.example.com(不写端口)时,RustDesk 内部有一张默认端口表:

hbbs (ID 服务器)
→ UDP 21116 ID 注册 + 心跳
→ TCP 21115 NAT 类型检测
→ TCP 21116 TCP 打洞连接
hbbr (中继服务器)
→ TCP 21117 流量中继

客户端会根据自己的需求,自动去对应的端口。

但一旦你写了 rdv6.example.com:21116,RustDesk 可能以为你用的是非标端口部署,就把 ID 服务器的所有通信全往 21116 怼 —— 包括 NAT 类型检测本该走 21115 的流量。hbbs 在 21116 上只处理注册和打洞,不处理 NAT 检测,握手阶段直接挂了。

所以记住这条规则:

不改默认端口的情况下,填域名就够了,别画蛇添足加端口。 只有你真的改过服务端监听端口时,才需要在客户端手动指定。

第一台设备配好后,点「复制配置信息」,生成一段字符串,其他设备「导入配置」粘贴进去 —— 不用每台都手填。

验证

客户端设置页底部显示「就绪」就是通了。

两台设备都注册到服务器之后,在控制端输入被控端的 ID,连接。如果两台在同一局域网或都有 IPv6,大概率走 P2P 直连,延迟跟内网几乎没区别。打洞失败的极端情况才会走中继。

你可以用 docker logs hbbs 看连接日志,确认是 P2P 还是 relay。

总结

这个方案折腾完之后的感受是:一旦 IPv6 + DDNS 的基础有了,自建任何服务都是零边际成本。

RustDesk 服务端跑在 NAS 上,跟 Docker 里的其他容器同居,不吃多少资源。客户端配一次就忘,之后所有设备无论内网外网、Win 还是 Mac,全通过同一个域名互相连通。P2P 优先、中继兜底,不依赖任何商业服务。

如果你家宽带也有 IPv6、也有一台 NAS 或者随便一台常年开机的 Linux 机器 —— 按上面的步骤,二十分钟搞定。