Ubuntu 22.04 部署 RustDesk Server 与 FRPS

记录在 Ubuntu 22.04 VPS 上部署 RustDesk Server OSS 与 FRP 服务端的完整过程,包括 systemd 开机自启、UFW 端口、FRP 文件 Token、仅本机监听的 Dashboard、SSH 隧道访问及日常检查命令。

这份记录面向一台 Ubuntu 22.04、AMD64、1 核 2 GB 的 VPS。目标是在同一台服务器上运行 RustDesk Server OSS 与 FRP 服务端(FRPS),并通过 systemd 管理进程和开机自启。

最终方案里,RustDesk 使用 Techahold 的安装脚本部署 hbbs 与 hbbr;FRPS 使用原生二进制、TOML 配置和独立低权限用户。FRPS 控制端口为 7000/TCP,Dashboard 只监听 127.0.0.1:7500,需要时通过 SSH 隧道访问,不直接暴露到公网。

执行远程脚本和启用 UFW 都可能影响服务器可用性。操作前先保留一个可用的 SSH 会话,并确认实际 SSH 端口已经在系统防火墙与云安全组中放行。

部署方案与端口规划

RustDesk Server OSS 由两个程序组成:

程序 作用
hbbs ID 注册、心跳、NAT 类型测试与连接协调
hbbr P2P 无法建立时中继流量

FRP 部分只在 VPS 上部署 frps。内网设备运行 frpc,主动连接 VPS 的 7000/TCP,再按需创建业务端口映射。服务端通过 allowPorts 将可申请的远程端口限制在 30000–39999。

部署前先安装基础工具并确认架构:

apt update
apt install -y curl wget unzip tar openssl ca-certificates tmux ufw

dpkg --print-architecture
uname -m

在本文环境中,AMD64 主机应分别显示 amd64 与 x86_64。如果结果不同,后续 RustDesk 和 FRP 二进制包也要改成对应架构。

部署 RustDesk Server OSS

下载并检查安装脚本

RustDesk 官方文档将 Techahold 脚本列为一种 systemd 安装方式。脚本会从 RustDesk Server Release 下载当前版本的 hbbs、hbbr,写入 /opt/rustdesk,并创建 rustdesksignal.service 与 rustdeskrelay.service。

远程脚本会变化,因此先保存到本地并检查内容,不直接通过管道执行:

mkdir -p /root/rustdesk-install
cd /root/rustdesk-install

wget https://raw.githubusercontent.com/techahold/rustdeskinstall/master/install.sh
chmod +x install.sh
less install.sh

直接使用 VPS 公网 IP:

./install.sh --resolveip --skip-http --no-sudo

使用已经解析到 VPS 的域名:

./install.sh \
  --resolvedns "rd.example.com" \
  --skip-http \
  --no-sudo

这些参数的含义如下:

参数 说明
--resolveip 由脚本解析当前 VPS 公网 IP
--resolvedns 使用指定的完整域名
--skip-http 不安装额外的客户端下载 HTTP 服务
--no-sudo 当前已经使用 root 执行,不再调用 sudo

服务器上若已有 Nginx、WordPress 或其他 Web 服务,保留 --skip-http 可以避免脚本额外启用 8000/TCP。

检查服务和开机自启

脚本安装完成后,先检查两个服务的完整状态:

systemctl status rustdesksignal --no-pager -l
systemctl status rustdeskrelay --no-pager -l

再分别检查是否已经启用开机启动、当前是否处于运行状态:

systemctl is-enabled rustdesksignal
systemctl is-enabled rustdeskrelay

systemctl is-active rustdesksignal
systemctl is-active rustdeskrelay

正常情况下,前两条命令应返回 enabled,后两条应返回 active。如果服务存在但尚未启用:

systemctl enable --now rustdesksignal
systemctl enable --now rustdeskrelay

配置 RustDesk 防火墙

启用 UFW 前,先放行服务器实际使用的 SSH 端口:

ufw allow SSH_PORT/tcp comment 'SSH'

不使用 RustDesk Web 客户端时,最小端口集合如下:

ufw allow 21115/tcp comment 'RustDesk NAT test'
ufw allow 21116/tcp comment 'RustDesk connection'
ufw allow 21116/udp comment 'RustDesk ID heartbeat'
ufw allow 21117/tcp comment 'RustDesk relay'

其中 21115/TCP 用于 NAT 类型测试,21116/TCP 用于 TCP 打洞与连接服务,21116/UDP 用于 ID 注册和心跳,21117/TCP 用于中继。21118/TCP 与 21119/TCP 面向 Web 客户端;不使用该功能时保持关闭。

确认 SSH 规则无误后再启用并检查 UFW:

ufw enable
ufw status numbered

VPS 服务商的云防火墙或安全组也要放行相同的公网入站端口,否则只修改 UFW 仍无法建立连接。

检查实际监听状态:

ss -lntup | grep -E '21115|21116|21117'

正常情况下应能看到 21115/TCP、21116/TCP、21116/UDP 和 21117/TCP 对应的监听项。

获取公钥并配置客户端

Techahold 脚本将服务文件放在 /opt/rustdesk。查看服务端公钥:

cat /opt/rustdesk/id_ed25519.pub

在 Windows RustDesk 客户端进入“设置 → 网络 → ID/中继服务器”,填写:

ID 服务器:VPS 公网 IP 或域名
中继服务器:留空
API 服务器:留空
Key:id_ed25519.pub 的完整内容

使用默认端口并且 hbbs、hbbr 位于同一台服务器时,客户端通常可以根据 ID 服务器推导中继地址,因此中继服务器可以留空。Key 是服务端生成的公钥,不是私钥。

日志、重启与备份

查看最近日志或持续跟踪日志:

journalctl -u rustdesksignal -n 100 --no-pager
journalctl -u rustdeskrelay -n 100 --no-pager

journalctl -u rustdesksignal -f
journalctl -u rustdeskrelay -f

重启两个服务:

systemctl restart rustdesksignal rustdeskrelay

备份整个工作目录:

tar -czf "/root/rustdesk-backup-$(date +%F).tar.gz" /opt/rustdesk

至少要保留以下密钥文件:

/opt/rustdesk/id_ed25519
/opt/rustdesk/id_ed25519.pub

私钥 id_ed25519 不应公开,也不要粘贴到文章、工单或聊天记录中。

部署 FRP 服务端

安装二进制并规划目录

本文使用以下路径:

/usr/local/bin/frps
/etc/frp/frps.toml
/etc/frp/server_token
/etc/systemd/system/frps.service

从 FRP 官方 Release 下载与架构匹配的压缩包并解压后,安装 frps。目录中的版本号应替换为实际下载版本:

cd /tmp/frp_<FRP_VERSION>_linux_amd64
install -m 0755 frps /usr/local/bin/frps
frps --version

frps.toml 是服务端配置,frpc.toml 是客户端配置。两者的校验命令不要混用:

frps verify -c /etc/frp/frps.toml
frpc verify -c /etc/frp/frpc.toml

[[proxies]] 只能出现在 frpc.toml。如果把客户端配置交给 frps 校验,可能看到 json: unknown field "proxies"。

创建低权限用户与目录

为 FRPS 创建不可登录的系统用户:

useradd \
  --system \
  --home-dir /var/lib/frp \
  --create-home \
  --shell /usr/sbin/nologin \
  frp

如果 frp 用户已经存在,可以跳过创建。随后准备配置目录和运行目录:

install -d -m 0750 -o root -g frp /etc/frp
install -d -m 0750 -o frp -g frp /var/lib/frp

使用文件保存认证 Token

生成随机 Token,并只允许 root 写入、frp 组读取:

openssl rand -hex 32 > /etc/frp/server_token
chown root:frp /etc/frp/server_token
chmod 640 /etc/frp/server_token

需要将同一个 Token 配置到 FRPC,但不要把真实值写进公开文档。FRP 的 auth.tokenSource 文件读取方式从 v0.64.0 开始提供,因此实际版本必须满足这一条件。

编写 frps.toml

编辑服务端配置:

nano /etc/frp/frps.toml

配置内容如下:

bindAddr = "0.0.0.0"
bindPort = 7000

auth.method = "token"
auth.tokenSource.type = "file"
auth.tokenSource.file.path = "/etc/frp/server_token"

transport.tls.force = true
transport.maxPoolCount = 5

allowPorts = [
  { start = 30000, end = 39999 }
]

log.to = "console"
log.level = "info"
log.disablePrintColor = true

webServer.addr = "127.0.0.1"
webServer.port = 7500
webServer.user = "admin"
webServer.password = "替换为独立强密码"

allowPorts 限制 FRPC 可以申请的远程端口范围。Dashboard 只绑定环回地址,因此无法直接从公网访问。密码仍需设置为独立强密码,不能照抄占位文本。

设置权限并校验配置:

chown root:frp /etc/frp/frps.toml
chmod 640 /etc/frp/frps.toml

frps verify -c /etc/frp/frps.toml

只有校验通过后再创建和启动 systemd 服务。

创建 frps.service

编辑服务文件:

nano /etc/systemd/system/frps.service

写入:

[Unit]
Description=FRP Server
After=network-online.target
Wants=network-online.target

[Service]
Type=simple
User=frp
Group=frp
WorkingDirectory=/var/lib/frp
ExecStart=/usr/local/bin/frps -c /etc/frp/frps.toml
Restart=on-failure
RestartSec=5s
LimitNOFILE=1048576

NoNewPrivileges=true
PrivateTmp=true
ProtectHome=true
ProtectSystem=strict
ReadWritePaths=/var/lib/frp

[Install]
WantedBy=multi-user.target

重新加载 systemd,并立即启动、启用开机自启:

systemctl daemon-reload
systemctl enable --now frps

验证服务、日志和监听端口

分层检查服务状态:

systemctl is-enabled frps
systemctl is-active frps
systemctl status frps --no-pager -l

is-enabled 返回 enabled 表示已设置开机启动;is-active 返回 active 表示当前进程正在运行。若状态异常,查看日志:

journalctl -u frps -n 100 --no-pager
journalctl -u frps -f

检查控制端口与 Dashboard:

ss -lntp | grep -E '7000|7500'

期望的绑定关系是:

0.0.0.0:7000
127.0.0.1:7500

前者允许 FRPC 从公网连接,后者只允许 VPS 本机访问。

配置 FRPS 防火墙

开放 FRP 控制端口:

ufw allow 7000/tcp comment 'FRP control'

云安全组也要开放 7000/TCP。不要为 Dashboard 开放 7500/TCP;只监听 127.0.0.1 时,公网防火墙规则本身也没有必要。

业务端口按需放行。例如 FRPC 将 SSH 映射到 30022/TCP:

ufw allow 30022/tcp comment 'FRP SSH'

该端口必须同时位于 allowPorts 指定的范围内。如果使用“FRP 32401 → VPS 本机 Nginx → HTTPS 域名”的链路代理 Plex,公网通常只开放 80/TCP 与 443/TCP,不直接开放 32401/TCP;但具体反向代理监听方式需要与 Nginx 配置一致。

通过 SSH 隧道访问 Dashboard

在本机 PowerShell 建立端口转发:

ssh -p SSH_PORT -L 7500:127.0.0.1:7500 ADMIN_USER@VPS_PUBLIC_IP

保持 SSH 会话开启,然后在本机浏览器访问:

http://127.0.0.1:7500

这里的 SSH_PORT、ADMIN_USER 与 VPS_PUBLIC_IP 都要替换为实际值。Dashboard 流量经 SSH 隧道进入服务器,不需要把 7500/TCP 暴露到公网。

FRPC 的 Plex 映射示例

内网设备上的 frpc.toml 可以按下面的结构配置:

serverAddr = "VPS_PUBLIC_IP"
serverPort = 7000

auth.method = "token"
auth.token = "填写与服务器一致的 Token"

transport.tls.enable = true

[[proxies]]
name = "plex"
type = "tcp"
localIP = "127.0.0.1"
localPort = 32400
remotePort = 32401

校验并前台运行:

frpc verify -c /etc/frp/frpc.toml
frpc -c /etc/frp/frpc.toml

示例为了说明对应关系而直接写了 auth.token。生产环境应限制 frpc.toml 的读取权限;如果客户端版本支持,也可以改为文件 Token。

端口汇总

端口 协议 用途 公网开放
自定义 SSH 端口 TCP SSH 管理 是
80 TCP HTTP、证书签发或反向代理 按需
443 TCP HTTPS、WordPress 或反向代理 按需
7000 TCP FRPC 连接 FRPS 是
7500 TCP FRPS Dashboard 否
21115 TCP RustDesk NAT 类型测试 是
21116 TCP RustDesk TCP 打洞与连接 是
21116 UDP RustDesk ID 注册与心跳 是
21117 TCP RustDesk 中继 是
21118 TCP RustDesk Web 客户端 未使用则否
21119 TCP RustDesk Web 中继 未使用则否
FRP 业务端口 TCP/UDP 内网服务映射 按需

端口需要同时考虑进程监听、UFW 和云安全组。三处任意一处缺失,外部连接都可能失败。

一次性检查清单

RustDesk:

systemctl is-enabled rustdesksignal rustdeskrelay
systemctl is-active rustdesksignal rustdeskrelay
systemctl status rustdesksignal rustdeskrelay --no-pager -l
ss -lntup | grep -E '21115|21116|21117'

FRPS:

frps verify -c /etc/frp/frps.toml
systemctl is-enabled frps
systemctl is-active frps
systemctl status frps --no-pager -l
ss -lntp | grep -E '7000|7500'
journalctl -u frps -n 50 --no-pager

防火墙:

ufw status verbose

检查完成后,FRPS 至少应满足:服务为 enabled 和 active,7000 监听 0.0.0.0,7500 只监听 127.0.0.1。RustDesk 两个服务也应同时处于启用和运行状态。

参考资料

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注