SSD Nodes Learn 🎉 VPS $5.50/月起
指南 Matt Connor作者: Matt Connor

Linux VPS远程桌面:xrdp与XFCE配置指南

在Ubuntu 24.04上用xrdp和XFCE运行真实图形桌面,通过SSH隧道访问而非暴露3389端口,并说明RustDesk适用的场景与限制。

Linux VPS 上的远程桌面实际指什么

搜索“Linux VPS 上的远程桌面”时,通常会遇到两类不同的产品。选错类型可能浪费整个下午。第一类是远程访问中转服务。RustDesk 的自托管服务器是常见示例:它在您已经拥有的两台设备之间中继会话,例如您的笔记本电脑和家中的 PC。租用的服务器不会渲染桌面。它只负责让两端相互发现,并在两端无法直接连接时转发数据包。第二类是在租用的服务器上运行真正的图形桌面。桌面画面在数据中心中渲染,再以流的形式传输给您。这类方案包括 xrdp、VNC(虚拟网络计算)或容器工作区。

有一个问题可以区分这两类方案。配置完成后,鼠标指针位于哪里?如果位于您已经拥有的设备上,您需要的是中转服务。如果位于 VPS 本身,您需要的是运行在 VPS 上的桌面。下面主要介绍第二种情况,因为大多数教程都会跳过这一部分。

适合您工作的选项

  • 使用自有中继服务器的 RustDesk。 它可以避免会话经过陌生人运行的公共会合服务器,因为密钥对由您持有。但它无法保护受控机器;受控机器仍然是您安装客户端的那台 PC,安全性取决于该 PC 设置的密码。
  • 通过 SSH 隧道或 VPN 使用 xrdp。 它可以避免 TCP 3389 持续遭受来自整个互联网的扫描,也可以避免 RDP 登录端点遭受密码猜测,因为该端口不会直接暴露在互联网中。但如果攻击者已经获得隧道访问权限,它无法保护弱账户密码。
  • 通过同一隧道使用 VNC。 它可以提供断开连接后仍能保留的桌面会话,并使用比 RDP 更老、更简单的协议。VNC 本身不提供任何保护:所有安全措施都由隧道完成,因此单独将 VNC 暴露在公网端口上是这里最差的选项。
  • 使用 Webtop 或 Kasm 等容器工作区。 它可以在可随时删除并重建的容器中提供浏览器或完整桌面,从而保护真实机器免受该浏览器接触到的内容影响。但它无法保护宿主机:这些镜像以较高权限运行,内部还没有密码的 sudo,因此不应将容器视为可运行恶意工作负载的可信边界。

在 Ubuntu 24.04 上安装 xrdp 和 XFCE

VPS 服务器镜像不包含图形桌面。先安装图形桌面,再安装 xrdp。xrdp 是开源服务器,使用 RDP(远程桌面协议)通信,Windows 客户端也使用该协议。请选择轻量级桌面,通常使用 XFCE。

sudo apt update
sudo apt install -y xrdp xorgxrdp xfce4 xfce4-goodies dbus-x11
systemctl is-active xrdp

截至 August 2026,Ubuntu 24.04 在 universe 组件中提供 xrdp 0.9.24 和 xorgxrdp。请按名称安装 xorgxrdp,即使它只是推荐软件包。它是 xrdp 为新会话启动的 X 服务器后端。如果未安装,登录框会接受密码,然后立即返回登录框。

现在指定会话要启动的桌面。xrdp 会运行 /etc/xrdp/startwm.sh;当该文件存在时,该文件会运行 ~/.xsession

echo "xfce4-session" > ~/.xsession
chmod 644 ~/.xsession

最后,xrdp 需要读取用于向客户端提供 TLS(传输层安全)连接的密钥。该文件的权限模式为 640,所有者组为 ssl-cert

ls -l /etc/ssl/private/ssl-cert-snakeoil.key
id xrdp

列表中会显示 -rw-r----- 1 root ssl-cert。如果 id xrdp 输出的组列表中没有 ssl-cert,请运行 sudo adduser xrdp ssl-cert,然后运行 sudo systemctl restart xrdp。如果跳过此步骤,xrdp 将无法打开密钥,并且 /var/log/xrdp.log 会在日志行中使用 snakeoil 文件名记录该失败。

为什么不应将端口 3389 开放到互联网

互联网上的各种扫描器会持续扫描 TCP 3389,RDP 登录框会对每次密码尝试都返回响应。不要开放此端口。应将 xrdp 绑定到 loopback 地址,再通过已信任的隧道访问它。

编辑 /etc/xrdp/xrdp.ini,并修改 [Globals] 部分中的监听地址。

[Globals]
port=tcp://.:3389

随附文件会在注释中说明该语法:tcp://.:3389 表示 127.0.0.1:3389,tcp://:3389 表示所有网络接口。修改后重启并确认配置,因为这里的拼写错误可能不会报错,却会使服务继续监听所有地址。

sudo systemctl restart xrdp
ss -tlnp | grep 3389

你需要看到 127.0.0.1:3389。如果看到 0.0.0.0:3389,说明 xrdp 忽略了你的修改。通常是因为该行最终位于文件下方另一个 section heading 之下。

现在从你自己的计算机建立隧道。

ssh -N -L 3389:127.0.0.1:3389 you@vps.example.com

-N 表示“建立连接,但不运行命令”,因此该会话仅用于传输端口。保持此终端运行,并将 RDP 客户端指向 127.0.0.1:3389。在 Linux 客户端上,使用 FreeRDP 3;其在 Ubuntu 24.04 中的二进制文件名为 xfreerdp3

sudo apt install -y freerdp3-x11
xfreerdp3 /v:127.0.0.1:3389 /u:you /dynamic-resolution +clipboard /sound

在 Windows 上使用内置的 mstsc,并将 127.0.0.1 填入计算机字段。FreeRDP 首次连接时会要求你信任证书,并显示 Do you trust the above certificate? (Y/T/N);使用自签名的 snakeoil 证书时,这是正常现象。

如果 ssh 返回 bind [127.0.0.1]:3389: Address already in use,说明你自己的计算机上已有程序占用 3389。使用 ssh -N -L 13389:127.0.0.1:3389 you@vps.example.com 更改本地端口,然后连接到 127.0.0.1:13389

每个人都建立一条隧道会很麻烦,因此对于团队,更好的方案是使用私有网络。将该主机置于自托管的 WireGuard VPN之后,为其分配隧道地址 10.8.0.1,并设置 port=tcp://10.8.0.1:3389,使 xrdp 仅在 VPN 内响应。无论采用哪种方式,都不应存在针对 3389 的防火墙规则。如果不确定当前规则允许哪些流量,请先从VPS 上的 ufw 防火墙基础开始,并在连接前检查,而不是连接后再检查。

2 GB VPS 上的远程桌面需要多少 RAM

您选择的桌面环境决定了 2 GB 套餐是否够用。以下数值是 Ubuntu 24.04 登录后不久的典型内存占用,已经取整,来源是已发布的对比数据,并非在您的机器上实测。连接后立即使用 free -m 测量实际占用。

ChartTypical memory in use after login, Ubuntu 24.04 (published figures)
The data behind this chart
[
  {
    "label": "LXQt",
    "idle_ram_mb": 300
  },
  {
    "label": "XFCE",
    "idle_ram_mb": 400
  },
  {
    "label": "MATE",
    "idle_ram_mb": 500
  },
  {
    "label": "KDE Plasma",
    "idle_ram_mb": 800
  },
  {
    "label": "GNOME",
    "idle_ram_mb": "1,200"
  }
]

在这 5 个桌面环境中,差异才是关键。LXQt 的占用接近 300 MB,XFCE 接近 400 MB,因此在 2 GB 服务器上,这两者都能为浏览器留出空间。GNOME 在打开任何窗口前就大约需要 1,200 MB,因此在 2 GB VPS 上,浏览器只能与桌面环境争夺剩余内存。

真正消耗资源的是浏览器,而不是桌面外壳。现代浏览器每个活动标签页通常会占用 150 到 400 MB,因此运行 XFCE 的 2 GB VPS 只能处理少量标签页,随后就会开始使用 swap。添加 swap,让机器变慢而不是直接终止进程:sudo fallocate -l 2G /swapfile,然后执行 sudo chmod 600 /swapfilesudo mkswap /swapfilesudo swapon /swapfile,并在 /etc/fstab 中添加对应配置行,使其在重启后仍然生效。如果某个进程毫无提示地消失,请运行 dmesg | grep -i "killed process"。这表示内核的 out-of-memory killer 终止了该进程,而浏览器通常是受害者。

CPU 是另一个限制,而且更容易被低估。VPS 没有 GPU,因此 X 会通过 llvmpipe 回退到软件渲染,这意味着由 CPU 绘制每个像素。滚动内容复杂的页面和播放视频都会直接表现为 CPU 负载,帧率会下降,而不是整台机器冻结。这也是您如果想知道 是否可以在 VPS 上玩游戏 时会遇到的限制:对于任何 3D 内容,答案都是不可以,原因正是如此。

xrdp 会话中的声音和剪贴板

Ubuntu 24.04 使用 PipeWire,而 xrdp 的声音重定向基于 PulseAudio 开发,因此全新安装后通常可以正常显示画面,但没有声音。Ubuntu 提供了所需的桥接模块。

sudo apt install -y pipewire-module-xrdp pulseaudio-utils alsa-utils

完全退出 RDP 会话,然后重新登录,因为该模块会在会话启动时加载。仅重新连接不够。随后在会话中执行以下检查:

pactl list short sinks
speaker-test -c 2 -t wav -l 1

您应看到名称中包含 xrdp 的接收端,并通过客户端听到测试音。没有 xrdp 接收端,表示模块未加载到当前会话中。客户端还必须请求音频:在 xfreerdp3 中使用 /sound 标志,或者在 Windows 客户端的“本地资源”下启用“远程音频”。

xrdp-chansrv 为您的会话运行后,文本剪贴板即可双向工作;xrdp 会为您启动该进程。使用 pgrep -a xrdp-chansrv 确认。如果会话进行到一半时复制和粘贴停止工作,说明该进程已退出;重新连接会重新启动它。复制文件而不是文本使用单独的通道,称为驱动器重定向:xfreerdp3 中的 /drive:home,/home/you 会将本地目录挂载到远程会话中。

polkit 弹窗及其他首次登录失败

首次登录时最常见的意外,是看到内容为 Authentication is required to create a color managed device 的对话框。原因很明确。colord 服务会向 polkit 请求权限。polkit 只会对其认定为本地登录的会话静默授予该操作,而 RDP 会话不属于本地登录会话。因此,polkit 会改为要求您输入密码。Ubuntu 24.04 随附 polkit 124,该版本移除了旧的本地授权 .pkla 文件。因此,所有指导您写入 /etc/polkit-1/localauthority/50-local.d/45-allow-colord.pkla 的教程在 24.04 上都完全不起作用。请改为编写 JavaScript 规则。

/* /etc/polkit-1/rules.d/45-allow-colord.rules */
polkit.addRule(function(action, subject) {
    if (action.id.indexOf("org.freedesktop.color-manager.") === 0 &&
        subject.isInGroup("sudo")) {
        return polkit.Result.YES;
    }
});

运行 sudo systemctl restart polkit,然后重新连接。还有另外两种失败情况,可以根据症状识别。

登录框接受密码后立即返回。 会话已启动,但随即退出。先查看 /var/log/xrdp-sesman.log,然后查看主目录中的 ~/.xsession-errors。缺少 xorgxrdp~/.xsession 指向未安装的桌面环境、您没有写入权限的主目录,或磁盘已满,都会导致这种结果。

连接后看到带有 X 光标的灰色屏幕。 X 已启动,但桌面没有启动。这仍然是 ~/.xsession:通过 SSH 手动运行 xfce4-session,然后查看它输出的错误。

自托管 RustDesk 服务器的作用

RustDesk 由两个进程组成。hbbs 是客户端注册使用的 ID 和 rendezvous 服务器,hbbr 是中继服务器;当点对点直连失败时,它负责转发会话流量。两者都不运行桌面环境。它们来自同一个镜像。以下是项目发布的 compose 文件,其中中继地址已改为您自己的主机名:

services:
  hbbs:
    container_name: hbbs
    image: rustdesk/rustdesk-server:latest
    command: hbbs -r rustdesk.example.com:21117
    ports:
      - 21115:21115
      - 21116:21116
      - 21116:21116/udp
      - 21118:21118
    volumes:
      - ./data:/root
    restart: unless-stopped
  hbbr:
    container_name: hbbr
    image: rustdesk/rustdesk-server:latest
    command: hbbr
    ports:
      - 21117:21117
      - 21119:21119
    volumes:
      - ./data:/root
    restart: unless-stopped

启动服务,然后读取服务器首次启动时生成的公钥:

sudo docker compose up -d
sudo cat ./data/id_ed25519.pub

每个客户端都需要配置您的主机名和该公钥。两者都应在 RustDesk 客户端的 Network 设置中填写。对应的私钥保存在 ./data/id_ed25519 中。删除数据目录后,服务器会生成一对新的密钥,因此所有客户端都必须使用新密钥重新配置。请备份该目录。

防火墙必须直接放行这些端口。hbbs 使用 TCP 21115、21116 和 21118,以及 UDP 21116。hbbr 使用 TCP 21117 和 21119。

sudo ufw allow 21115/tcp
sudo ufw allow 21116/tcp
sudo ufw allow 21116/udp
sudo ufw allow 21117/tcp
sudo ufw allow 21118/tcp
sudo ufw allow 21119/tcp

RustDesk 无法置于 nginx 或 Traefik 后方

已经在一个反向代理上为所有服务终止 TLS 的用户,通常会尝试这样配置,但最终会失败。hbbs 和 hbbr 通过 TCP 和 UDP 使用各自的二进制协议,而不是 HTTP。没有可用于路由的 Host 标头,也没有可检查的 HTTP 请求,因此 nginx 的 server 块或 Traefik 的 HTTP 路由器没有匹配目标。21116 端口上的 UDP 监听在任何层面都不是 HTTP。

有两种方式可行。nginx 可以通过 stream 块转发 TCP 端口。这属于纯粹的第 4 层转发,通常不称为反向代理。21118 和 21119 端口承载 RustDesk Web 客户端使用的 WebSocket,而 WebSocket 属于普通 HTTP,因此这两个端口可以置于代理后方。如果采用这种方式,请添加防火墙规则,确保只有代理可以访问 21118 和 21119,因为 hbbs 依赖 WebSocket 连接中的 X-Real-IP 标头来确定真实的客户端地址。

容器中的临时浏览器

有时,您只需要一个干净的浏览器,并为其分配一个不变的 IP,同时与您自己的计算机隔离。容器工作区可以实现这一点,而且无需安装大量软件。LinuxServer 的 Webtop 是较轻量的选择:

services:
  webtop:
    image: lscr.io/linuxserver/webtop:latest
    container_name: webtop
    environment:
      - PUID=1000
      - PGID=1000
      - TZ=Etc/UTC
    volumes:
      - /path/to/data:/config
    ports:
      - 127.0.0.1:3000:3000
      - 127.0.0.1:3001:3001
    shm_size: "1gb"
    restart: unless-stopped

端口 3000 提供 HTTP,端口 3001 提供 HTTPS。您可以直接在浏览器标签页中访问桌面,无需在任何地方安装 RDP 客户端。镜像标签覆盖 XFCE、KDE、MATE 和 i3,并提供多种基础发行版。该项目的文档明确说明了风险:容器对主机具有特权访问权限,并包含一个可免密码运行 sudo 的终端,因此不应在未受保护的情况下直接面向互联网。正因如此,上述端口绑定到 127.0.0.1,而不是发布到所有地址。您可以通过访问 xrdp 时使用的同一个 SSH 隧道或 VPN 连接到它。

Kasm Workspaces 是规模大得多的同类方案,提供 Web 控制台、用户账户,以及在会话结束时重置的独立会话容器。它需要的机器资源超过小型 VPS 的通常配置。截至 August 2026,文档列出的最低配置为 2 个 CPU 核心、4 GB 内存和 50 GB SSD;此外,每个用户会话默认使用 2 个核心和 2768 MB 内存。2 GB 的方案无法运行它。安装过程是下载并运行脚本:

cd /tmp
curl -O https://kasm-static-content.s3.amazonaws.com/kasm_release_1.17.0.7f020d.tar.gz
tar -xf kasm_release_1.17.0.7f020d.tar.gz
sudo bash kasm_release/install.sh

VNC,以及它仍然适用的场景

VNC 发送帧缓冲区更新,而不是绘图命令,因此在慢速链路上的体验比 RDP 更沉重,并且不提供声音通道。它适用于一种场景:您希望桌面会话在断开连接后继续运行,并在返回时恢复同一个会话。TigerVNC 可以实现这一点。vncserver -localhost yes :1 将 Xvnc 绑定到 TCP 5901 上的 127.0.0.1,并拒绝来自其他位置的连接,因此可以像使用 xrdp 配合 ssh -N -L 5901:127.0.0.1:5901 you@vps.example.com 一样,通过隧道连接。切勿将 VNC 端口发布到公网。大多数 VNC 服务器只会在握手期间保护密码,此后的通信不会受到保护,因此通过公网端口连接时,会话内容可被其他人读取。

VPS 适合用作桌面吗?

不适合日常使用,原因很多。VPS 没有 GPU,因此所有图形渲染都由 CPU 完成。每次按键都要等待一次网络往返;40 ms 的延迟在 SSH 中通常可以接受,但在文本编辑器中会明显感觉到。视频会被压缩两次:一次由网站完成,另一次由 RDP 编码器完成。您的文件存储在您无法直接控制的磁盘上,而高强度桌面使用会消耗每月带宽额度;该额度通常是按 Web 服务器的需求配置的。

作为一次性使用的机器,VPS 非常合适,原因也正是这些特性。IP 地址稳定,并且属于数据中心;当服务必须看到固定地址时,这正是您需要的配置。机器可以在几分钟内从镜像重建,因此某个会话如果感染恶意软件,重建不会造成实际损失。VPS 与您的真实硬件隔离,并且在您合上笔记本电脑后仍会继续运行。按小时计费也使临时桌面的成本很低。

如果您还在确定这台机器的用途,建议先阅读VPS 的实际适用场景列表,再在其上安装桌面环境。如果您想要桌面的原因只是运行一个 Windows 应用,也应先对照Linux 与 Windows Server 的实际差异进行评估,因为许可证会改变最终成本。

FAQ

我可以在 2 GB VPS 上运行远程桌面吗?

可以,但应使用轻量级桌面环境。XFCE 或 LXQt 登录后大约占用 300 到 400 MB,因此还可为打开少量标签页的浏览器留出足够内存。在 2 GB 内存的 VPS 上运行 GNOME 或 KDE Plasma 几乎不会为应用程序留下可用内存。添加 2 GB swap 文件,使内存压力减慢系统,而不是直接终止进程。如果某个进程无提示消失,请检查 dmesg | grep -i "killed process",确认是否是内核的内存不足终止程序导致。

我应该在 VPS 防火墙上开放端口 3389 吗?

不应该。TCP 3389 会持续遭到扫描,暴露 RDP 登录界面会招致密码猜测攻击。在 /etc/xrdp/xrdp.ini 中设置 port=tcp://.:3389,使 xrdp 仅监听 127.0.0.1;使用 ss -tlnp | grep 3389 确认设置,然后通过 ssh -N -L 3389:127.0.0.1:3389 you@vps.example.com 连接。超过一两名用户时,应将 xrdp 绑定到 WireGuard 地址,而不是回环地址。

xrdp 为什么会提示“需要身份验证才能创建颜色管理设备”?

colord 服务会向 polkit 请求权限,而 polkit 只有在本地登录会话中才会静默授予该操作。RDP 会话不属于本地登录会话,因此每次登录都会出现密码提示。在 Ubuntu 24.04 中,旧的 .pkla 修复方法不起作用,因为 polkit 124 删除了本地 authority 文件。创建 /etc/polkit-1/rules.d/45-allow-colord.rules,其中包含一条 JavaScript 规则:对于以 org.freedesktop.color-manager. 开头的操作 ID 返回 polkit.Result.YES,然后运行 sudo systemctl restart polkit

我可以将自托管的 RustDesk 服务器放在 nginx 或 Traefik 后面吗?

不能代理主服务。hbbs 和 hbbr 使用自有二进制协议,而不是 HTTP,因此没有可用于路由的 Host 标头;UDP 21116 也完全无法通过 HTTP 代理。应在防火墙上开放 TCP 21115 到 21119 以及 UDP 21116,让客户端直接连接。Web 客户端使用的 websocket 端口 21118 和 21119 属于 HTTP,可以放在代理后面。如果这样配置,应限制防火墙规则,使只有代理可以访问这些端口,因为 hbbs 会信任这些连接上的 X-Real-IP

我的 xrdp 会话为什么没有声音?

Ubuntu 24.04 使用 PipeWire,而 xrdp 的声音重定向功能是为 PulseAudio 构建的,因此必须安装桥接模块后才会有声音。运行 sudo apt install -y pipewire-module-xrdp,然后完全注销会话并重新登录,因为该模块会在会话启动时加载,重新连接不会加载它。使用 pactl list short sinks 检查是否存在名称包含 xrdp 的接收端,并确认客户端请求音频:在 xfreerdp3 中这是 /sound 标志,在 Windows 客户端中则是“远程音频”。

#remote-desktop#xrdp#rustdesk#vnc#自托管