Comment auto-héberger un relais RustDesk sur un VPS
Déployez hbbs et hbbr sur votre VPS avec la clé Ed25519, des tags d’image figés, des ports limités et la bande passante de relais réellement facturée.
Ce qu’est un serveur relais RustDesk auto-hébergé
Un serveur relais RustDesk auto-hébergé se compose de deux démons sur un même VPS. hbbs est le serveur d’identifiants et de rendez-vous : il enregistre l’identifiant de chaque client et met deux clients en relation. hbbr est le serveur relais : il transporte les données de session, mais uniquement pour les sessions qui ne peuvent pas communiquer directement. La plupart des guides installent les deux composants, établissent la connexion entre eux, puis s’arrêtent là. La suite couvre le reste : la clé qui contrôle l’accès, les ports, la mise à niveau et la bande passante.
Les deux démons sont fournis dans la même image, rustdesk/rustdesk-server, et lisent la même paire de clés Ed25519 dans le même répertoire. Ed25519 est un mécanisme de signature à clé publique. Cette paire de clés détermine avec quels clients votre serveur communiquera. Il n’existe pas de base de données utilisateurs derrière ce mécanisme.
hbbs et hbbr : quel daemon consomme votre bande passante
Le trafic de hbbs est faible et constant : enregistrement des ID et heartbeats, ainsi que le bref échange qui présente deux pairs. Il fonctionne toute la journée et ne coûte presque rien.
Le trafic de hbbr correspond à la session elle-même. Les images d’écran circulent dans un sens, le clavier et la souris dans l’autre, et chaque octet relayé arrive sur votre VPS avant d’en repartir. Si votre fournisseur ne facture que le trafic sortant, une session relayée vous coûte environ le débit de la session. S’il facture le volume total transféré, le coût est environ deux fois supérieur.
Le relais est une solution de secours, pas le chemin normal. hbbs essaie d’abord de connecter directement les deux clients, en utilisant le hole punching à travers le NAT (network address translation) situé devant chacun d’eux. Lorsque cette méthode fonctionne, la session ne passe jamais par hbbr et votre quota de transfert reste intact. Lorsque l’un des côtés se trouve derrière un NAT qui attribue un nouveau port à chaque destination, ou derrière un pare-feu qui bloque le chemin créé par le hole punching, la session bascule sur hbbr et chaque image traverse votre VPS.
Une variable d’environnement supprime ce choix. ALWAYS_USE_RELAY=Y sur hbbs force toutes les sessions à passer par hbbr. La documentation de RustDesk la montre dans l’un de ses exemples Compose, ce qui explique qu’elle soit souvent copiée. Elle rend les connexions plus prévisibles et rend votre trafic sortant bien réel. Définissez-la parce que vous l’avez décidé, et non parce que vous l’avez copiée-collée.
Ports nécessaires pour un serveur RustDesk auto-hébergé
Les numéros de port ci-dessous ont été vérifiés dans la documentation du serveur RustDesk et le dépôt rustdesk-server le 17 août 2026.
- TCP 21115, sur hbbs : test du type de NAT.
- UDP 21116, sur hbbs : enregistrement de l’ID et heartbeat. Sans ce port, le client ne se connecte jamais, quels que soient les autres ports ouverts.
- TCP 21116, sur hbbs : TCP hole punching et service de connexion.
- TCP 21117, sur hbbr : relay. C’est le port qui transporte les données de session. C’est donc celui qui génère du trafic réseau.
- TCP 21118 sur hbbs et TCP 21119 sur hbbr : WebSocket, utilisé par le client dans le navigateur. Laissez ces deux ports fermés si vous ne l’utilisez pas.
- TCP 21114 est la console web de RustDesk Server Pro. La version open source n’écoute pas sur ce port.
Installer hbbs et hbbr avec le tag d’image épinglé
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 psLes deux services doivent lire running. Vérifiez que les listeners sont présents avant de modifier le firewall.
sudo ss -tlnp | grep -E ':2111[5-7]'
sudo ss -ulnp | grep ':21116'Vous devez voir des listeners TCP sur 21115, 21116 et 21117, ainsi qu’un listener UDP sur 21116. Si la ligne UDP est absente, hbbs ne fonctionne pas, car les clients s’enregistrent auprès de ce listener.
Quatre éléments de ce fichier sont définis volontairement. Le tag est 1.1.16, la version actuelle en août 2026, publiée le 20 juillet 2026, et non latest, car latest signifie que la version la plus récemment publiée sera utilisée. Un docker compose pull dans six mois peut ainsi vous fournir un serveur que vous n’avez jamais testé. network_mode: "host" lie directement les interfaces de l’hôte, conformément aux recommandations de la documentation RustDesk, et détermine le comportement de votre firewall. ./data:/root mappe le répertoire de travail de l’image sur l’hôte afin que la paire de clés soit stockée à un emplacement que vous pouvez sauvegarder. Enfin, hbbr -k _ est la seule modification par rapport à l’exemple upstream, car la configuration par défaut laisse votre relay ouvert à tout le monde. Si Compose est nouveau pour vous, exécuter Docker Compose sur un VPS présente le format du fichier et les commandes de gestion du cycle de vie.
Si hbbr est déplacé sur un second serveur, hbbs doit savoir où il se trouve : transmettez -r relay.example.com:21117 ou définissez la variable d’environnement RELAY-SERVERS. Sur un serveur unique, ce n’est pas nécessaire.
La paire de clés Ed25519 contrôle l’accès
Au premier démarrage, hbbs génère id_ed25519 et id_ed25519.pub dans son répertoire de travail. Avec le montage ci-dessus, les deux fichiers apparaissent sur l’hôte.
ls -l ~/rustdesk/data/
sudo cat ~/rustdesk/data/id_ed25519.pubid_ed25519.pub contient une chaîne encodée en base64. Cette chaîne doit être renseignée dans le champ Key de chaque client. id_ed25519 est la partie privée et ne quitte jamais le serveur. La clé publique n’est pas un secret, puisqu’elle est copiée dans la configuration de chaque client. La clé privée est un secret : toute personne qui la détient peut mettre en place un serveur auquel vos clients feront confiance.
Sauvegardez les deux fichiers maintenant, avant d’avoir configuré vingt clients.
sudo tar czf ~/rustdesk-keys.tgz -C ~/rustdesk/data id_ed25519 id_ed25519.pub
sudo chmod 600 ~/rustdesk-keys.tgzCopiez cette archive hors du serveur. Voici pourquoi cette étape est plus importante que toutes les autres. Si vous supprimez ~/rustdesk/data ou reconstruisez le serveur sur un nouveau VPS sans le copier, hbbs génère une nouvelle paire de clés au démarrage suivant. Chaque client contient toujours l’ancienne clé publique. hbbs la refuse donc et le client passe hors ligne. Exécutez sudo cat ~/rustdesk/data/id_ed25519.pub et comparez sa sortie au champ Key d’un client : les deux chaînes ne correspondent plus, et cette différence explique entièrement la panne. Pour corriger le problème, vous devez modifier les paramètres manuellement sur chaque machine, y compris celles auxquelles vous comptiez accéder avec RustDesk.
La clé n’est pas le mot de passe de session. Les confondre conduit à négliger l’un des deux. La clé détermine avec quels clients votre serveur communiquera. Le mot de passe permanent ou le code à usage unique sur la machine contrôlée détermine qui peut ouvrir une session sur cette machine. Vous avez besoin des deux. La présence de l’un ne compense pas la faiblesse de l’autre.
Pourquoi un relais sans authentification pose problème
Par défaut, hbbr ne vérifie rien. La documentation de configuration de RustDesk l’indique clairement : une clé vide autorise les clients qui ne possèdent pas de clé correspondante à utiliser le relais. Cette valeur vide par défaut évite que les nouveaux utilisateurs rencontrent une erreur de clé incompatible lors de la première exécution. En contrepartie, toute personne qui découvre votre adresse sur TCP 21117 peut faire transiter le trafic de sa session par votre VPS, en utilisant votre quota de transfert et votre adresse IP.
command: hbbr -k _ règle ce problème. L’argument _ indique à hbbr de charger une paire de clés depuis son répertoire de travail. Comme les deux conteneurs montent le même ./data, il s’agit de la paire déjà générée par hbbs. Rien n’est copié manuellement, donc aucune divergence ne peut apparaître.
Le volume partagé est le point qui pose le plus souvent problème. Si vous donnez à hbbr son propre répertoire, il génère une paire de clés différente. hbbs et hbbr n’utilisent alors pas la même paire, toutes les sessions relayées échouent et les sessions directes continuent de fonctionner. Le symptôme est déroutant : RustDesk atteint certains pairs, mais pas d’autres, selon que le hole punching a réussi ou non. Un seul ls -l ~/rustdesk/data/ contenant une paire id_ed25519 unique permet d’écarter ce problème.
Dirigez les clients vers votre serveur
Sur chaque machine, ouvrez RustDesk, puis Settings, Network et ID/Relay Server.
- ID Server : le nom d’hôte de votre serveur, par exemple
rustdesk.example.com. Le client utilise le port 21116, sauf si vous en indiquez un autre. - Relay Server : laissez ce champ vide si hbbr s’exécute sur le même hôte que hbbs.
- API Server : laissez ce champ vide. Le serveur open source n’en fournit pas.
- Key : la chaîne base64 obtenue avec
id_ed25519.pub, collée exactement, sans espace final.
La fenêtre principale doit alors indiquer que le client est prêt. Si ce n’est pas le cas, UDP 21116 n’atteint pas hbbs, car l’enregistrement et les heartbeats utilisent UDP et rien d’autre ne rend l’ID disponible.
Restreindre les ports pour que le relais ne soit pas un service ouvert
Comme les conteneurs utilisent le réseau de l’hôte, aucune règle NAT Docker ne se trouve devant eux. Les règles ufw s’appliquent donc comme prévu.
sudo ufw allow 22/tcp
sudo ufw allow 21115:21117/tcp
sudo ufw allow 21116/udp
sudo ufw enable
sudo ufw status numberedAjoutez 21118:21119/tcp uniquement si vous utilisez le client navigateur. Gardez une deuxième session SSH ouverte pendant l’activation de ufw. Ainsi, une erreur dans la règle SSH ne vous bloquera pas l’accès à votre propre serveur. Les bases du pare-feu ufw pour un VPS présente les stratégies par défaut et l’ordre des règles.
Voici le piège. Si vous publiez les ports avec un bloc ports:, comme dans l’exemple d’image RustDesk supervisor alternatif, Docker écrit ses propres règles DNAT. Les paquets atteignent alors le conteneur sans passer par la chaîne où résident vos règles ufw. Un refus ufw sur 21117 reste donc sans effet, et le relais est ouvert sur Internet alors que ufw status affirme le contraire. Les ports publiés par Docker contournent ufw explique l’ordre des chaînes. Le réseau de l’hôte évite entièrement ce problème. Si vous publiez un port, liez-le à une seule adresse, comme avec "127.0.0.1:21118:21118" derrière un reverse proxy.
La restriction par adresse source ne fonctionne que si vos clients disposent d’adresses stables.
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 udpLes ordinateurs portables connectés aux réseaux des hôtels n’ont pas d’adresses stables. C’est précisément pourquoi la clé sur hbbr joue ici un rôle plus important que le pare-feu.
Mettre à niveau une stack qui contient votre clé
La clé se trouve dans le bind mount, pas dans le conteneur. La mise à niveau est donc sûre tant que vous ne modifiez pas ./data.
- Sauvegardez d’abord le répertoire de données :
sudo tar czf ~/rustdesk-data-backup.tgz -C ~/rustdesk data. - Consultez les notes de version du nouveau tag sur la page des releases de rustdesk-server.
- Modifiez
compose.ymlet remplacez les deux lignesimage:par le nouveau tag. - Exécutez
sudo docker compose pull, puissudo docker compose up -d. - Exécutez
sudo cat ~/rustdesk/data/id_ed25519.pubet vérifiez que la chaîne correspond à celle que vos clients possèdent déjà.
L’étape 5 est le contrôle important. Une clé modifiée ne produit aucun message visible sur le serveur et interrompt tous les clients au même moment. Pour revenir en arrière, remettez l’ancien tag, puis exécutez à nouveau up -d. Cela ne fonctionne que parce que vous avez fixé le tag : avec latest, docker compose pull a associé le nom à la nouvelle image. Il ne reste donc aucun tag qui désigne l’ancienne image.
La cause habituelle de la perte de la clé n’est pas docker compose down, qui ne modifie pas un bind mount. C’est la migration vers un nouveau VPS avec la copie de compose.yml seulement. Copiez également ./data.
Surveillez le trafic sortant d’une offre avec quota de transfert
hbbr est le seul composant de cette stack susceptible de consommer le quota de transfert. La FAQ de RustDesk estime le débit d’une connexion relayée sur un écran 1920x1080 entre 30 KB/s et 3 MB/s, et le situe autour de 100 KB/s pour un usage bureautique classique. Ces chiffres sont publiés pour une session unique. Ils ne mesurent pas votre installation. Sur soixante heures par mois, à raison de deux heures par jour, cela donne les valeurs suivantes.
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
}
]Avec le débit d’un usage bureautique, une session consomme environ 21.6 GB par mois. Aucune offre ne le remarquera. Au débit maximal publié, les mêmes soixante heures consomment 648 GB. Deux sessions simultanées à ce débit dépassent un quota de 1 TB au cours du mois. La valeur basse est de 6.5 GB. Ici, un gigaoctet correspond à 1000 MB, comme c’est généralement le cas pour les quotas de transfert.
docker stats ne détaillera pas cette consommation, car un conteneur utilisant le host networking partage le network namespace de l’hôte. Ses compteurs sont donc ceux de l’hôte. Deux autres outils sont utilisables. vnstat mesure l’ensemble de la machine :
sudo apt install -y vnstat
sudo systemctl enable --now vnstat
vnstat -mL’ensemble de la machine signifie bien l’ensemble de la machine. Si ce VPS exécute aussi un service qui transfère réellement des données, par exemple l’un des serveurs photo auto-hébergés qui récupère chaque nuit les photothèques des téléphones, ses uploads apparaissent sur la même ligne mensuelle que le trafic relayé. Un serveur multimédia produit le même effet dans l’autre sens : un service comme Halcyon, qui transforme une bibliothèque Jellyfin en vidéothèque des années 90 consultable diffuse des vidéos vers les utilisateurs, et ce trafic sortant consomme le même quota que celui utilisé par le relais.
Un compteur nftables mesure spécifiquement le trafic du relais :
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 relaymeterCette règle ne définit aucun verdict. Elle compte donc les paquets et les octets sans modifier ce qui est autorisé. Elle se trouve dans une table dédiée afin de ne pas perturber ufw. Elle n’est pas persistante. Ajoutez les mêmes lignes dans /etc/nftables.conf pour la restaurer après un redémarrage. Le compteur n’augmente que lorsqu’une session est effectivement relayée. S’il continue d’augmenter alors qu’aucune de vos machines n’est connectée, cela signifie qu’une autre personne a découvert votre relais. C’est précisément le cas que hbbr -k _ doit empêcher. Comme vous ne consulterez pas nft list chaque matin, ajoutez-y une tâche cron qui compare le nombre d’octets à un seuil et envoie une alerte push lorsqu’il est dépassé. Votre propre serveur ntfy convient pour cette tâche.
hbbr propose également des limites de débit que vous pouvez réduire. SINGLE_BANDWIDTH est défini par défaut à 128 Mb/s par connexion relayée, et TOTAL_BANDWIDTH à 1024 Mb/s pour l’ensemble des connexions. Définir SINGLE_BANDWIDTH=8 limite une session à environ 1 MB/s. Cela limite le débit, pas le volume mensuel total. Utilisez donc ce paramètre pour empêcher une session de saturer la connexion, et non pour contrôler le budget de transfert.
Quand vous n’avez pas besoin d’un relais
Pour un usage personnel, la réponse honnête est que vous n’avez peut-être besoin de rien de tout cela. Placez les deux machines sur un mesh VPN et connectez-vous directement à l’adresse du tunnel. Il n’y a alors ni hbbs, ni hbbr, ni trafic sortant de relais, ni conteneur sur un VPS à mettre à niveau.
Sur la machine que vous voulez contrôler, activez l’accès direct par IP dans les paramètres de sécurité de RustDesk. Le champ du port contient par défaut 21118. Vérifiez que le service écoute avant de tenter la connexion :
ss -tlnp | grep 21118Connectez-vous ensuite à l’adresse VPN de ce pair plutôt qu’à un ID. La FAQ de RustDesk indique que ce mode n’est pas chiffré. Utilisez-le donc à l’intérieur du tunnel et jamais sur Internet. C’est le tunnel qui fournit le chiffrement.
Choisissez selon le propriétaire des machines. Un hbbs et un hbbr auto-hébergés conviennent lorsque vous administrez des machines qui ne vous appartiennent pas, ou des utilisateurs qui n’installeront jamais de client VPN, car leur côté de la configuration se limite à un ID et à un mot de passe. Un mesh VPN avec accès direct par IP convient lorsque toutes les machines vous appartiennent et peuvent utiliser une clé. WireGuard comparé à Tailscale présente les deux méthodes habituelles pour construire ce mesh, tandis que exécuter un bureau distant sur un VPS Linux couvre l’autre cas : la machine dont vous voulez afficher l’écran est le serveur lui-même.
FAQ
Chaque session RustDesk passe-t-elle par mon relay ?
Non. hbbs essaie d’abord de connecter directement les deux clients, en utilisant le hole punching à travers le NAT situé devant chacun d’eux. Seules les sessions pour lesquelles cette méthode échoue basculent vers hbbr, et seules celles-ci consomment votre bande passante. L’exception est ALWAYS_USE_RELAY=Y sur hbbs, qui force chaque session à passer par hbbr, même lorsqu’un chemin direct est disponible. Si cette variable est définie dans votre fichier Compose, chaque octet de chaque session est facturé au titre de votre transfert de données.
Où la clé du serveur RustDesk est-elle stockée et que se passe-t-il si je la perds ?
hbbs génère id_ed25519 et id_ed25519.pub dans son répertoire de travail lors du premier démarrage. Ce répertoire est /root dans l’image officielle. Avec le montage de volume présenté plus haut, les fichiers apparaissent donc dans ./data sur l’hôte. Sauvegardez les deux fichiers en dehors du serveur. S’ils sont perdus, hbbs génère une nouvelle paire au démarrage suivant, et tous les clients qui possèdent encore l’ancienne clé publique sont refusés. Il n’existe pas d’autre solution que de modifier manuellement le champ Key sur chaque client.
Quels ports dois-je ouvrir pour un serveur RustDesk auto-hébergé ?
TCP 21115, 21116 et 21117, ainsi que UDP 21116. hbbs utilise 21115 pour le test du type de NAT et 21116 pour l’enregistrement des ID et le heartbeat sur UDP, ainsi que pour le hole punching sur TCP. hbbr utilise 21117 pour le relay. TCP 21118 et 21119 sont les ports WebSocket du client dans le navigateur. Laissez-les donc fermés si vous ne l’utilisez pas. TCP 21114 est utilisé par la console web Pro. La version open source n’en a pas besoin.
Des inconnus peuvent-ils utiliser mon relay RustDesk auto-hébergé ?
Oui, si vous exécutez hbbr avec sa configuration par défaut. La documentation RustDesk indique qu’une clé vide permet aux clients qui ne possèdent pas de clé correspondante d’utiliser le relay. Toute personne qui connaît votre hostname et le port 21117 peut donc faire transiter du trafic par votre serveur. Exécutez hbbr avec -k _ afin qu’il charge la même paire de clés que celle générée par hbbs dans le volume partagé ./data. Ensuite, seuls les clients configurés avec votre clé publique pourront utiliser votre relay.