Skip to content
Back to Blog教程

RustDesk 自托管设置 — 完整 Docker + Caddy TLS 演练

GoDesk Editorial Team8 分钟阅读
RustDesk 自托管设置 — 完整 Docker + Caddy TLS 演练

你正在尝试自托管 RustDesk,但反复被相同的阻碍卡住:NAT 与防火墙、令人困惑的服务端组件,以及是否需要在 RustDesk 自带加密之外再加一层 TLS 的疑问。本指南为技术读者提供一套完整可复现的自托管部署…

你正在尝试自托管 RustDesk,但反复被相同的阻碍卡住:NAT 与防火墙、令人困惑的服务端组件,以及是否需要在 RustDesk 自带加密之外再加一层 TLS 的疑问。本指南为技术型读者演示在单台 VPS 上的完整、可复现的 RustDesk 自托管部署 — 使用 Docker Compose 运行 hbbs/hbbr,并用 Caddy 做 TLS 终端以便客户端能在受限网络上通过 443 连接。

我们要构建的内容与原因

目标:在单台 VPS 上部署 RustDesk 的 rendezvous + relay,并通过 DNS 名称让客户端指向它。涉及的组件:

  • rustdesk server 组件(hbbs 和 hbbr)在 Docker 中运行 —— 本文在 rustdesk-server v1.2.1 镜像上测试。
  • Caddy v2(通过 Let's Encrypt 自动管理证书),在 443 提供 TLS 入口,使客户端在出口 21115 被阻断时仍能访问中继。
  • 可选的 UDP 直通或为扩展增加额外中继(在注释中说明)。

为什么要这么做?RustDesk 的协议本身对桌面会话提供端到端加密,但很多网络只允许出站 443/80。将 TLS 在 VPS 上终止(并让 Caddy 获取并自动续期证书)是一个实用方法,可以在不开放非标准端口的情况下使服务可达。如果你只需要局域网访问或通过反向隧道控制 NAT,请参阅我们的文章 remote-desktop-without-port-forwarding

先决条件与选择

撰写本文时我使用的环境:

  • 公有 VPS 上的 Ubuntu 22.04 LTS(测试用途 1 vCPU / 2 GB RAM 足够;若为多个客户端请扩展到 4+ CPU,并监控 CPU/RAM)。
  • Docker 24.x 和 Docker Compose v2(compose V2 CLI 语法)。
  • rustdesk-server Docker 镜像(本指南以 tag v1.2.1 为例)——如有较新稳定版本请调整。
  • Caddy v2.6+(Caddy 的自动 ACME 使证书续期无痛)。
  • 一个指向 VPS 公网 IP 的 DNS A 记录,如 rustdesk.example.com,并允许 80/443(Caddy 在验证阶段需要 80/443)。

何时商业托管产品更合适:如果你需要企业级 SLA、更高级的会话审计或商业支持,TeamViewer/AnyDesk 可能更合适 —— 参见 rustdesk-vs-anydesk 和我们的价格对比文章。自托管适合需要控制、降低经常性成本或避免第三方服务器的场景。

步骤 1 — 使用 Docker Compose 部署 rustdesk 服务器

在 VPS 上创建项目目录并将下面的 docker-compose.yml 放入其中。此示例将典型的 RustDesk 服务器端口暴露到宿主机。根据你的环境替换环境变量和镜像标签。

mkdir -p ~/rustdesk-server
cd ~/rustdesk-server
cat > docker-compose.yml <<'EOF'
version: '3.8'
services:
  rustdesk-server:
    image: rustdesk/rustdesk-server:1.2.1
    container_name: rustdesk-server
    restart: unless-stopped
    ports:
      - "21115:21115/tcp"   # rendezvous / TCP relay
      - "21115:21115/udp"   # optional UDP relay (if your image supports it)
      - "21116:21116/udp"   # additional UDP (some builds use multiple UDP ports)
    volumes:
      - ./data:/root/.config/rustdesk-server
    environment:
      - RUSTDESK_RELAY_IPV4=0.0.0.0
      - RUSTDESK_RELAY_PORT=21115
EOF

启动它:

docker compose up -d
# watch logs
docker compose logs -f rustdesk-server

确认容器已启动并在 21115 上监听。在你的 VPS 上运行:

ss -tuln | grep 21115

如果你使用的镜像暴露了不同端口或采用不同的配置方式,请查阅该镜像的 README。有些运维人员会手动编译 hbbs/hbbr 并使用自定义端口;请相应调整这些步骤。

步骤 2 — 使用 Caddy 在 relay 上加 TLS(443)

有两种常见的模式可以让 RustDesk 在 443 可达:

  1. 使用 Caddy 2.6+ 做 TCP TLS 终止(Caddy 终止 TLS 并将原始 TCP 转发到 rustdesk relay)。Caddy 在 v2.6 中增强了对 TCP 的支持;采用该方法可以获得自动 ACME 证书及续期。
  2. 让 Caddy 只管理证书,然后使用一个 TCP 代理(stunnel、HAProxy 或 Nginx stream)来消费这些证书文件。这是当你的 Caddy 版本或运行环境不支持所需 TCP 代理特性时的备选方案。

下面是一个最小且务实的 Caddy 配置示例,使用 Caddy 在 443 做 TLS,并将原始 TCP 连接转发到本地的 RustDesk relay(localhost:21115)。这需要 Caddy v2.6+(可用 caddy version 检查)。

# Caddyfile (save as ./Caddyfile in the same folder as docker-compose.yml)
rustdesk.example.com:443 {
    # Caddy will obtain/renew certificates automatically
    reverse_proxy 127.0.0.1:21115 {
        # Use plain TCP transport; Caddy will accept TLS from clients and connect to the backend via TCP
        transport http {
            # We don't speak HTTP to the backend; keep minimal transport settings
        }
    }
}

在同一项目中并置 Caddy 与 rustdesk 服务器的 docker-compose 片段:

cat >> docker-compose.yml <<'EOF'
  caddy:
    image: caddy:2.6.4
    container_name: caddy
    restart: unless-stopped
    ports:
      - "80:80"
      - "443:443"
    volumes:
      - ./Caddyfile:/etc/caddy/Caddyfile:ro
      - caddy_data:/data
      - caddy_config:/config
volumes:
  caddy_data:
  caddy_config:
EOF

docker compose up -d caddy

重要提示:Caddy 内置的 reverse_proxy 面向 HTTP,因此将非 HTTP 的原始 TCP 代理通过它时的行为取决于 Caddy 版本和 transport 选项。实际中许多运维人员使用 Caddy 2.6 引入的 TCP 功能来为任意 TCP 后端终止 TLS。如果遇到协议问题,请使用上面的第(2)种方案:让 Caddy 管理证书,并将证书文件交由一个小型的 TCP TLS 层(如 stunnel 或 HAProxy stream)来代理到 rustdesk 的纯 TCP。

示例:Caddy 作为证书管理器 + stunnel 做 TLS 终止(快速概览)。

# 1) Ensure Caddy is running and has issued certs for rustdesk.example.com
# 2) Copy cert/key from Caddy storage into a place stunnel can read, or mount the same volume.
# 3) Run stunnel with a config that points TLS 443 -> 127.0.0.1:21115

# stunnel.conf snippet
[rustdesk]
accept = 443
connect = 127.0.0.1:21115
cert = /etc/stunnel/fullchain.pem
key = /etc/stunnel/privkey.pem

# In Docker world, mount Caddy's certificate files into the stunnel container path above.

任一方法都会给你一个主机名(rustdesk.example.com)和端口 443 供客户端使用。从另一台机器测试连通性:nc -vz rustdesk.example.com 443 — 如果 Caddy/stunnel 配置正确,你应能完成 TLS 握手。

步骤 3 — 在客户端指向你的自托管服务器

RustDesk 客户端设置中允许自定义 ID/relay 服务器。不同平台和版本的界面略有差异,但核心值如下:

  • ID Server / Rendezvous:rustdesk.example.com:443(或你的域名和端口)
  • Relay Server:rustdesk.example.com:443

在 Windows 上:打开 RustDesk > Settings > ID/Server,并将 Id serverRelay server 设置为 rustdesk.example.com:443。在 Linux 与 macOS 上相同设置位于 Preferences。对于无头安装,客户端有时可以通过命令行标志或配置文件提供 —— 请查看客户端仓库获取详细信息。

确保客户端是近期版本(撰写时为 1.2.x 或更新)。较新的客户端包含协议修复和更好的 NAT 穿透。如果尝试使用远旧版本的客户端,行为可能不同。

故障排查与强化

常见问题与调试方法:

  • 防火墙:确认 VPS 防火墙(ufw/iptables/云提供商)允许 80/443 入站。对于在本地监听 21115 的 RustDesk 服务器容器,确认 TCP 套接字存在(使用 ss/netstat)。
  • 证书签发:如果 Let's Encrypt 无法验证,Caddy 会记录错误。确认你的 DNS A 记录指向 VPS,且在初次签发期间端口 80 可达。
  • 协议不匹配:如果看到 TLS 握手成功但客户端连接失败,可能是误用 Caddy 做了仅面向 HTTP 的代理。遇到此类情况请改用 stunnel 方案。
  • UDP 中继:RustDesk 在帧传输上用 UDP 会更高效;如果网络路径阻止 UDP,你会回退到 TCP 中继。仅当你能控制网络并了解后果时才暴露/转发 UDP 端口。

安全加固建议:

  • 在专用的非特权用户下运行 rustdesk 服务器,并保持 Docker 镜像为最新。
  • 启用 fail2ban 或类似组件限制重复失败的连接,并监控日志(docker compose logs -f rustdesk-server)。
  • 定期备份 rustdesk 服务器的数据目录(示例中为 ./data)。
  • 如果运行多个中继,考虑将中继置于私有网络或 VPC 之下。

扩展说明:单个中继适合小团队。对于更大规模的部署,在不同机器上运行多个 hbbr 进程并使用 DNS 负载均衡或合适的 L4 负载均衡器。若需要集中式企业功能如审计,商业解决方案可能更具优势。参见我们的相关文章 self-hosted-remote-desktoprustdesk-vs-anydesk 了解权衡。

维护、成本与最终建议

运营成本主要是 VPS 费用和运维时间。典型小型 VPS(1–2 CPU,2–4 GB)可在 $5–10/month 找到(DigitalOcean、Vultr、Hetzner)。Caddy 与 RustDesk server 都是开源;主要的经常性成本是托管费用。如果你需要基于 GUI 的计费或企业支持,商业厂商会按座位或会话收费 —— 参见我们的定价比较文章,例如 anydesk-pricing-explainedgodeskflow-vs-teamviewer-pricing 了解更多背景。

建议:

  • 从单台 VPS 和上述 Docker Compose 布局开始。在用户将实际使用的网络(家庭 ISP、公司防火墙)上测试连接。
  • 如果客户端常常处于高度受限的防火墙后,务必将中继放在 443 并验证 TLS 终止的可靠性;若 Caddy-only 的 TCP 代理导致问题,则使用 Caddy+stunnel 组合。
  • 自动化备份服务器数据目录并跟踪镜像升级。RustDesk server 会发布新版本;若依赖生产可用性,请在预发布环境中测试升级。

如需更简短的远程访问模式或替代方案说明,请阅读我们的相关文章:remote-access-setup-guideremote-desktop-security

看完了吗?如果你想尝试一个与自托管集成良好的完全开源远程桌面,下载 GoDesk 或比较其定价 —— 参见 GoDesk 下载GoDesk 定价。如果你已准备好部署此 RustDesk 方案,先创建上文的 docker-compose.yml 和 Caddyfile,然后运行 docker compose up -d。欲快速开始,请前往 /download 获取客户端并连接。