SSD Nodes Learn Hosting plans →
指南 Matt Connor作者: Matt Connor · 更新于 2026-08-25

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

在Ubuntu 24.04上用xrdp和XFCE运行真正的VPS图形桌面,通过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,即使它只是 recommended package:它是 xrdp 为新会话启动的 X server backend。缺少它时,登录框会接受密码,然后立即返回登录框。

现在指定会话要启动的桌面。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 绑定到回环地址,然后通过已信任的隧道访问它。

编辑 /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 忽略了你的修改,通常是因为该行最终位于文件下方另一个部分标题之下。

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

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 环境下,浏览器只能与桌面竞争剩余内存。

真正消耗资源的是浏览器,而不是桌面 shell。现代浏览器每个活动标签页通常占用 150 到 400 MB,因此运行 XFCE 的 2 GB VPS 只能处理少量标签页,随后就会开始使用 swap。添加 swap,让机器变慢而不是直接终止进程:sudo fallocate -l 2G /swapfile,然后执行 sudo chmod 600 /swapfile、sudo mkswap /swapfile 和 sudo 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 和会合服务器,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 中。删除数据目录后,服务器会生成新的一对密钥,所有客户端都必须使用新密钥重新配置。请备份该目录。如果团队以后依靠它访问每台机器,而不只是将其作为周末实验,建议参考专用的 RustDesk 中继构建版本,其中会介绍 Ed25519 密钥处理、使用固定的镜像标签而不是 latest,以及最终由您的套餐承担费用的中继带宽。

防火墙必须直接放行这些端口。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 端口。这属于纯四层转发,通常不算反向代理。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 完成。每次按键都要等待一次网络往返;在 SSH 中感觉正常的 40 ms 延迟,在文本编辑器中会明显感知到。视频会被压缩两次:一次由网站完成,另一次由 RDP 编码器完成。您的文件存储在您无法直接持有的磁盘上,而高强度桌面使用会消耗按 Web 服务器用量配置的月度带宽额度。

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

如果您还在确定这台机器的用途,建议先阅读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 文件。创建包含 JavaScript 规则的 /etc/polkit-1/rules.d/45-allow-colord.rules,让该规则对以 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 客户端中则是“远程音频”选项。