突破公网瓶颈:基于 Tailscale 构建“赛博虫洞”,实现 RustDesk 原画级直连
在日常远程开发和运维场景中,我遇到了一个很现实的痛点:当我跨公网访问一台无头的被控主机时,明明主机硬件性能很强,显卡硬件编码也完全够用,但由于复杂的 NAT、运营商网络和防火墙限制,RustDesk 这类远程桌面工具往往无法成功完成 P2P 打洞。
一旦 P2P 失败,数据流就会被迫走云端中继服务器。对于国内用户来说,这通常意味着两个问题:
- 延迟明显升高;
- 画面码率被中继带宽限制,原本清晰的桌面被压成马赛克。

(RustDesk 在很多网络环境下会退回中继连接)
为了解决这个问题,我们可以换一个思路:不再依赖应用层脆弱的 P2P 打洞,而是在操作系统底层铺一条加密虚拟局域网。本文将使用 Tailscale + RustDesk 搭建一条“赛博虫洞”,让异地的主控主机和被控主机尽可能实现高速直连。
一、核心原理与工具准备
本方案的核心逻辑是:让 RustDesk 不再直接面对复杂公网,而是走 Tailscale 提供的虚拟内网地址。
- Tailscale:基于 WireGuard 的虚拟组网工具。它会为每台设备分配一个固定的
100.x.x.x虚拟内网 IP,并自动尝试 NAT 穿透。 - RustDesk:开源跨平台远程桌面工具。我们利用它的“IP 直连”功能,让远程桌面流量直接走 Tailscale 隧道。
最终效果是:
主控主机 -> Tailscale 虚拟网络 -> 被控主机 -> RustDesk 直连
如果 Tailscale 能打洞成功,数据会尽可能 P2P 直连;如果打洞失败,也可以通过后文的自建 DERP 中继降低延迟。
二、搭建 Tailscale 虚拟局域网
1. 注册 Tailscale 账号
访问 Tailscale 官网,使用 GitHub、Microsoft 或其他账号注册登录。
这个账号相当于整个虚拟网络的控制面,用于管理设备、ACL 和 DERP 配置。
2. 接入主控与被控设备
分别在两台机器上安装 Tailscale:
- 在被控主机上安装 Tailscale 并登录。
- 在主控主机上安装 Tailscale,并使用同一个账号登录。
登录成功后,两台设备会自动加入同一个 Tailnet。
3. 获取 Tailscale 虚拟 IP
登录 Tailscale 后,可以在客户端菜单或 Admin Console 中看到每台机器的虚拟 IP,例如:
100.x.x.x
在主控主机上测试连通性:
ping 100.x.x.x
如果能看到稳定延迟返回,说明 Tailscale 虚拟网络已经连通。
三、联动 RustDesk,实现原画级直连
1. 开启 RustDesk IP 直连
在被控主机上打开 RustDesk:
设置 -> 安全 -> 允许 IP 直接访问
建议同时设置一个高强度固定密码,不要只依赖临时密码。
2. 使用 Tailscale IP 连接
回到主控主机,在 RustDesk 顶部连接框中输入被控主机的 Tailscale IP:
100.x.x.x
然后直接连接。
此时 RustDesk 的远程桌面流量会走 Tailscale 虚拟网络,而不是默认的公网 ID / Relay 路径。
3. 调整画质参数
如果网络质量足够好,可以在 RustDesk 的显示设置中进行进一步调优:
- 编解码器:优先选择
H265或AV1; - 画质 / 码率:根据带宽适当拉高;
- 帧率:可设置为
60 FPS; - 硬件编码:如果显卡支持,建议开启。
这样可以尽可能释放被控主机的硬件编码能力,获得更接近本地操作的体验。
四、如何判断是否真的直连?
Tailscale 提供了一个很好用的检测命令:
tailscale ping 100.x.x.x
如果返回类似:
pong from device-name (100.x.x.x) in 23ms
通常说明已经直连。
如果返回类似:
pong from device-name (100.x.x.x) via DERP(region) in 180ms
说明当前没有打洞成功,连接正在走 DERP 中继。
DERP 不一定不能用,但如果默认 DERP 节点在海外,延迟和稳定性可能会比较差。此时就可以考虑自建一个国内 DERP 节点。
补充:自建 Tailscale DERP 中继节点
在双重 NAT、公司网络、校园网、运营商限制较多的环境下,Tailscale 可能无法完成 P2P 打洞。此时它会自动切换到 DERP 中继模式。
默认 DERP 节点可能不在国内,延迟较高。我们可以使用自己的云服务器搭建一个私有 DERP 节点,让最坏情况下的中继路径也尽量短。
一、放行云服务器端口
在云服务器安全组中放行:
33445/tcp
3478/udp
其中:
33445/tcp:用于 DERP HTTPS 长连接;3478/udp:用于 STUN 探测 NAT 类型。
如果服务器本机还启用了 ufw、firewalld 或宝塔/1Panel 防火墙,也要同步放行。
二、准备自签证书
这里使用“域名 + 自签证书”的方案。
虽然证书是自签的,但 DERP Map 中会配置 InsecureForTests: true,让 Tailscale 客户端接受它。同时,HostName 会让客户端在 TLS 握手时带上正确的 SNI,避免服务端出现 missing server name 问题。
在服务器上执行:
mkdir -p ~/derp/certs
cd ~/derp
openssl req -x509 -newkey rsa:4096 -sha256 -days 3650 -nodes \
-keyout certs/derp.example.com.key \
-out certs/derp.example.com.crt \
-subj "/CN=derp.example.com" \
-addext "subjectAltName=DNS:derp.example.com"
注意把 derp.example.com 替换成你的真实 DERP 子域名。
三、使用 Docker Compose 部署 DERP
创建 docker-compose.yml:
services:
derper:
image: docker.1panel.live/fredliang/derper:latest
container_name: derper
restart: always
ports:
- "33445:443"
- "3478:3478/udp"
environment:
- DERP_DOMAIN=derp.example.com
- DERP_VERIFY_CLIENTS=false
- DERP_CERT_MODE=manual
volumes:
- ./certs:/app/certs:ro
启动:
cd ~/derp
docker compose up -d
docker logs -f derper
如果看到类似:
STUN server listening on [::]:3478
derper: serving on :443 with TLS
说明 DERP 服务已经启动。
这里要注意一个容易踩坑的点:容器内部监听的是 443,所以端口映射应为:
- "33445:443"
不要写成:
- "33445:33445"
四、配置 Tailscale DERP Map
进入 Tailscale 后台:
Admin Console -> Access Controls -> JSON editor
在最外层 JSON 中加入:
"derpMap": {
"OmitDefaultRegions": true,
"Regions": {
"900": {
"RegionID": 900,
"RegionCode": "myderp",
"RegionName": "Private China DERP",
"Nodes": [
{
"Name": "900a",
"RegionID": 900,
"HostName": "derp.example.com",
"IPv4": "203.0.113.10",
"DERPPort": 33445,
"STUNPort": 3478,
"InsecureForTests": true
}
]
}
}
}
参数说明:
HostName:用于 TLS SNI,必须和证书域名一致;IPv4:指定实际连接的服务器公网 IP;DERPPort:公网 DERP 端口;STUNPort:公网 STUN 端口;InsecureForTests:允许使用自签证书;OmitDefaultRegions:是否禁用官方 DERP 节点。
如果你只是想增加一个私有节点,而不是完全禁用官方节点,可以先把:
"OmitDefaultRegions": true
改成:
"OmitDefaultRegions": false
测试稳定后,再决定是否完全切断官方 DERP。
五、验证 DERP 是否生效
在客户端执行:
tailscale netcheck
如果配置成功,会看到类似:
Nearest DERP: Private China DERP
DERP latency:
- myderp: 10.8ms
然后测试到被控主机:
tailscale ping 100.x.x.x
如果返回类似:
pong from device-name (100.x.x.x) via DERP(myderp) in 15ms
说明私有 DERP 已经生效。
此时即使 Tailscale 没法完成 P2P 打洞,流量也会走你自己的国内中继节点,而不是绕到海外官方 DERP。
六、常见问题
1. netcheck 能看到 DERP,但 tailscale ping 超时?
这通常说明 DERP Map 已下发,但 DERP 的 TLS 服务没有真正连通。优先检查:
docker logs -f derper
以及安全组是否放行:
33445/tcp
3478/udp
2. 日志里出现 missing server name 是什么?
这是 TLS 握手时没有携带 SNI 导致的。常见原因是客户端直接用 IP 访问,服务端不知道应该使用哪张证书。
解决方式是在 DERP Map 中同时配置:
"HostName": "derp.example.com",
"IPv4": "203.0.113.10"
这样客户端实际连接 IP,但 TLS 握手时仍然会声明自己要访问 derp.example.com。
3. 为什么还要 InsecureForTests?
因为这里使用的是自签证书,不是公开 CA 签发的正式证书。InsecureForTests 的作用是告诉 Tailscale 客户端接受这个 DERP 节点的自签证书。
如果你让 DERP 独占 80/443 并成功申请正式证书,则可以不使用这个参数。
总结
这套方案分成两层:
第一层是 Tailscale + RustDesk IP 直连。如果 NAT 打洞成功,远程桌面流量可以直接走 P2P,体验最好。
第二层是 自建 DERP。如果 P2P 失败,至少可以让中继流量走自己的国内服务器,把默认海外 DERP 的高延迟降下来。
最终效果是:
能直连时:主控 -> Tailscale P2P -> 被控
不能直连时:主控 -> 自建 DERP -> 被控
对于远程开发、无头工作站、异地运维和高画质远程桌面来说,这套组合非常实用。它不一定能突破物理带宽上限,但可以最大限度减少中继绕路,把网络路径控制在自己手里。