Desktop remoto su Linux VPS con xrdp e XFCE
Configura un desktop grafico reale su Linux VPS con xrdp e XFCE, usa un tunnel SSH senza aprire la porta 3389 e scopri quando scegliere RustDesk.
Che cosa significa realmente desktop remoto su un Linux VPS
Due prodotti diversi corrispondono alla ricerca "desktop remoto su un Linux VPS", e scegliere quello sbagliato può farti perdere un pomeriggio. Il primo è un broker per l'accesso remoto. Il server self-hosted di RustDesk ne è l'esempio più comune: inoltra una sessione tra due macchine che possiedi già, ad esempio il laptop e il PC di casa. Il server noleggiato non esegue alcun desktop. Mette in comunicazione i due estremi e inoltra i pacchetti quando non possono raggiungersi direttamente. Il secondo è un vero desktop grafico in esecuzione sul server noleggiato. In questo caso i pixel vengono elaborati nel data centre e trasmessi al tuo dispositivo. Le tecnologie utilizzate possono essere xrdp, VNC (virtual network computing) oppure un workspace in un container.
Una domanda consente di distinguerli. Dopo aver completato la configurazione, dove si trova il puntatore del mouse? Se si trova su una macchina che possiedi già, ti serve un broker. Se si trova sul VPS, ti serve un desktop in esecuzione sul VPS. La seconda situazione occupa la maggior parte della guida seguente, perché è quella che la maggior parte delle guide trascura.
Quale opzione è adatta al tuo lavoro
- RustDesk con un relay gestito da te. Protegge la sessione dal passaggio attraverso un server pubblico di rendezvous gestito da terzi, perché possiedi tu la coppia di chiavi. Non protegge la macchina controllata, che rimane il PC su cui hai installato il client, con la password configurata su quel PC.
- xrdp tramite un tunnel SSH o una VPN. Ti protegge dalle scansioni costanti dell'intera Internet sulla porta TCP 3389 e dai tentativi di indovinare la password nella schermata di accesso RDP, perché quella porta non è mai esposta a Internet. Non protegge una password debole dell'account da chiunque disponga già del tunnel.
- VNC tramite lo stesso tunnel. Fornisce una sessione desktop che sopravvive alle disconnessioni, usando un protocollo più vecchio e semplice di RDP. Da solo non protegge nulla: tutta la sicurezza dipende dal tunnel, quindi VNC da solo su una porta pubblica è l'opzione peggiore in questo caso.
- Un workspace containerizzato come Webtop o Kasm. Fornisce un browser o un intero desktop in un container che puoi eliminare e ricreare, proteggendo la macchina reale da ciò con cui interagisce quel browser. Non protegge l'host: queste immagini vengono eseguite con privilegi ampi e con un
sudosenza password all'interno, quindi il container non è un confine di sicurezza a cui affidare un carico di lavoro ostile.
Installare xrdp e XFCE su Ubuntu 24.04
L'immagine di un server VPS non include un ambiente desktop grafico. È necessario installarne uno, quindi installare xrdp, il server open source che usa RDP (remote desktop protocol), lo stesso protocollo usato dal client Windows. Scegliere un desktop leggero: XFCE è la scelta abituale.
sudo apt update
sudo apt install -y xrdp xorgxrdp xfce4 xfce4-goodies dbus-x11
systemctl is-active xrdpA ottobre 2026 Ubuntu 24.04 include xrdp 0.9.24 e xorgxrdp nel componente universe. Installare xorgxrdp indicando il nome, anche se è soltanto un pacchetto consigliato: è il backend del server X che xrdp avvia per una nuova sessione. Senza questo pacchetto, la finestra di accesso accetta la password e poi torna direttamente alla finestra di accesso.
Ora indicare alla sessione quale desktop avviare. xrdp esegue /etc/xrdp/startwm.sh, che esegue ~/.xsession quando quel file esiste.
echo "xfce4-session" > ~/.xsession
chmod 644 ~/.xsessionInfine, xrdp deve poter leggere la chiave TLS (transport layer security) che presenta ai client. Il file ha modalità 640 ed è di proprietà del gruppo ssl-cert.
ls -l /etc/ssl/private/ssl-cert-snakeoil.key
id xrdpL'elenco mostra -rw-r----- 1 root ssl-cert. Se id xrdp non stampa ssl-cert tra i gruppi, eseguire sudo adduser xrdp ssl-cert e poi sudo systemctl restart xrdp. Se si salta questo passaggio, xrdp non può aprire la chiave e /var/log/xrdp.log registra l'errore indicando il nome del file snakeoil nella riga.
Perché non dovresti aprire la porta 3389 a Internet
La porta TCP 3389 viene sottoposta continuamente a scansioni da parte di sistemi presenti su Internet, e una schermata di accesso RDP risponde a ogni tentativo di autenticazione. Non aprirla. Configura xrdp in ascolto solo sull'indirizzo di loopback e raggiungilo tramite un tunnel di cui ti fidi già.
Modifica /etc/xrdp/xrdp.ini e cambia il listener nella sezione [Globals].
[Globals]
port=tcp://.:3389Il file fornito documenta questa sintassi nei propri commenti: tcp://.:3389 indica 127.0.0.1:3389, mentre tcp://:3389 indica tutte le interfacce. Riavvia il servizio e verifica la configurazione, perché un errore di sintassi può lasciare il servizio in ascolto su tutti gli indirizzi senza messaggi evidenti.
sudo systemctl restart xrdp
ss -tlnp | grep 3389Devi ottenere 127.0.0.1:3389. Se visualizzi 0.0.0.0:3389, xrdp ha ignorato la modifica, di solito perché la riga è finita sotto un'altra intestazione di sezione più avanti nel file.
Ora apri il tunnel dal tuo computer.
ssh -N -L 3389:127.0.0.1:3389 you@vps.example.com-N significa "apri la connessione ma non eseguire alcun comando", quindi la sessione esiste solo per trasportare la porta. Lascia aperto quel terminale e configura il client RDP per connettersi a 127.0.0.1:3389. Su un client Linux il software è FreeRDP 3, il cui binario su Ubuntu 24.04 si chiama xfreerdp3:
sudo apt install -y freerdp3-x11
xfreerdp3 /v:127.0.0.1:3389 /u:you /dynamic-resolution +clipboard /soundSu Windows usa mstsc, incluso nel sistema, e inserisci 127.0.0.1 come computer. Al primo collegamento FreeRDP chiede di considerare attendibile il certificato e visualizza Do you trust the above certificate? (Y/T/N); è previsto quando si usa il certificato snakeoil autofirmato.
Se ssh restituisce bind [127.0.0.1]:3389: Address already in use, qualcosa sul tuo computer sta già usando la porta 3389. Sposta l'estremità locale con ssh -N -L 13389:127.0.0.1:3389 you@vps.example.com e connettiti a 127.0.0.1:13389.
Un tunnel per ogni persona diventa scomodo. Per un team, la soluzione migliore è una rete privata. Colloca il server dietro una VPN WireGuard self-hosted, assegnagli l'indirizzo del tunnel 10.8.0.1 e configura port=tcp://10.8.0.1:3389 in modo che xrdp risponda solo all'interno della VPN. In entrambi i casi, la regola del firewall per la porta 3389 non dovrebbe esistere. Se non sai quali connessioni consentono attualmente le tue regole, parti da le basi del firewall ufw su un VPS e verifica prima di connetterti, non dopo.
Quanta RAM utilizza un desktop remoto su un VPS da 2 GB
Il desktop scelto determina se un piano da 2 GB è sufficiente o inutilizzabile. I valori riportati di seguito sono stime tipiche arrotondate della memoria utilizzata subito dopo l'accesso a Ubuntu 24.04. Sono ricavati da confronti pubblicati e non da misurazioni eseguite sul tuo computer. Misura il consumo effettivo con free -m subito dopo la connessione.
I dati alla base di questo grafico
[
{
"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"
}
]Tra questi 5 desktop, la differenza è significativa. LXQt utilizza circa 300 MB e XFCE circa 400 MB. Entrambi lasciano quindi spazio per un browser su un sistema da 2 GB. GNOME richiede circa 1,200 MB prima ancora di aprire una finestra. Su un sistema da 2 GB, il browser deve quindi condividere con il desktop la memoria rimanente.
Il costo reale è il browser, non la shell del desktop. Un browser moderno utilizza tra 150 e 400 MB per ogni scheda attiva. Per questo, un VPS da 2 GB con XFCE gestisce alcune schede e poi inizia a utilizzare lo swap. Aggiungi lo swap per fare in modo che il sistema rallenti invece di terminare i processi: sudo fallocate -l 2G /swapfile, poi sudo chmod 600 /swapfile, sudo mkswap /swapfile, sudo swapon /swapfile e una riga corrispondente in /etc/fstab, così la configurazione viene mantenuta dopo un riavvio. Se qualcosa scompare senza avviso, esegui dmesg | grep -i "killed process". Questo indica che il kernel ha terminato il processo tramite il meccanismo out-of-memory. Di solito il processo terminato è il browser.
L'altra limitazione è la CPU, che è facile sottovalutare. Un VPS non dispone di una GPU, quindi X utilizza il rendering software tramite llvmpipe. La CPU deve quindi elaborare ogni pixel. Lo scorrimento di una pagina pesante e la riproduzione di video si manifestano come normale carico della CPU. Il frame rate diminuisce invece di bloccare il sistema. È lo stesso limite che si incontra quando ci si chiede se sia possibile giocare su un VPS: llvmpipe può eseguire il rendering 3D, ma solo alla velocità consentita dalla CPU. Per attività che vanno oltre un uso 3D leggero, quindi, la risposta è no, proprio per questo motivo.
Audio e clipboard in una sessione xrdp
Ubuntu 24.04 usa PipeWire per l'audio, mentre il reindirizzamento audio di xrdp è stato sviluppato per PulseAudio. Per questo, una nuova installazione offre video funzionante ma nessun audio. Ubuntu include il bridge necessario.
sudo apt install -y pipewire-module-xrdp pulseaudio-utils alsa-utilsDisconnettiti completamente dalla sessione RDP e accedi di nuovo, perché il modulo viene caricato all'avvio della sessione. Riconnettersi non è sufficiente. Quindi verifica dall'interno della sessione:
pactl list short sinks
speaker-test -c 2 -t wav -l 1Dovresti vedere un sink il cui nome contiene xrdp e sentire il tono di prova tramite il client. Se non compare alcun sink xrdp, il modulo non è stato caricato in questa sessione. Anche il client deve richiedere l'audio: si tratta del flag /sound su xfreerdp3 oppure dell'impostazione "Audio remoto" nella sezione Risorse locali del client Windows.
Il clipboard di testo funziona in entrambe le direzioni quando xrdp-chansrv è in esecuzione per la sessione, cosa che xrdp gestisce automaticamente. Verificalo con pgrep -a xrdp-chansrv. Se il copia e incolla smette di funzionare durante una sessione, il processo si è arrestato e la riconnessione lo riavvia. Lo stesso canale del clipboard trasporta anche bitmap e file. Per esporre invece un'intera directory locale, usa il canale separato chiamato reindirizzamento delle unità: /drive:home,/home/you su xfreerdp3 monta una directory locale nella sessione remota.
Il popup di polkit e gli altri problemi al primo accesso
La sorpresa più comune al primo accesso è una finestra di dialogo con il messaggio Authentication is required to create a color managed device. La causa è specifica. Il servizio colord chiede a polkit l'autorizzazione. polkit concede automaticamente questa azione solo a una sessione che considera locale e attiva sulla console. Una sessione RDP non viene considerata tale, quindi polkit richiede una password. Ubuntu 24.04 include polkit 124, che legge i vecchi file dell'autorità locale .pkla solo tramite il pacchetto opzionale polkitd-pkla. polkitd si limita a suggerire questo pacchetto, quindi in genere un'installazione server non lo include. Di conseguenza, le guide che indicano di scrivere /etc/polkit-1/localauthority/50-local.d/45-allow-colord.pkla non hanno effetto su 24.04. Scrivete invece una regola JavaScript, che funziona con o senza quel pacchetto.
/* /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;
}
});Eseguite sudo systemctl restart polkit e riconnettetevi. È utile conoscere altri due problemi, riconoscibili dal relativo sintomo.
La finestra di accesso accetta la password e torna subito alla schermata iniziale. La sessione è stata avviata, ma si è chiusa subito. Leggete prima /var/log/xrdp-sesman.log, quindi ~/.xsession-errors nella directory home. Se manca xorgxrdp, se ~/.xsession indica un desktop non installato, se non potete scrivere nella directory home o se il disco è pieno, il risultato è lo stesso.
Vi connettete e vedete una schermata grigia con un cursore a forma di X. X è stato avviato, ma il desktop no. Anche in questo caso il problema riguarda ~/.xsession: eseguite manualmente xfce4-session tramite SSH e leggete l'errore visualizzato.
Cosa fa il server RustDesk self-hosted
RustDesk è composto da due processi. hbbs è il server ID e rendezvous a cui si registrano i client, mentre hbbr è il relay che trasporta la sessione quando una connessione peer-to-peer diretta non riesce. Nessuno dei due esegue un desktop. Entrambi provengono dalla stessa immagine. La documentazione del progetto pubblica ora un file compose che usa network_mode: "host". Questa versione mappa invece esplicitamente le porte, in modo che le porte esposte siano elencate nel file, e passa il nome host come indirizzo del relay tramite -r:
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-stoppedAvvialo, quindi leggi la chiave pubblica generata dal server al primo avvio:
sudo docker compose up -d
sudo cat ./data/id_ed25519.pubOgni client richiede il nome host e la chiave pubblica, da inserire entrambi nelle impostazioni Network del client RustDesk. La chiave privata corrispondente resta in ./data/id_ed25519. Se elimini la directory dei dati, il server genera una nuova coppia di chiavi; di conseguenza, ogni client deve essere riconfigurato con la nuova chiave. Esegui il backup di quella directory. Se questa diventa la modalità con cui il team accede a ogni macchina, invece di un esperimento per il fine settimana, vale la pena seguire una build dedicata del relay RustDesk per la gestione della chiave Ed25519, i tag delle immagini fissati invece di latest e la larghezza di banda del relay inclusa nel piano che finirai per pagare.
Il firewall deve consentire direttamente queste porte. hbbs usa le porte TCP 21115, 21116 e 21118, oltre alla porta UDP 21116. hbbr usa le porte TCP 21117 e 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/tcpPerché RustDesk non può essere pubblicato dietro un reverse proxy HTTP
Chi termina già TLS per tutti i servizi su un unico reverse proxy spesso prova questa configurazione e riscontra un errore. hbbs e hbbr usano protocolli binari propri su TCP e UDP, non HTTP. Non esiste un header Host su cui eseguire il routing né una richiesta HTTP da analizzare, quindi un blocco nginx server o un router HTTP di Traefik non ha alcun criterio di corrispondenza. Il listener UDP sulla porta 21116 non usa HTTP a nessun livello.
Sono possibili due soluzioni. nginx può inoltrare le porte TCP e la porta UDP 21116 tramite un blocco stream, mentre Traefik può fare lo stesso con i router TCP e UDP. Si tratta di un semplice inoltro a livello 4, non di un reverse proxy nel senso usuale: i byte passano senza modifiche e ogni porta richiede comunque un listener dedicato. Le porte 21118 e 21119 trasportano invece i websocket usati dal client web di RustDesk. Usano HTTP standard, quindi possono essere pubblicate dietro il proxy. In questo caso, aggiungere regole firewall per consentire l'accesso alle porte 21118 e 21119 soltanto al proxy, perché hbbs si basa sull'header X-Real-IP nelle connessioni websocket per determinare l'indirizzo reale del client.
Un browser temporaneo in un container
A volte serve soltanto un browser pulito, con un indirizzo IP stabile e isolato dal proprio computer. Un ambiente di lavoro in un container offre questa possibilità installando molto meno software. Webtop di LinuxServer è l'opzione più leggera:
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-stoppedLa porta 3000 serve HTTP e la porta 3001 serve HTTPS. È possibile accedere al desktop in una scheda del browser, senza alcun client RDP. I tag delle immagini includono XFCE, KDE, MATE e i3 su diverse distribuzioni di base, oltre a LXQt su Ubuntu. La documentazione del progetto segnala chiaramente il rischio: il container dispone di accesso privilegiato all'host e include un terminale con sudo senza password. Non deve quindi essere esposto a Internet senza protezioni. Per questo le porte precedenti sono associate a 127.0.0.1, invece di essere pubblicate su tutti gli indirizzi. È possibile raggiungerlo tramite lo stesso tunnel SSH o la stessa VPN usata per xrdp.
Kasm Workspaces applica lo stesso principio su scala molto più ampia. Include una console web, account utente e container separati per ogni sessione, che vengono ripristinati al termine della sessione. Richiede più risorse di quelle disponibili su un piccolo VPS. A ottobre 2026 il minimo indicato nella documentazione è di 2 core CPU, 4 GB di memoria e 75 GB di SSD. Ogni sessione utente richiede inoltre, per impostazione predefinita, 2 core e 2768 MB. Un piano da 2 GB non è sufficiente per eseguirlo. L'installazione consiste nel download, nel controllo del checksum e nell'esecuzione di uno script. Di seguito è mostrata la procedura per la release 1.19.0, quella corrente a ottobre 2026:
cd /tmp
curl -fO https://kasm-static-content.s3.amazonaws.com/kasm_release_1.19.0-latest.tar.gz
curl -fO https://kasm-static-content.s3.amazonaws.com/kasm_release_1.19.0-latest.tar.gz.sha256sum
sha256sum --check kasm_release_1.19.0-latest.tar.gz.sha256sum
tar -xf kasm_release_1.19.0-latest.tar.gz
sudo bash kasm_release/install.shVNC e i casi in cui è ancora adatto
VNC invia aggiornamenti del framebuffer invece di comandi di disegno, quindi su una connessione lenta risulta più pesante di RDP e non dispone di un canale audio. È utile in una situazione specifica: vuoi una sessione desktop che continui a funzionare dopo la disconnessione e vuoi ritrovare la stessa sessione quando torni. TigerVNC lo consente. vncserver -localhost yes :1 associa Xvnc a 127.0.0.1 sulla porta TCP 5901 e rifiuta le connessioni provenienti da qualsiasi altra origine, quindi puoi inoltrarlo tramite tunnel esattamente come xrdp usando ssh -N -L 5901:127.0.0.1:5901 you@vps.example.com. Non pubblicare mai una porta VNC. La maggior parte dei server VNC protegge la password durante l'handshake, ma non protegge il traffico successivo: su una porta pubblica, il contenuto della sessione è leggibile in rete.
Un VPS è adatto come desktop?
Come ambiente di lavoro quotidiano, no. I motivi sono diversi. Non c’è una GPU, quindi il rendering viene eseguito dalla CPU. Ogni pressione di un tasto attende un andata e ritorno di rete, e una latenza di 40 ms, che in SSH può sembrare trascurabile, si nota in un editor di testo. Il video viene compresso due volte: una dal sito e una dal codificatore RDP. I file risiedono su un disco che non controlli direttamente, e un uso intenso del desktop consuma il limite mensile di banda, dimensionato per un web server.
Come macchina temporanea è invece molto valido, e le stesse caratteristiche spiegano il motivo. L’indirizzo IP è stabile e appartiene a un data center: è ciò che serve quando un servizio deve rilevare sempre lo stesso indirizzo. La macchina viene ricreata da un’immagine in pochi minuti, quindi una sessione che ha acquisito qualcosa di dannoso non comporta costi rilevanti. È isolata dall’hardware reale e continua a funzionare quando chiudi il laptop. La fatturazione oraria rende economico un desktop usa e getta.
Se non hai ancora definito l’utilizzo del server, conviene leggere l’elenco pratico delle attività per cui un VPS è adatto prima di installarvi un desktop. Se invece volevi un desktop per eseguire una sola applicazione Windows, valuta prima le differenze effettive tra Linux e Windows Server, perché la licenza modifica il costo della soluzione.
FAQ
Posso eseguire un desktop remoto su un VPS da 2 GB?
Sì, con un desktop leggero. Dopo l'accesso, XFCE o LXQt utilizzano circa 300-400 MB, lasciando memoria sufficiente per un browser con alcune schede aperte. GNOME o KDE Plasma su 2 GB lasciano quasi nessuna memoria alle applicazioni. Aggiungi un file di swap da 2 GB, in modo che la pressione sulla memoria rallenti la macchina invece di terminare i processi. Se qualcosa scompare senza messaggi, controlla dmesg | grep -i "killed process" per verificare l'attività dell'out-of-memory killer del kernel.
Devo aprire la porta 3389 nel firewall del mio VPS?
No. La porta TCP 3389 viene sottoposta continuamente a scansioni e un endpoint RDP esposto invita a tentare password. Imposta port=tcp://.:3389 in /etc/xrdp/xrdp.ini, in modo che xrdp sia in ascolto solo su 127.0.0.1, verifica l'impostazione con ss -tlnp | grep 3389 e raggiungilo con ssh -N -L 3389:127.0.0.1:3389 you@vps.example.com. Per più di una o due persone, associa xrdp a un indirizzo WireGuard invece che all'interfaccia di loopback.
Perché xrdp visualizza il messaggio "Authentication is required to create a color managed device"?
Il servizio colord richiede a polkit l'autorizzazione, e polkit concede automaticamente questa operazione solo a una sessione locale con utente presente. Una sessione RDP non è considerata locale, quindi viene richiesta una password a ogni accesso. Su Ubuntu 24.04, la vecchia correzione .pkla non ha effetto se non è installato il pacchetto opzionale polkitd-pkla, perché polkit 124 legge i file delle autorizzazioni locali solo tramite questo backend. Crea /etc/polkit-1/rules.d/45-allow-colord.rules con una regola JavaScript che restituisca polkit.Result.YES per gli identificativi delle azioni che iniziano con org.freedesktop.color-manager., quindi esegui sudo systemctl restart polkit.
Posso eseguire un server RustDesk self-hosted dietro nginx o Traefik?
Non come servizio HTTP. hbbs e hbbr utilizzano protocolli binari propri invece di HTTP, quindi non esiste un header Host su cui eseguire il routing e UDP 21116 non può attraversare in alcun caso un proxy HTTP. Il forwarding di livello 4 funziona: un blocco nginx stream oppure i router TCP e UDP di Traefik possono inoltrare le porte senza modificarle. La configurazione più semplice consiste comunque nell'aprire nel firewall le porte TCP da 21115 a 21119 e la porta UDP 21116, lasciando che i client si connettano direttamente. Le porte WebSocket 21118 e 21119, utilizzate dal client web, usano HTTP e possono essere pubblicate dietro un proxy. In tal caso, configurale nel firewall in modo che solo il proxy possa raggiungerle, perché hbbs si fida di X-Real-IP per queste connessioni.