0
0

突破公网瓶颈:基于 Tailscale 构建“赛博虫洞”,实现 RustDesk 原画级直连

2026-07-12
2026-07-12
突破公网瓶颈:基于 Tailscale 构建“赛博虫洞”,实现 RustDesk 原画级直连

在日常远程开发和运维场景中,我遇到了一个很现实的痛点:当我跨公网访问一台无头的被控主机时,明明主机硬件性能很强,显卡硬件编码也完全够用,但由于复杂的 NAT、运营商网络和防火墙限制,RustDesk 这类远程桌面工具往往无法成功完成 P2P 打洞。

一旦 P2P 失败,数据流就会被迫走云端中继服务器。对于国内用户来说,这通常意味着两个问题:

  • 延迟明显升高;
  • 画面码率被中继带宽限制,原本清晰的桌面被压成马赛克。

image-oCCs.png

(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:

  1. 被控主机上安装 Tailscale 并登录。
  2. 主控主机上安装 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 的显示设置中进行进一步调优:

  • 编解码器:优先选择 H265AV1
  • 画质 / 码率:根据带宽适当拉高;
  • 帧率:可设置为 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 类型。

如果服务器本机还启用了 ufwfirewalld 或宝塔/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 -> 被控

对于远程开发、无头工作站、异地运维和高画质远程桌面来说,这套组合非常实用。它不一定能突破物理带宽上限,但可以最大限度减少中继绕路,把网络路径控制在自己手里。

评论