Linux VPS 遠端桌面:xrdp、XFCE 與 SSH tunnel
在 Linux VPS 執行圖形桌面,使用 xrdp 與 XFCE,透過 SSH tunnel 連線而不開放 TCP 3389,並比較 RustDesk 適用的情境。
Linux VPS 上的遠端桌面實際代表什麼
搜尋「Linux VPS 上的遠端桌面」時,通常會找到兩種不同的產品。選錯產品可能浪費一個下午。第一種是遠端存取中介服務。RustDesk 的自架伺服器是常見範例:它會在你已擁有的兩台機器之間轉送工作階段,例如筆電與家中的電腦。租用的伺服器不會繪製任何桌面。它只會讓兩端彼此建立連線,並在兩端無法直接連線時轉送封包。第二種是在租用的伺服器上實際執行圖形桌面。畫面會在資料中心繪製,再串流傳送給你。這類方案包括 xrdp、VNC(virtual network computing)或容器工作區。
有一個問題可以區分這兩種方案。設定完成後,滑鼠指標位於哪裡?如果位於你已擁有的機器上,你需要的是中介服務。如果位於 VPS 本身,你需要的是在 VPS 上執行的桌面。以下內容大多聚焦於第二種情況,因為多數指南都會略過這種情境。
哪個選項適合你的工作
- RustDesk 搭配自有 relay。 由於你持有金鑰組,它能避免工作階段經由陌生人營運的公開 rendezvous server 傳輸。它無法保護受控端電腦;該電腦仍是你安裝 client 的那台 PC,安全性也取決於該 PC 使用的密碼。
- xrdp 透過 SSH tunnel 或 VPN。 由於該連接埠不會直接暴露在網際網路上,它能避免 TCP 3389 遭到持續的全網路掃描,也能避免 RDP 登入介面遭受密碼猜測。它無法防護弱帳號密碼,因為已取得 tunnel 的人仍可嘗試登入。
- VNC 使用相同的 tunnel。 它能提供中斷連線後仍可保留的桌面工作階段,使用的通訊協定比 RDP 更舊且更簡單。VNC 本身不提供任何保護:所有安全性都由 tunnel 負責,因此單獨將 VNC 開放在公開連接埠上,是這裡最差的選項。
- Webtop 或 Kasm 等 container workspace。 它能在可丟棄並重新建置的 container 中提供瀏覽器或完整桌面,讓實際主機免於受到該瀏覽器接觸之內容的影響。它無法保護 host:這些映像檔具有廣泛權限,且其中的
sudo沒有設定密碼,因此不應將 container 視為可安全執行惡意工作負載的隔離邊界。
在 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 測量實際數值。
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"。該行表示 kernel 的 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 的 sink,並能透過用戶端聽到測試音效。若沒有 xrdp sink,表示模組未載入目前的工作階段。用戶端也必須要求音訊重新導向:在 xfreerdp3 上使用 /sound 旗標,或在 Windows 用戶端的 Local Resources 中啟用「Remote audio」設定。
只要 xrdp-chansrv 正在為目前工作階段執行,文字剪貼簿就能雙向運作;xrdp 會替您啟動該程序。使用 pgrep -a xrdp-chansrv 確認。如果工作階段進行期間無法再複製與貼上,表示該程序已終止,重新連線即可重新啟動。複製檔案而非文字使用另一個名為 drive redirection 的通道:/drive:home,/home/you 在 xfreerdp3 上將本機資料夾掛載到遠端工作階段。
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 是在直接點對點連線失敗時轉送工作階段資料的 relay。兩者都不會執行桌面環境。兩者來自同一個 image,以下是專案發布的 compose 檔案,其中已將 relay 位址改為您自己的主機名稱:
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 relay 的專用建置,了解 Ed25519 金鑰處理方式、使用固定的 image tag 取代 latest,以及方案最終需要支付的 relay 頻寬。
防火牆必須直接允許這些連接埠。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/tcpRustDesk 為何無法放在 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 client 使用的 websockets,而這是一般的 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 tunnel 或 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.shVNC,以及仍適用的情境
VNC 傳送 framebuffer 更新,而不是繪圖命令,因此在低速連線上會比 RDP 更耗用資源,而且不提供音訊通道。VNC 適用於一種情境:您希望桌面工作階段在中斷連線後持續執行,並在返回時恢復相同的工作階段。TigerVNC 可以做到這點。vncserver -localhost yes :1 會將 Xvnc 綁定至 TCP 5901 的 127.0.0.1,並拒絕來自其他位置的連線,因此可搭配 ssh -N -L 5901:127.0.0.1:5901 you@vps.example.com,以與 xrdp 完全相同的方式建立 tunnel。切勿公開 VNC 埠。多數 VNC 伺服器只會在 handshake 期間保護密碼,之後不再提供保護。因此,若將 VNC 埠公開,工作階段內容可在網路傳輸中被讀取。
VPS 適合當作桌面電腦嗎?
不適合當作日常使用的主要電腦,原因很多。VPS 沒有 GPU,因此所有畫面都由 CPU 繪製。每次按鍵都要等待一次網路往返;在 SSH 中感覺尚可的 40 ms 延遲,到了文字編輯器中就很明顯。影片會被壓縮兩次,一次由網站處理,另一次由 RDP 編碼器處理。檔案存放在不由你持有的磁碟上,而大量使用桌面環境會消耗每月頻寬配額;這項配額通常是依 Web 伺服器的需求設定。
但作為一次性使用的機器,VPS 非常合適,而相同的特性也說明了原因。IP 位址穩定,且屬於資料中心;當服務必須看到固定位址時,這正是你需要的條件。機器可在幾分鐘內從映像檔重建,因此某個工作階段若遭遇惡意內容,重建即可,不會造成實質損失。VPS 與你的實體硬體隔離,且即使闔上筆記型電腦仍會持續執行。按小時計費也讓拋棄式桌面環境的成本很低。
如果你仍在釐清這台機器的用途,建議先閱讀VPS 適合用途的實用清單,再決定是否在其上安裝桌面環境。如果你想要桌面環境的原因是需要執行某個 Windows 應用程式,也應先比較Linux 與 Windows Server 的實際差異,因為授權會改變解決方案的成本。
FAQ
我可以在 2 GB VPS 上執行遠端桌面嗎?
可以,但應使用輕量型桌面環境。XFCE 或 LXQt 登入後約使用 300 到 400 MB,足以執行開啟數個分頁的瀏覽器。在 2 GB 記憶體上使用 GNOME 或 KDE Plasma,幾乎沒有空間留給應用程式。請建立 2 GB swap 檔案,讓記憶體壓力降低系統速度,而不是直接終止處理程序。如果某個項目無訊息消失,請檢查 dmesg | grep -i "killed process",確認是否為核心的 out-of-memory killer 所致。
我應該在 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 連線。若使用者超過 1 或 2 人,請將 xrdp 綁定至 WireGuard 位址,而不是 loopback。
為什麼 xrdp 會詢問「需要驗證才能建立色彩管理裝置」?
colord 服務會向 polkit 請求權限,而 polkit 只會對本機登入的 session 靜默核准該動作。RDP session 不被視為本機登入,因此每次登入都會出現密碼提示。在 Ubuntu 24.04 上,舊的 .pkla 修正方式不會生效,因為 polkit 124 已移除 local authority 檔案。請建立 /etc/polkit-1/rules.d/45-allow-colord.rules,內容包含一項 JavaScript 規則:對以 org.freedesktop.color-manager. 開頭的 action id 回傳 polkit.Result.YES,然後執行 sudo systemctl restart polkit。
我可以將自架的 RustDesk 伺服器放在 nginx 或 Traefik 後方嗎?
主要服務不行。hbbs 與 hbbr 使用自有的二進位通訊協定,而不是 HTTP,因此沒有可供路由使用的 Host 標頭;UDP 21116 也完全無法通過 HTTP proxy。在防火牆上開放 TCP 21115 到 21119 以及 UDP 21116,讓用戶端直接連線。Web 用戶端使用的 websocket 連接埠 21118 與 21119 採用 HTTP,可以放在 proxy 後方。若採用此配置,請限制防火牆規則,使只有 proxy 能連線,因為 hbbs 會信任這些連線上的 X-Real-IP。
為什麼我的 xrdp session 沒有聲音?
Ubuntu 24.04 使用 PipeWire,但 xrdp 的聲音轉送功能是為 PulseAudio 建置,因此必須安裝 bridge 後才會有音訊。執行 sudo apt install -y pipewire-module-xrdp,然後完整登出 session,再重新登入,因為該模組會在 session 啟動時載入,重新連線不會載入它。使用 pactl list short sinks 檢查是否有名稱包含 xrdp 的 sink,並確認用戶端要求音訊;在 xfreerdp3 中這是 /sound 旗標,在 Windows 用戶端中則是「Remote audio」。