Escritorio remoto en un VPS Linux con xrdp
Instala XFCE y xrdp para usar un escritorio gráfico real en el VPS. Accede mediante un túnel SSH sin abrir el puerto 3389 y compara cuándo conviene RustDesk.
Qué significa realmente un escritorio remoto en un VPS Linux
Dos productos diferentes responden a la búsqueda «escritorio remoto en un VPS Linux», y elegir el incorrecto puede hacerle perder toda una tarde. El primero es un intermediario de acceso remoto. El servidor autohospedado de RustDesk es el ejemplo habitual: retransmite una sesión entre dos equipos que ya son suyos, como su portátil y el PC de casa. El servidor alquilado no muestra ningún escritorio. Presenta ambos extremos y reenvía los paquetes cuando no pueden comunicarse directamente. El segundo es un escritorio gráfico real que se ejecuta en el servidor alquilado, de modo que los píxeles se generan en el centro de datos y se transmiten hasta usted. Ese es el caso de xrdp, VNC (virtual network computing) o un espacio de trabajo en un contenedor.
Una pregunta permite distinguirlos. Cuando esto funciona, ¿dónde está el puntero del ratón? Si está en un equipo que ya posee, necesita un intermediario. Si está en el propio VPS, necesita un escritorio en el VPS. La segunda situación ocupa la mayor parte de lo que sigue, porque es la que la mayoría de las guías omiten.
Qué opción se adapta a su trabajo
- RustDesk con su propio relay. Protege la sesión para que no pase por un servidor público de rendezvous administrado por terceros, porque usted conserva el par de claves. No protege la máquina controlada, que sigue siendo el PC donde instaló el cliente, con la contraseña que tenga ese PC.
- xrdp mediante un túnel SSH o una VPN. Le protege frente al escaneo constante de Internet del puerto TCP 3389 y frente a los intentos de adivinar la contraseña del cuadro de inicio de sesión de RDP, porque ese puerto nunca queda expuesto a Internet. No protege una contraseña de cuenta débil frente a alguien que ya tenga acceso al túnel.
- VNC mediante el mismo túnel. Proporciona una sesión de escritorio que sobrevive a las desconexiones, mediante un protocolo más antiguo y sencillo que RDP. Por sí solo no protege nada: el túnel realiza todo el trabajo de seguridad, por lo que VNC solo en un puerto público es la peor opción de esta lista.
- Un workspace en un contenedor, como Webtop o Kasm. Proporciona un navegador o un escritorio completo dentro de un contenedor que puede eliminar y reconstruir, lo que protege su máquina real frente a cualquier elemento que ese navegador toque. No protege el host: estas imágenes se ejecutan con privilegios amplios y con un
sudosin contraseña en su interior, por lo que el contenedor no es un límite de seguridad en el que deba confiar para ejecutar cargas de trabajo hostiles.
Instalar xrdp y XFCE en Ubuntu 24.04
La imagen de un servidor VPS no incluye un escritorio gráfico. Primero debe instalar uno y después xrdp, el servidor de código abierto que utiliza RDP (protocolo de escritorio remoto), el mismo protocolo que utiliza el cliente de Windows. Elija un escritorio ligero. XFCE suele ser la opción habitual.
sudo apt update
sudo apt install -y xrdp xorgxrdp xfce4 xfce4-goodies dbus-x11
systemctl is-active xrdpUbuntu 24.04 incluye xrdp 0.9.24 y xorgxrdp en el componente universe, a fecha de agosto de 2026. Instale xorgxrdp por nombre aunque sólo sea un paquete recomendado: es el backend del servidor X que xrdp inicia para una sesión nueva. Sin él, el cuadro de inicio de sesión acepta la contraseña y después vuelve directamente al cuadro de inicio de sesión.
Ahora indique a la sesión qué escritorio debe iniciar. xrdp ejecuta /etc/xrdp/startwm.sh, que ejecuta ~/.xsession cuando existe ese archivo.
echo "xfce4-session" > ~/.xsession
chmod 644 ~/.xsessionPor último, xrdp necesita leer la clave TLS (seguridad de la capa de transporte) que ofrece a los clientes. Ese archivo tiene el modo 640 y pertenece al grupo ssl-cert.
ls -l /etc/ssl/private/ssl-cert-snakeoil.key
id xrdpLa salida muestra -rw-r----- 1 root ssl-cert. Si id xrdp no muestra ssl-cert entre los grupos, ejecute sudo adduser xrdp ssl-cert y después sudo systemctl restart xrdp. Si omite este paso, xrdp no podrá abrir la clave y /var/log/xrdp.log registrará el fallo con el nombre de archivo snakeoil en la línea.
Por qué no debe abrir el puerto 3389 a Internet
TCP 3389 recibe escaneos continuos desde Internet, y una pantalla de inicio de sesión de RDP responde de forma rutinaria a cada intento de contraseña. No lo abra. Enlace xrdp a la dirección de loopback y acceda mediante un túnel de confianza.
Edite /etc/xrdp/xrdp.ini y cambie el listener en la sección [Globals].
[Globals]
port=tcp://.:3389El archivo incluido documenta esa sintaxis en sus propios comentarios: tcp://.:3389 significa 127.0.0.1:3389, y tcp://:3389 significa todas las interfaces. Reinicie y confirme el resultado, porque un error tipográfico aquí puede dejar el servicio escuchando en todas las direcciones sin mostrar un error claro.
sudo systemctl restart xrdp
ss -tlnp | grep 3389Debe obtener 127.0.0.1:3389. Si ve 0.0.0.0:3389, xrdp ignoró el cambio, normalmente porque la línea terminó bajo otro encabezado de sección más abajo en el archivo.
Ahora abra el túnel desde su propio equipo.
ssh -N -L 3389:127.0.0.1:3389 you@vps.example.com-N significa «abrir la conexión, pero no ejecutar ningún comando», por lo que la sesión sólo transporta el puerto. Deje ese terminal abierto y configure el cliente RDP para conectarse a 127.0.0.1:3389. En un cliente Linux, el software es FreeRDP 3, cuyo binario en Ubuntu 24.04 se llama xfreerdp3:
sudo apt install -y freerdp3-x11
xfreerdp3 /v:127.0.0.1:3389 /u:you /dynamic-resolution +clipboard /soundEn Windows, use mstsc, incluido en el sistema, y escriba 127.0.0.1 como equipo. FreeRDP le pide que confíe en el certificado durante la primera conexión y muestra Do you trust the above certificate? (Y/T/N), algo esperado con el certificado snakeoil autofirmado.
Si ssh responde bind [127.0.0.1]:3389: Address already in use, algo en su propio equipo ya está usando 3389. Cambie el extremo local con ssh -N -L 13389:127.0.0.1:3389 you@vps.example.com y conéctese a 127.0.0.1:13389.
Un túnel por persona resulta poco práctico. Para un equipo, la mejor opción es una red privada. Coloque el equipo detrás de una VPN WireGuard autohospedada, asígnele la dirección del túnel 10.8.0.1 y establezca port=tcp://10.8.0.1:3389 para que xrdp responda sólo dentro de la VPN. En cualquier caso, no debe existir ninguna regla del firewall para 3389. Si no está seguro de qué permiten las reglas actuales, consulte los conceptos básicos del firewall ufw en un VPS y compruébelo antes de conectarse, no después.
Cuánta RAM usa un escritorio remoto en un VPS de 2 GB
El escritorio que elija determina si un plan de 2 GB resulta cómodo o inutilizable. Las cifras siguientes son valores típicos redondeados de memoria en uso justo después de iniciar sesión en Ubuntu 24.04. Proceden de comparativas publicadas y no de mediciones realizadas en su máquina. Mida el consumo real con free -m justo después de conectarse.
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"
}
]En esos 5 escritorios, la diferencia es lo importante. LXQt usa cerca de 300 MB y XFCE cerca de 400 MB, por lo que cualquiera de los dos deja espacio para un navegador en un equipo con 2 GB. GNOME necesita aproximadamente 1,200 MB antes de abrir una sola ventana. En un equipo con 2 GB, esto obliga al navegador a competir con el escritorio por la memoria restante.
El navegador es el coste real, no el shell del escritorio. Un navegador moderno consume entre 150 y 400 MB por pestaña activa. Por eso, un VPS de 2 GB con XFCE puede manejar unas pocas pestañas antes de empezar a usar swap. Añada swap para que la máquina se ralentice en lugar de terminar procesos: sudo fallocate -l 2G /swapfile, después sudo chmod 600 /swapfile, sudo mkswap /swapfile, sudo swapon /swapfile y una línea equivalente en /etc/fstab para que sobreviva a un reinicio. Si algo desaparece sin aviso, ejecute dmesg | grep -i "killed process". Esa línea indica que el killer de falta de memoria del kernel terminó el proceso. El navegador suele ser la víctima.
La CPU es el otro límite y es fácil subestimarlo. Un VPS no tiene GPU, por lo que X recurre a la renderización por software mediante llvmpipe. Esto significa que la CPU dibuja cada píxel. Desplazarse por una página pesada y reproducir vídeo aparecen como carga normal de CPU. La velocidad de fotogramas disminuye en lugar de que la máquina se bloquee. Ese es el mismo límite que encontrará si se pregunta si puede jugar en un VPS: para cualquier contenido 3D, la respuesta es no, precisamente por este motivo.
Sonido y portapapeles en una sesión de xrdp
Ubuntu 24.04 usa PipeWire, pero la redirección de sonido de xrdp se diseñó para PulseAudio. Por eso, una instalación nueva muestra vídeo, pero no emite sonido. Los paquetes de Ubuntu incluyen el puente.
sudo apt install -y pipewire-module-xrdp pulseaudio-utils alsa-utilsCierre por completo la sesión de RDP y vuelva a iniciar sesión. El módulo se carga cuando comienza la sesión. Reconectarse no es suficiente. Después, compruébelo desde dentro de la sesión:
pactl list short sinks
speaker-test -c 2 -t wav -l 1Debería ver un sink cuyo nombre mencione xrdp y oír el tono de prueba a través del cliente. Si no aparece ningún sink de xrdp, el módulo no se cargó en esta sesión. El cliente también debe solicitar audio: esa opción corresponde al indicador /sound de xfreerdp3, o a la configuración "Remote audio" de Local Resources en el cliente de Windows.
El portapapeles de texto funciona en ambas direcciones cuando xrdp-chansrv se está ejecutando para la sesión. xrdp lo inicia automáticamente. Confírmelo con pgrep -a xrdp-chansrv. Si copiar y pegar deja de funcionar durante una sesión, ese proceso terminó y al reconectarse se iniciará de nuevo. Copiar archivos en lugar de texto usa un canal independiente llamado redirección de unidades: /drive:home,/home/you en xfreerdp3 monta una carpeta local dentro de la sesión remota.
La ventana de polkit y otros fallos del primer inicio de sesión
La sorpresa más habitual durante el primer inicio de sesión es un cuadro de diálogo con el mensaje Authentication is required to create a color managed device. La causa es concreta. El servicio colord solicita permiso a polkit. polkit concede esa acción sin preguntar sólo a una sesión que considera local. Una sesión RDP no se considera local, por lo que polkit termina solicitando una contraseña. Ubuntu 24.04 incluye polkit 124, que eliminó los archivos antiguos de autoridad local .pkla. Por tanto, cualquier guía que indique crear /etc/polkit-1/localauthority/50-local.d/45-allow-colord.pkla no tiene ningún efecto en 24.04. En su lugar, cree una regla de 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;
}
});Ejecute sudo systemctl restart polkit y vuelva a conectarse. Conviene conocer otros dos fallos por sus síntomas.
El cuadro de inicio de sesión acepta la contraseña y vuelve a aparecer. La sesión se inició y terminó. Revise primero /var/log/xrdp-sesman.log y después ~/.xsession-errors en su directorio personal. La ausencia de xorgxrdp, un ~/.xsession que especifique un escritorio no instalado, un directorio personal en el que no pueda escribir o un disco lleno terminan provocando este comportamiento.
Se conecta y ve una pantalla gris con un cursor en forma de X. X se inició, pero el escritorio no. De nuevo se trata de ~/.xsession: ejecute xfce4-session manualmente mediante SSH y revise el error que muestra.
Qué hace el servidor RustDesk autoalojado
RustDesk se divide en dos procesos. hbbs es el servidor de ID y rendezvous al que se registran los clientes, y hbbr es el relay que transporta la sesión cuando falla una conexión directa entre pares. Ninguno de los dos ejecuta un escritorio. Ambos proceden de una sola imagen. Este es el archivo compose que publica el proyecto, con la dirección del relay cambiada por el nombre de host propio:
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-stoppedInícielo y lea la clave pública que el servidor generó durante el primer arranque:
sudo docker compose up -d
sudo cat ./data/id_ed25519.pubCada cliente necesita el nombre de host y esa clave pública. Ambos se introducen en Network settings del cliente RustDesk. La clave privada correspondiente permanece en ./data/id_ed25519. Si elimina el directorio de datos, el servidor genera un par nuevo. En ese caso, debe reconfigurar todos los clientes con la clave nueva. Haga una copia de seguridad de ese directorio. Si esta pasa a ser la forma habitual de su equipo de acceder a todas las máquinas, en lugar de un experimento de fin de semana, conviene seguir una compilación dedicada del relay RustDesk para gestionar las claves Ed25519, usar etiquetas de imagen fijadas en lugar de latest y tener en cuenta el ancho de banda del relay que finalmente incluya su plan.
El firewall debe permitir directamente estos puertos. hbbs usa TCP 21115, 21116 y 21118, además de UDP 21116. hbbr usa TCP 21117 y 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/tcpPor qué RustDesk no funciona detrás de nginx o Traefik
Los lectores que ya terminan TLS para todo en un único proxy inverso suelen probar esta configuración y fallan. hbbs y hbbr utilizan sus propios protocolos binarios sobre TCP y UDP, no HTTP. No existe ninguna cabecera Host que permita enrutar ni ninguna petición HTTP que inspeccionar, por lo que un bloque server de nginx o un router HTTP de Traefik no tienen nada que coincida. El listener UDP del puerto 21116 no es HTTP en ninguna capa.
Hay dos opciones que sí funcionan. nginx puede reenviar los puertos TCP mediante un bloque stream. Eso es un reenvío de capa 4, no un proxy inverso en el sentido habitual. Además, los puertos 21118 y 21119 transportan los websockets que utiliza el cliente web de RustDesk. Es tráfico HTTP normal, por lo que esos dos puertos pueden situarse detrás del proxy. Si lo hace, añada reglas de firewall para que sólo el proxy pueda acceder a 21118 y 21119, porque hbbs confía en la cabecera X-Real-IP de las conexiones websocket para determinar la dirección real del cliente.
Un navegador desechable en un contenedor
A veces sólo necesita un navegador limpio con una IP que no cambie, aislado de su propio equipo. Un espacio de trabajo en un contenedor lo permite con mucho menos software instalado. Webtop de LinuxServer es la opción ligera:
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-stoppedEl puerto 3000 sirve HTTP y el 3001 sirve HTTPS. Puede acceder al escritorio desde una pestaña del navegador sin usar ningún cliente RDP. Las etiquetas de imagen incluyen XFCE, KDE, MATE e i3 sobre varias distribuciones base. La documentación del propio proyecto advierte claramente del riesgo: el contenedor tiene acceso privilegiado al host e incluye un terminal con sudo sin contraseña. Por tanto, no debe exponerse a Internet sin protección. Por eso los puertos anteriores están vinculados a 127.0.0.1 en lugar de publicarse en todas las direcciones. Acceda a él mediante el mismo túnel SSH o la misma VPN que usó para xrdp.
Kasm Workspaces aplica la misma idea a una escala mucho mayor. Incluye una consola web, cuentas de usuario y contenedores por sesión que se restablecen cuando termina la sesión. Necesita más recursos de los que ofrece un VPS pequeño. En agosto de 2026, el mínimo documentado es de 2 núcleos de CPU, 4 GB de memoria y 50 GB de SSD. Además, cada sesión de usuario usa por defecto 2 núcleos y 2768 MB. Un plan de 2 GB no puede ejecutarlo. La instalación consiste en descargar un archivo y ejecutar un 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 y cuándo sigue siendo adecuado
VNC envía actualizaciones del framebuffer en lugar de comandos de dibujo. Por eso resulta más pesado que RDP en enlaces lentos y no incluye un canal de sonido. Tiene sentido en una situación: cuando quiere que una sesión de escritorio siga ejecutándose después de desconectarse y recuperar esa misma sesión al volver. TigerVNC lo permite. vncserver -localhost yes :1 vincula Xvnc a 127.0.0.1 en TCP 5901 y rechaza las conexiones desde cualquier otro lugar, por lo que debe tunelizarlo igual que xrdp con ssh -N -L 5901:127.0.0.1:5901 you@vps.example.com. Nunca publique un puerto de VNC. La mayoría de los servidores VNC protegen la contraseña durante el handshake, pero no protegen nada después. Por tanto, en un puerto público, el contenido de la sesión se puede leer en la red.
¿Es un VPS un buen equipo de escritorio?
Como equipo de uso diario, no. Los inconvenientes se acumulan. No hay GPU, así que la CPU procesa todo. Cada pulsación de tecla espera un viaje de ida y vuelta por la red, y una latencia de 40 ms que parece aceptable en SSH se nota en un editor de texto. El vídeo se comprime dos veces: una en el sitio web y otra en el codificador RDP. Los archivos están en un disco que no tiene físicamente, y el uso intensivo del escritorio consume una cuota mensual de ancho de banda dimensionada para un servidor web.
Como máquina desechable, es muy buena. Sus mismas características explican el motivo. La dirección IP es estable y pertenece a un centro de datos. Eso es lo que necesita un servicio que debe ver siempre una dirección coherente. La máquina se reconstruye a partir de una imagen en minutos. Por tanto, si una sesión adquiere algo malicioso, el coste es nulo. Está aislada de su hardware real y sigue ejecutándose cuando cierra el portátil. La facturación por horas hace que un escritorio desechable sea barato.
Si todavía está determinando para qué sirve la máquina, merece la pena leer la lista práctica de usos adecuados para un VPS antes de instalarle un escritorio. Y si quería un escritorio por una única aplicación de Windows, compare primero esa opción con las diferencias reales entre Linux y Windows Server, porque la licencia cambia el coste de la solución.
FAQ
¿Puedo ejecutar un escritorio remoto en un VPS de 2 GB?
Sí, con un escritorio ligero. XFCE o LXQt usan aproximadamente entre 300 y 400 MB después del inicio de sesión, lo que deja recursos suficientes para un navegador con varias pestañas. GNOME o KDE Plasma en 2 GB dejan muy pocos recursos para las aplicaciones. Añada un archivo de swap de 2 GB para que la presión de memoria ralentice la máquina en lugar de terminar los procesos. Si algo desaparece sin mostrar ningún mensaje, revise dmesg | grep -i "killed process" para comprobar si intervino el terminador de procesos por falta de memoria del kernel.
¿Debo abrir el puerto 3389 en el firewall de mi VPS?
No. TCP 3389 se analiza constantemente y exponer un cuadro de inicio de sesión RDP facilita los intentos de adivinar contraseñas. Establezca port=tcp://.:3389 en /etc/xrdp/xrdp.ini para que xrdp escuche sólo en 127.0.0.1, confírmelo con ss -tlnp | grep 3389 y acceda mediante ssh -N -L 3389:127.0.0.1:3389 you@vps.example.com. Para más de una o dos personas, vincule xrdp a una dirección de WireGuard en lugar de loopback.
¿Por qué xrdp muestra el mensaje "Authentication is required to create a color managed device"?
El servicio colord solicita permiso a polkit, y polkit concede esa acción sin solicitar contraseña sólo a una sesión local activa. Una sesión RDP no es una sesión local activa, por lo que aparece una solicitud de contraseña en cada inicio de sesión. En Ubuntu 24.04, la solución antigua .pkla no hace nada porque polkit 124 dejó de usar los archivos de autoridad local. Cree /etc/polkit-1/rules.d/45-allow-colord.rules con una regla JavaScript que devuelva polkit.Result.YES para los identificadores de acción que empiecen por org.freedesktop.color-manager. y ejecute después sudo systemctl restart polkit.
¿Puedo colocar un servidor RustDesk autohospedado detrás de nginx o Traefik?
No el servicio principal. hbbs y hbbr usan sus propios protocolos binarios en lugar de HTTP, por lo que no existe ninguna cabecera Host que permita enrutar las conexiones. Además, UDP 21116 no puede atravesar un proxy HTTP. Abra TCP 21115 a 21119 y UDP 21116 en el firewall, y permita que los clientes se conecten directamente. Los puertos websocket 21118 y 21119, que usa el cliente web, son HTTP y pueden situarse detrás de un proxy. Si lo hace, configure el firewall para que sólo el proxy pueda acceder a ellos, porque hbbs confía en X-Real-IP en esas conexiones.
¿Por qué no hay sonido en mi sesión xrdp?
Ubuntu 24.04 usa PipeWire, mientras que la redirección de sonido de xrdp se diseñó para PulseAudio. Por eso no hay audio hasta que instala el puente. Ejecute sudo apt install -y pipewire-module-xrdp. Después, cierre completamente la sesión y vuelva a iniciar sesión, porque el módulo se carga al iniciar la sesión y una reconexión no lo cargará. Compruebe con pactl list short sinks que exista un sink cuyo nombre incluya xrdp y asegúrese de que el cliente solicite audio. En xfreerdp3, esto corresponde a la opción /sound, o a "Remote audio" en el cliente de Windows.