SSD Nodes Learn Hosting plans →
Guides Matt ConnorPar Matt Connor

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 daemons sur un même VPS. hbbs est le serveur d’identification et de rendez-vous : il enregistre l’ID de chaque client et met deux clients en relation. hbbr est le serveur relais : il transporte les octets de la session, mais uniquement pour les sessions qui n’ont pas pu établir de connexion directe. La plupart des guides installent les deux daemons, é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 daemons sont fournis dans la même image, rustdesk/rustdesk-server, et dans la configuration ci-dessous, ils utilisent tous deux la même paire de clés Ed25519 depuis le même répertoire. Ce comportement doit être configuré : hbbs charge ou génère la paire de manière autonome, mais hbbr ignore les clés si vous ne le démarrez pas avec une clé. Ed25519 est un schéma de signature à clé publique. Cette paire de clés détermine quels clients peuvent communiquer avec votre serveur. Aucune base de données utilisateurs n’est utilisée.

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 dans le dépôt rustdesk-server le 10 octobre 2026.

  • TCP 21115, sur hbbs : test du type de NAT.
  • UDP 21116, sur hbbs : enregistrement de l’ID et heartbeat. C’est le chemin utilisé par défaut par un client.
  • TCP 21116, sur hbbs : enregistrement de l’ID pour les clients configurés en TCP uniquement, ainsi que le TCP hole punching et le service de connexion.
  • TCP 21117, sur hbbr : le relay. C’est le port qui transporte les données de session ; c’est donc celui qui vous coûte de l’argent.
  • TCP 21118 sur hbbs et TCP 21119 sur hbbr : WebSocket, utilisé par le client web. Laissez ces deux ports fermés si vous ne l’utilisez pas.
  • TCP 21114 correspond au serveur d’API HTTP 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-stopped
mkdir -p ~/rustdesk
cd ~/rustdesk
# save the block above as ~/rustdesk/compose.yml before this line
sudo docker compose up -d
sudo docker compose ps

Les deux services doivent lire running. Vérifiez que les sockets en écoute existent avant de modifier le pare-feu.

sudo ss -tlnp | grep -E ':2111[5-7]'
sudo ss -ulnp | grep ':21116'

Vous devez voir des sockets TCP en écoute sur 21115, 21116 et 21117, ainsi qu’un socket UDP en écoute sur 21116. Si la ligne UDP est absente, hbbs ne fonctionne pas, car hbbs ouvre ce socket au démarrage et c’est celui auquel les clients s’enregistrent par défaut.

Quatre éléments de ce fichier sont intentionnels. Le tag est 1.1.16, qui est toujours la version actuelle en octobre 2026, publiée le 20 juillet 2026, et non latest, car latest signifie « ce qui a été publié le plus récemment » et un docker compose pull dans six mois peut vous fournir un serveur que vous n’avez jamais testé. network_mode: "host" lie directement les interfaces de l’hôte. C’est ce que recommande la documentation RustDesk et ce paramètre détermine le comportement de votre pare-feu. ./data:/root monte 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 en amont, car la configuration par défaut laisse votre relais 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 seul serveur, 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.pub

id_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.tgz

Copiez 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 n’effectue aucun contrôle. La documentation de configuration de RustDesk l’indique clairement : une clé vide permet aux clients sans clé correspondante d’utiliser le relais. Cette valeur vide par défaut évite que les nouveaux utilisateurs rencontrent des erreurs 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 ses sessions par votre VPS, en consommant votre quota de transfert et depuis votre adresse IP.

command: hbbr -k _ corrige ce problème. L’argument _ indique à hbbr de charger une paire de clés depuis son répertoire de travail, ou d’en générer une si aucune n’y est présente. Comme les deux conteneurs montent le même ./data, il s’agit de la même paire que celle utilisée par hbbs. Rien n’est copié manuellement, donc aucune divergence n’est possible.

Le volume partagé est le point le plus souvent mal configuré. Si vous attribuez à hbbr son propre répertoire, il génère une paire de clés différente. hbbs et hbbr ne disposent alors pas de la même clé, 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/ affichant une paire id_ed25519 unique permet d’écarter cette incompatibilité. Cela ne prouve pas que le relais vérifie les clés, car hbbr ignore ces fichiers s’il n’a pas été démarré avec une clé non vide. Vérifiez donc également la commande en cours d’exécution :

ps -eo args | grep '[h]bbr'

Cette commande doit afficher hbbr -k _. Un simple hbbr signifie que le relais est toujours ouvert, quel que soit le contenu du répertoire.

Pointez 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 lorsque 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 issue de 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 et que le client utilise les paramètres par défaut, la cause habituelle est que le port UDP 21116 n’atteint pas hbbs. C’est sur ce port qu’un client utilisant la configuration par défaut s’enregistre et envoie son heartbeat. Toutefois, un ID hors ligne ne suffit pas à le prouver. Un client dont l’option disable-udp est définie sur Y s’enregistre à la place via TCP 21116 et n’utilise jamais UDP 21116. Pour ce client, vérifiez d’abord TCP 21116.

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 Docker de NAT 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 numbered

Ajoutez 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 empêchera pas d’accéder à votre propre serveur. Les bases du pare-feu ufw pour un VPS présente les règles par défaut et l’ordre d’application des règles.

Voici le piège. Si vous remplacez cette configuration par la publication de ports avec un bloc ports:, comme dans de nombreux exemples RustDesk avec un seul conteneur, Docker écrit ses propres règles DNAT. Les paquets atteignent alors le conteneur sans passer par la chaîne où se trouvent vos règles ufw. Un refus ufw sur 21117 n’a donc aucun 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 dans "127.0.0.1:21118:21118" derrière un reverse proxy.

La restriction par adresse source ne fonctionne que si vos clients ont des 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 udp

Les ordinateurs portables connectés aux réseaux des hôtels n’ont pas d’adresses stables. C’est précisément pour cela que 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.

  1. Sauvegardez d’abord le répertoire de données : sudo tar czf ~/rustdesk-data-backup.tgz -C ~/rustdesk data.
  2. Consultez les notes de version du nouveau tag sur la page des releases de rustdesk-server.
  3. Modifiez compose.yml et remplacez les deux lignes image: par le nouveau tag.
  4. Exécutez sudo docker compose pull, puis sudo docker compose up -d.
  5. Exécutez sudo cat ~/rustdesk/data/id_ed25519.pub et 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.

GraphiqueVPS egress from one relayed RustDesk session, 60 hours per month
Les données de ce graphique
[
  {
    "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 -m

L’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 relaymeter

Cette 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 21118

Connectez-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 : cette option force toutes les sessions à 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 comptabilisé dans votre quota de transfert.

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. Dans l’image officielle, ce répertoire est /root. Avec le montage de volume indiqué plus haut, les fichiers apparaissent donc dans ./data sur l’hôte. Sauvegardez les deux fichiers hors 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 moyen de récupération 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 via UDP, ainsi que pour l’enregistrement et le hole punching via TCP. hbbr utilise 21117 pour le relay. TCP 21118 et 21119 sont les ports WebSocket du client navigateur. Laissez-les donc fermés si vous ne l’utilisez pas. TCP 21114 appartient au serveur d’API HTTP 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 ne possédant 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 hbbs depuis le volume partagé ./data. Ensuite, seuls les clients configurés avec votre clé publique pourront utiliser votre relay.