Cómo alojar un relay de RustDesk en tu VPS
Configura hbbs y hbbr de RustDesk en tu VPS con clave Ed25519, etiquetas de imagen fijadas, puertos restringidos y cálculo del ancho de banda.
Qué es un servidor relay de RustDesk autohospedado
Un servidor relay de RustDesk autohospedado consta de dos daemons en un mismo VPS. hbbs es el servidor de ID y rendezvous: registra el ID de cada cliente y pone en contacto a dos clientes. hbbr es el servidor relay: transporta los bytes de la sesión, pero sólo en las sesiones que no pudieron comunicarse directamente. La mayoría de las guías instalan ambos, permiten emparejarlos y terminan ahí. Lo que sigue cubre el resto del trabajo: la clave que actúa como control de acceso, los puertos, la actualización y el ancho de banda.
Ambos daemons se distribuyen en la misma imagen, rustdesk/rustdesk-server, y ambos leen el mismo par de claves Ed25519 desde el mismo directorio. Ed25519 es un esquema de firma con clave pública. Ese par de claves determina con qué clientes se comunicará el servidor; no existe una base de datos de usuarios detrás.
hbbs y hbbr: qué daemon consume el ancho de banda
El tráfico de hbbs es reducido y constante: el registro de ID y los mensajes de latido, además del breve intercambio que presenta entre sí a dos pares. Se ejecuta todo el día y apenas consume ancho de banda.
El tráfico de hbbr es la propia sesión. Los fotogramas de pantalla viajan en una dirección, el teclado y el ratón en la otra, y cada byte retransmitido llega a su VPS y vuelve a salir de él. Si su proveedor contabiliza únicamente el tráfico saliente, una sesión retransmitida le cuesta aproximadamente la velocidad de la sesión. Si contabiliza la transferencia total, el coste es aproximadamente el doble.
El relay es una vía de reserva, no la ruta normal. Primero, hbbs intenta conectar directamente los dos clientes mediante hole punching a través del NAT (network address translation) situado delante de cada uno. Si funciona, la sesión nunca pasa por hbbr y no consume su cuota de transferencia. Si un extremo está detrás de un NAT que asigna un puerto nuevo para cada destino, o de un firewall que descarta la ruta creada mediante hole punching, la sesión recurre a hbbr y cada fotograma atraviesa su VPS.
Una variable de entorno elimina esta elección. ALWAYS_USE_RELAY=Y en hbbs fuerza todas las sesiones a pasar por hbbr. La documentación de RustDesk la muestra en uno de sus ejemplos de Compose, por lo que se copia con frecuencia. Hace que las conexiones sean más predecibles y convierte el tráfico saliente en un consumo real. Establézcala porque usted lo ha decidido, no porque la haya pegado sin más.
Qué puertos necesita un servidor RustDesk autohospedado
Los números de puerto siguientes se comprobaron con la documentación del servidor RustDesk y el repositorio rustdesk-server el 17 de agosto de 2026.
- TCP 21115, en hbbs: prueba del tipo de NAT.
- UDP 21116, en hbbs: registro del ID y señales de actividad. Sin este puerto, el cliente nunca aparece en línea, aunque los demás estén abiertos.
- TCP 21116, en hbbs: perforación de NAT mediante TCP y servicio de conexión.
- TCP 21117, en hbbr: relay. Este es el puerto que transporta los datos de las sesiones, por lo que es el puerto que genera costes.
- TCP 21118 en hbbs y TCP 21119 en hbbr: WebSocket, utilizado por el cliente del navegador. Mantenga ambos cerrados si no lo utiliza.
- TCP 21114 es la consola web de RustDesk Server Pro. La compilación de código abierto no escucha en este puerto.
Instale hbbs y hbbr con la etiqueta de imagen fijada
services:
hbbs:
container_name: hbbs
image: rustdesk/rustdesk-server:1.1.16
command: hbbs
volumes:
- ./data:/root
network_mode: "host"
depends_on:
- hbbr
restart: unless-stopped
hbbr:
container_name: hbbr
image: rustdesk/rustdesk-server:1.1.16
command: hbbr -k _
volumes:
- ./data:/root
network_mode: "host"
restart: unless-stoppedmkdir -p ~/rustdesk
cd ~/rustdesk
# save the block above as ~/rustdesk/compose.yml before this line
sudo docker compose up -d
sudo docker compose psAmbos servicios deben leer running. Confirme que los listeners existan antes de modificar el firewall.
sudo ss -tlnp | grep -E ':2111[5-7]'
sudo ss -ulnp | grep ':21116'Debería ver listeners TCP en 21115, 21116 y 21117, y un listener UDP en 21116. Si falta la línea UDP, hbbs no se está ejecutando, porque ese listener es contra el que se registran los clientes.
Hay cuatro aspectos deliberados en ese archivo. La etiqueta es 1.1.16, la versión actual en agosto de 2026, publicada el 20 de julio de 2026, en lugar de latest, porque latest significa lo último que se haya publicado y un docker compose pull dentro de seis meses puede proporcionarle un servidor que nunca haya probado. network_mode: "host" enlaza directamente las interfaces del host. Es lo que recomienda la documentación de RustDesk y determina cómo se comporta el firewall. ./data:/root asigna el directorio de trabajo de la imagen al host, de modo que el par de claves queda en una ubicación de la que puede hacer copias de seguridad. hbbr -k _ es el único cambio respecto al ejemplo original, porque la configuración predeterminada deja el relay abierto a cualquiera. Si Compose es nuevo para usted, ejecutar Docker Compose en un VPS explica el formato del archivo y los comandos del ciclo de vida.
Si hbbr se traslada alguna vez a un segundo servidor, debe indicar a hbbs dónde se encuentra: pase -r relay.example.com:21117 o establezca la variable de entorno RELAY-SERVERS. En un único servidor no es necesario.
El par de claves Ed25519 controla el acceso
En el primer arranque, hbbs genera id_ed25519 y id_ed25519.pub en su directorio de trabajo. Con el montaje anterior, ambos archivos aparecen en el host.
ls -l ~/rustdesk/data/
sudo cat ~/rustdesk/data/id_ed25519.pubid_ed25519.pub contiene una cadena base64. Esa cadena se introduce en el campo Key de todos los clientes. id_ed25519 es la parte privada y nunca sale del servidor. La clave pública no es un secreto, porque se copia en la configuración de todos los clientes. La clave privada sí es secreta: cualquiera que la tenga puede poner en marcha un servidor en el que confiarían sus clientes.
Haga una copia de seguridad de ambos archivos ahora, antes de configurar veinte clientes.
sudo tar czf ~/rustdesk-keys.tgz -C ~/rustdesk/data id_ed25519 id_ed25519.pub
sudo chmod 600 ~/rustdesk-keys.tgzCopie ese archivo comprimido fuera del servidor. Este es el motivo por el que este paso importa más que cualquier otro. Si elimina ~/rustdesk/data o reconstruye el servidor en un VPS nuevo sin copiarlo, hbbs genera un par de claves nuevo en el siguiente arranque. Todos los clientes siguen teniendo la clave pública antigua, por lo que hbbs la rechaza y el cliente queda desconectado. Ejecute sudo cat ~/rustdesk/data/id_ed25519.pub y compárelo con el campo Key de cualquier cliente: las dos cadenas ya no coinciden, y esa discrepancia es la causa completa del fallo. Para corregirlo, debe editar la configuración manualmente en cada máquina, incluidas las máquinas a las que confiaba en acceder mediante RustDesk.
La clave no es la contraseña de sesión. Confundir ambas hace que algunas personas omitan una de ellas. La clave determina con qué clientes se comunicará el servidor. La contraseña permanente o el código de un solo uso de la máquina controlada determina quién puede abrir una sesión en esa máquina. Necesita ambas cosas. Tener una no compensa que la otra sea débil.
Por qué un relay sin autenticación es un problema
De forma predeterminada, hbbr no comprueba nada. La documentación de configuración de RustDesk lo indica directamente: una clave vacía permite que los clientes sin una clave coincidente usen el relay. El valor predeterminado vacío existe para que los usuarios nuevos no encuentren errores de incompatibilidad de claves durante la primera ejecución. El coste es que cualquiera que encuentre tu dirección en TCP 21117 puede enviar el tráfico de su sesión a través de tu VPS, consumiendo tu cuota de transferencia y usando tu dirección IP.
command: hbbr -k _ lo soluciona. El argumento _ indica a hbbr que cargue un par de claves desde su directorio de trabajo. Como ambos contenedores montan el mismo ./data, ese es el par que hbbs ya generó. No se copia nada manualmente, por lo que las claves no pueden quedar desincronizadas.
El volumen compartido es la parte que suele configurarse mal. Si asignas a hbbr su propio directorio, genera un par de claves diferente. Entonces hbbs y hbbr no coinciden, todas las sesiones retransmitidas fallan y las sesiones directas siguen funcionando. El síntoma resulta confuso: RustDesk llega a algunos pares y no a otros, según que el hole punching haya tenido éxito. Un solo ls -l ~/rustdesk/data/ que muestre un único par de id_ed25519 descarta este problema.
Indique el servidor a los clientes
En cada equipo, abra RustDesk y vaya a Settings, después a Network y, por último, a ID/Relay Server.
- ID Server: el nombre de host, por ejemplo
rustdesk.example.com. El cliente usa el puerto 21116, salvo que escriba otro. - Relay Server: déjelo vacío cuando hbbr se ejecute en el mismo host que hbbs.
- API Server: déjelo vacío. El servidor de código abierto no proporciona este servicio.
- Key: la cadena base64 de
id_ed25519.pub, pegada exactamente y sin espacios finales.
La ventana principal debería indicar que el cliente está listo. Si no lo indica, UDP 21116 no está llegando a hbbs, porque el registro y el heartbeat funcionan mediante UDP y ningún otro componente activa el ID.
Restringir los puertos para que el relay no sea un servicio expuesto
Como los contenedores usan la red del host, no hay ninguna regla NAT de Docker delante de ellos, por lo que las reglas de ufw se aplican como espera.
sudo ufw allow 22/tcp
sudo ufw allow 21115:21117/tcp
sudo ufw allow 21116/udp
sudo ufw enable
sudo ufw status numberedAñada 21118:21119/tcp sólo si ejecuta el cliente de navegador. Mantenga abierta una segunda sesión SSH mientras habilita ufw, para que un error en la regla SSH no le bloquee el acceso a su propio servidor. Conceptos básicos del firewall ufw para un VPS explica las políticas predeterminadas y el orden de las reglas.
Aquí está el problema. Si cambia a la publicación de puertos mediante un bloque ports:, como hace el ejemplo de la imagen alternativa de supervisor de RustDesk, Docker escribe sus propias reglas DNAT y los paquetes llegan al contenedor sin pasar por la cadena en la que se encuentran las reglas de ufw. Por tanto, una denegación de ufw en 21117 no tiene efecto, y el relay queda expuesto a Internet aunque ufw status indique lo contrario. Los puertos publicados por Docker omiten ufw explica el orden de las cadenas. La red del host evita completamente el problema. Si publica un puerto, vincúlelo a una sola dirección, como en "127.0.0.1:21118:21118" detrás de un reverse proxy.
La restricción por dirección de origen sólo funciona cuando los clientes tienen direcciones estables.
sudo ufw allow from 203.0.113.0/24 to any port 21115:21117 proto tcp
sudo ufw allow from 203.0.113.0/24 to any port 21116 proto udpLos portátiles conectados a redes de hoteles no tienen direcciones estables. Por eso la clave de hbbr desempeña aquí una función más importante que el firewall.
Actualizar la pila que contiene la clave
La clave se encuentra en el bind mount, no dentro del contenedor. Por tanto, la actualización es segura siempre que no modifique ./data.
- Haga primero una copia de seguridad del directorio de datos:
sudo tar czf ~/rustdesk-data-backup.tgz -C ~/rustdesk data. - Lea las notas de la versión de la nueva etiqueta en la página de versiones de rustdesk-server.
- Edite
compose.ymly cambie las dos líneasimage:a la nueva etiqueta. - Ejecute
sudo docker compose pully, después,sudo docker compose up -d. - Ejecute
sudo cat ~/rustdesk/data/id_ed25519.puby confirme que la cadena coincide con la que ya tienen los clientes.
El paso 5 es la comprobación importante. Una clave modificada no genera avisos en el servidor y desconecta todos los clientes al mismo tiempo. Para revertir el cambio, vuelva a especificar la etiqueta anterior y ejecute up -d de nuevo. Esto sólo funciona porque fijó la etiqueta: con latest, docker compose pull movió el nombre a la nueva imagen, por lo que ya no queda ninguna etiqueta que identifique la anterior.
La forma habitual de perder la clave no es docker compose down, que deja intacto el bind mount. Lo habitual es migrar a un VPS nuevo y copiar sólo compose.yml. Copie también ./data.
Supervise el tráfico saliente en un plan con una cuota de transferencia
hbbr es la única parte de esta pila que puede consumir una cuota de transferencia. La sección de preguntas frecuentes de RustDesk sitúa una conexión retransmitida en una pantalla de 1920x1080 entre 30 KB/s y 3 MB/s, y el trabajo de oficina normal alrededor de 100 KB/s. Son cifras publicadas para una sola sesión, no una medición de su configuración. Proyectadas durante sesenta horas al mes, dos horas al día, quedan así.
The data behind this chart
[
{
"label": "Low end, 30 KB/s",
"gb_per_month": 6.5
},
{
"label": "Office work, 100 KB/s",
"gb_per_month": 21.6
},
{
"label": "High end, 3 MB/s",
"gb_per_month": 648
}
]Con la tasa de trabajo de oficina, una sesión consume aproximadamente 21.6 GB al mes, una cantidad que ningún plan notará. En el extremo superior del intervalo publicado, las mismas sesenta horas consumen 648 GB, y dos sesiones simultáneas a esa tasa superan una cuota de 1 TB dentro del mes. El extremo inferior es de 6.5 GB. Aquí, los gigabytes equivalen a 1000 MB, que es la forma habitual de contabilizar las cuotas de transferencia.
docker stats no desglosa este tráfico, porque un contenedor que usa la red del host comparte el espacio de nombres de red del host, por lo que sus contadores son los contadores del host. Hay otras dos herramientas que sí sirven. vnstat mide todo el servidor:
sudo apt install -y vnstat
sudo systemctl enable --now vnstat
vnstat -mTodo el servidor significa todo el servidor: si este VPS también ejecuta algo que mueve datos reales, por ejemplo uno de los servidores de fotos autoalojados que cada noche carga las bibliotecas de los teléfonos, esas cargas se contabilizan en la misma cuota mensual que el tráfico de retransmisión. Un servidor multimedia presenta el mismo problema en sentido contrario, porque algo como Halcyon, que convierte una biblioteca de Jellyfin en una videoteca de los años 90 que se puede explorar transmite contenido a quien lo está viendo, y ese tráfico saliente consume la misma cuota de la que depende la retransmisión.
Un contador de nftables mide específicamente la retransmisión:
sudo nft add table inet relaymeter
sudo nft add chain inet relaymeter out '{ type filter hook output priority 0 ; }'
sudo nft add rule inet relaymeter out tcp sport 21117 counter
sudo nft list table inet relaymeterEsa regla no aplica ninguna decisión, por lo que cuenta los paquetes y bytes sin modificar lo que está permitido. Además, se encuentra en una tabla independiente y no interfiere con ufw. No es persistente: coloque las mismas líneas en /etc/nftables.conf si quiere recuperarla después de un reinicio. El contador sólo aumenta mientras se está retransmitiendo una sesión. Si sigue aumentando cuando ninguno de sus equipos está conectado, significa que alguien más ha encontrado su relay. Ese es precisamente el caso que hbbr -k _ evita. Como no revisará nft list todas las mañanas, configure una tarea de cron que compare el recuento de bytes con un umbral y envíe una alerta push cuando lo supere. Para ello puede usar su propio servidor ntfy.
hbbr también tiene límites de velocidad que puede reducir. SINGLE_BANDWIDTH usa de forma predeterminada 128 Mb/s por conexión retransmitida y TOTAL_BANDWIDTH usa 1024 Mb/s para todas ellas. Al establecer SINGLE_BANDWIDTH=8, una sesión queda limitada a cerca de 1 MB/s. Esto limita la velocidad, no el total mensual. Úselo para evitar que una sesión sature el enlace, no como control del presupuesto.
Cuando no necesita ningún relay
En una configuración personal, la respuesta directa es que quizá no necesite nada de esto. Conecte ambas máquinas a una VPN en malla y conéctese directamente a la dirección del túnel. No habrá hbbs, hbbr, tráfico de salida por relay ni ningún contenedor en un VPS que actualizar.
En la máquina que quiere controlar, habilite el acceso IP directo en la configuración de seguridad de RustDesk. El campo del puerto tiene el valor predeterminado 21118. Compruebe que esté escuchando antes de intentar conectarse:
ss -tlnp | grep 21118Después, conéctese a la dirección VPN de ese peer en lugar de usar un ID. La FAQ de RustDesk indica que la conexión de este modo no está cifrada, por lo que debe ejecutarlo dentro del túnel y nunca a través de Internet abierta. El túnel es el que proporciona el cifrado.
Elija según quién sea el propietario de las máquinas. Un hbbs y un hbbr autohospedados son adecuados cuando administra máquinas que no son suyas o equipos de personas que nunca instalarán un cliente VPN, porque en su lado de la configuración sólo necesitan un ID y una contraseña. Una VPN en malla con acceso IP directo es adecuada cuando todas las máquinas le pertenecen y pueden usar una clave. WireGuard comparado con Tailscale explica las dos formas habituales de crear esa malla, y ejecutar un escritorio remoto en un VPS Linux cubre el otro caso: cuando la máquina en la que quiere ver una pantalla es el propio servidor.
FAQ
¿Todas las sesiones de RustDesk pasan por mi relay?
No. hbbs intenta conectar primero los dos clientes directamente mediante hole punching a través del NAT situado delante de cada uno. Sólo las sesiones en las que falla este intento recurren a hbbr, y sólo esas consumen ancho de banda. La excepción es ALWAYS_USE_RELAY=Y en hbbs, que obliga a pasar todas las sesiones por hbbr aunque exista una ruta directa. Si esa variable está definida en el archivo Compose, cada byte de todas las sesiones se incluye en la facturación de transferencia.
¿Dónde se almacena la clave del servidor RustDesk y qué ocurre si la pierdo?
hbbs genera id_ed25519 y id_ed25519.pub en su directorio de trabajo durante el primer arranque. Ese directorio es /root dentro de la imagen oficial, por lo que, con el montaje de volumen mostrado arriba, los archivos aparecen en ./data en el host. Haga una copia de seguridad de ambos archivos fuera del servidor. Si se pierden, hbbs genera un nuevo par durante el siguiente arranque y rechaza a todos los clientes que todavía tengan la clave pública antigua. No hay otra forma de recuperarla que editar manualmente el campo Key en cada cliente.
¿Qué puertos debo abrir para un servidor RustDesk autohospedado?
TCP 21115, 21116 y 21117, además de UDP 21116. hbbs usa 21115 para la prueba del tipo de NAT y 21116 para el registro de ID y los latidos mediante UDP, así como para el hole punching mediante TCP. hbbr usa 21117 para el relay. TCP 21118 y 21119 son los puertos WebSocket del cliente de navegador, así que manténgalos cerrados si no lo utiliza. TCP 21114 pertenece a la consola web Pro y la compilación de código abierto no lo necesita.
¿Pueden utilizar desconocidos mi relay RustDesk autohospedado?
Sí, si ejecuta hbbr con su configuración predeterminada. La documentación de RustDesk indica que una clave vacía permite utilizar el relay a clientes que no tengan una clave coincidente, por lo que cualquiera que conozca su nombre de host y el puerto 21117 puede dirigir tráfico a través del servidor. Ejecute hbbr con -k _ para que cargue el mismo par de claves que generó hbbs en el volumen compartido ./data. Después, sólo los clientes configurados con su clave pública podrán usar su relay.