Linux VPS 遠端桌面:用 xrdp 與 XFCE 安全連線
在 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 使用的密碼。
- 透過 SSH tunnel 或 VPN 使用 xrdp。 因為 TCP 3389 永遠不直接面向網際網路,它可避免網際網路持續掃描該埠,也能避免針對 RDP 登入介面的密碼猜測。若攻擊者已能使用該 tunnel,它無法保護脆弱的帳戶密碼。
- 透過相同的 tunnel 使用 VNC。 它可提供中斷連線後仍能保留的桌面工作階段,使用的協定比 RDP 更舊且更簡單。單獨使用時它不提供任何保護:所有安全性都由 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,即使它只是建議套件也一樣。它是 xrdp 為新工作階段啟動的 X server 後端。缺少此套件時,登入畫面會接受密碼,接著直接返回登入畫面。
接著指定工作階段要啟動的桌面。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 綁定回送位址,並透過你已信任的 tunnel 連線。
編輯 /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 忽略了你的修改,通常是因為該行最後位於檔案後方另一個區段標題之下。
現在從你自己的電腦建立 tunnel。
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 上,其 binary 名稱為 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。
每個人各自建立一個 tunnel 很快就會變得繁瑣,因此團隊使用私有網路會是較好的做法。將該主機置於 自行代管的 WireGuard VPN 後方,為它配置 tunnel 位址 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 使用 software rendering,這表示 CPU 必須繪製每個像素。捲動複雜網頁和播放影片都會直接增加 CPU 負載,結果是 frame rate 下降,而不是整台機器凍結。如果你想知道 是否能在 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 用戶端的「本機資源」中啟用「遠端音訊」設定。
只要 xrdp-chansrv 已在您的工作階段中執行,文字剪貼簿即可雙向運作;xrdp 會替您啟動該程序。使用 pgrep -a xrdp-chansrv 確認其狀態。如果剪貼與貼上在工作階段進行期間停止運作,表示該程序已結束;重新連線會重新啟動它。複製檔案而非文字使用的是另一個稱為磁碟機轉送的通道:/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。刪除資料目錄後,伺服器會產生新的金鑰組,因此所有用戶端都必須重新設定新的金鑰。請備份該目錄。
防火牆必須直接允許這些連接埠。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 router 沒有任何可比對的內容。21116 上的 UDP listener 在任何層級都不是 HTTP。
有兩種方式可行。nginx 可以使用 stream 區塊轉送 TCP 埠;這是純粹的第 4 層轉送,通常不算是一般意義上的反向代理。此外,21118 和 21119 埠承載 RustDesk Web client 使用的 websocket,這屬於一般 HTTP,因此可以放在代理後方。若採用這種方式,請加入防火牆規則,讓只有代理可以連線至 21118 和 21119,因為 hbbs 會信任 websocket 連線中的 X-Real-IP 標頭,以判斷實際的 client 位址。
容器中的一次性瀏覽器
有時候,您只需要一個乾淨的瀏覽器,使用不會變動的 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 cores、4 GB memory 和 50 GB SSD。此外,每個使用者工作階段預設還需要 2 個 cores 和 2768 MB。2 GB plan 無法執行它。安裝方式是下載並執行 script:
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 完全相同的方式建立通道。切勿公開 VNC 埠。多數 VNC 伺服器只會在交握期間保護密碼,之後不會保護任何資料。因此,若使用公開埠,工作階段內容可在網路上以明文讀取。
VPS 適合當作桌面電腦嗎?
不適合當作日常工作環境,原因很多。VPS 沒有 GPU,因此所有畫面都由 CPU 負責繪製。每次按鍵都要等待一次網路往返;在 SSH 中感覺不明顯的 40 ms 延遲,到了文字編輯器中就能察覺。影片會被壓縮兩次,一次由網站處理,另一次由 RDP encoder 處理。檔案儲存在你無法實際持有的磁碟上,而大量使用桌面環境會消耗每月頻寬額度;該額度通常是依 web server 的需求配置。
但作為一次性使用的機器,VPS 非常適合,原因也正是這些特性。IP 位址穩定,且屬於 data centre;當服務需要固定且一致的位址時,這正是你需要的條件。機器可以在幾分鐘內從 image 重建,因此工作階段若遭到惡意程式破壞,重建即可,不會造成實質損失。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 server 放在 nginx 或 Traefik 後方嗎?
主要服務不行。hbbs 與 hbbr 使用自有的 binary protocol,而非 HTTP,因此沒有可供路由的 Host header,UDP 21116 也完全無法通過 HTTP proxy。請在防火牆上開放 TCP 21115 到 21119 以及 UDP 21116,讓 client 直接連線。Web client 使用的 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,再重新登入,因為該 module 會在 session 啟動時載入,重新連線不會載入它。請使用 pactl list short sinks 檢查是否有命名為 xrdp 的 sink,並確認 client 已要求音訊;在 xfreerdp3 中這是 /sound flag,在 Windows client 中則是「Remote audio」。