SSD Nodes Learn 🎉 VPS dès $4.99/mois
Guides Matt ConnorPar Matt Connor

Auto-héberger le serveur VPN NetBird sur un VPS

Installez NetBird sur un VPS avec DNS et TLS, le script quickstart versionné et des setup keys pour les peers sans interaction. Comparaison avec Headscale.

Ce que vous apporte l’auto-hébergement du serveur VPN NetBird

L’auto-hébergement du serveur VPN NetBird place le control plane sur un VPS que vous possédez. Cette partie conserve la liste des peers, détermine quelle machine peut joindre quelle autre et aide deux peers à se trouver derrière un NAT (network address translation). Les tunnels eux-mêmes utilisent toujours WireGuard et sont chiffrés directement entre vos machines. La différence est qu’aucune entreprise externe ne conserve l’inventaire de vos appareils ni le processus de connexion.

NetBird se situe à la jonction de deux concepts que vous connaissez peut-être déjà. Il s’agit d’un mesh overlay : les peers se connectent entre eux au lieu de faire transiter tout le trafic par une seule gateway. Il est également auto-hébergeable de bout en bout, ce qui le rapproche de Headscale, le serveur de contrôle Tailscale auto-hébergé. Si vous n’avez utilisé jusqu’ici qu’un tunnel avec une seule gateway, lisez d’abord la différence entre WireGuard classique et un mesh overlay. Ce modèle mental vous aidera à comprendre la suite de cette page.

Si votre objectif réel est de faire sortir tout votre trafic par un seul serveur, un mesh apporte une complexité inutile. Un VPN WireGuard classique sur un VPS unique ou un exit node Tailscale répond à ce besoin avec beaucoup moins de composants à maintenir.

Ce que la stack exécute réellement

La structure a récemment changé, et la plupart des anciens guides décrivent encore l’ancienne version. En août 2026, avec la release v0.76.2, le script de démarrage rapide écrit par défaut un fichier Compose avec trois services.

  • netbird-server fournit l’API de gestion, le service de signalisation, le relay avec un listener STUN intégré et un identity provider intégré. Dans les releases précédentes, ces composants étaient des conteneurs distincts, et l’identity provider était une installation Zitadel séparée qu’il fallait d’abord construire.
  • dashboard correspond à la console web d’administration.
  • traefik termine les connexions TLS (transport layer security) et demande un certificat à Let’s Encrypt au premier démarrage.

Deux autres services existent et restent désactivés, sauf si vous répondez oui à une invite. Le service NetBird Proxy publie des services internes sur des noms d’hôte publics. CrowdSec filtre le trafic abusif. Aucun des deux n’est nécessaire pour construire un mesh fonctionnel, et tous deux consomment de la mémoire sur une petite machine.

Si vous venez de wg-easy dans un conteneur Docker unique, le nombre de composants augmente nettement. En contrepartie, vous bénéficiez de règles d’accès et de comptes par utilisateur, ainsi que de peers qui se connectent directement entre eux au lieu de passer par une seule gateway.

Ce qu’il vous faut avant de commencer

Un nom de domaine public est obligatoire. Le dashboard, l’API et le relay utilisent tous HTTPS sur le port 443. Traefik obtient son certificat auprès de Let's Encrypt avec un challenge HTTP. Celui-ci nécessite un nom qui pointe vers ce VPS depuis Internet. Une adresse IP seule ne fonctionne pas dans ce scénario.

Créez un enregistrement A, netbird.example.com, qui pointe vers l’adresse IPv4 publique du VPS. Attendez ensuite sa propagation avant d’exécuter quoi que ce soit.

dig +short netbird.example.com

Cette commande doit afficher l’adresse de votre serveur. Si vous exécutez l’installateur avant la propagation du DNS, la demande de certificat échoue au premier démarrage. Plusieurs validations échouées consécutives peuvent atteindre les limites de débit de Let's Encrypt. Vous devrez alors attendre une heure avant de réessayer.

Trois ports doivent être accessibles depuis Internet : TCP 80 pour le challenge de certificat et la redirection vers HTTPS, TCP 443 pour le dashboard, l’API, le trafic de signalisation et du relay, et UDP 3478 pour STUN.

sudo ufw allow 80/tcp
sudo ufw allow 443/tcp
sudo ufw allow 3478/udp
sudo ufw reload
sudo ufw status

Ouvrez-les également dans le firewall réseau de votre fournisseur. Dans la plupart des panneaux de gestion VPS, il s’agit d’un contrôle distinct. C’est pourquoi une machine dont le ufw status local semble correct peut tout de même refuser les connexions.

STUN (session traversal utilities for NAT) permet à un pair de connaître l’adresse et le port publics attribués par son propre NAT. Deux pairs peuvent ainsi tenter d’établir un tunnel direct. Si vous bloquez UDP 3478, les pairs continuent de se connecter via le relay sur TCP 443, sans symptôme évident. Vous obtenez toutefois Connection type: Relayed sur chaque pair, et tout le trafic passe par votre VPS au lieu de circuler directement entre les pairs.

Côté logiciel, vous avez besoin de Docker avec le plugin Compose v2, ainsi que de jq et curl. Le script vérifie tous ces éléments et s’arrête si l’un d’eux manque. Si Docker vient d’être installé sur cette machine, consultez d’abord Configurer Docker Compose sur le VPS.

Ports si vous n’utilisez pas le reverse proxy fourni

Sans Traefik, les services individuels sont exposés directement et la liste des ports s’allonge :

  • TCP 80, redirections HTTP
  • TCP 443, HTTPS
  • TCP 33073, gRPC de gestion
  • TCP 10000, gRPC de signalisation
  • TCP 33080, relay via WebSocket ou QUIC
  • UDP 3478, STUN

Choisissez cette configuration uniquement si la machine assure déjà la terminaison TLS d’un autre service. Sinon, le Traefik fourni nécessite moins de règles et réduit le risque d’erreur.

Installer le serveur NetBird avec le script d’installation rapide

La commande en une ligne documentée envoie la dernière release directement dans un shell :

curl -fsSL https://github.com/netbirdio/netbird/releases/latest/download/getting-started.sh | bash

Épinglez plutôt la version. latest évolue, donc la même commande exécutée à deux semaines d’intervalle produit deux installations différentes, sans qu’aucun fichier sur le disque n’indique laquelle a écrit votre configuration. Téléchargez une release marquée, lisez-la, puis exécutez-la.

mkdir -p ~/netbird
cd ~/netbird
curl -fsSL -o getting-started.sh \
  https://github.com/netbirdio/netbird/releases/download/v0.76.2/getting-started.sh
less getting-started.sh
bash getting-started.sh

Le script demande d’abord le domaine :

Enter the domain you want to use for NetBird (e.g. netbird.my-domain.com):

Il demande ensuite comment le chiffrement TLS sera géré :

Which reverse proxy will you use?
  [0] Traefik (recommended - automatic TLS, included in Docker Compose)
  [1] Existing Traefik (labels for external Traefik instance)
  [2] Nginx (generates config template)
  [3] Nginx Proxy Manager (generates config + instructions)
  [4] External Caddy (generates Caddyfile snippet)
  [5] Other/Manual (displays setup documentation)
Enter choice [0-5] (default: 0):

Choisissez [0]. Les options 2 à 5 écrivent un fragment de configuration et vous laissent gérer le raccordement. C’est adapté à une machine qui exécute déjà un proxy, mais pas à une installation neuve. L’option 0 demande ensuite une adresse e-mail pour Let’s Encrypt, utilisée pour les notifications d’expiration.

Refusez le service NetBird Proxy lors d’une première installation. Il nécessite deux enregistrements DNS supplémentaires, proxy.netbird.example.com et le wildcard *.proxy.netbird.example.com, et n’apporte rien à un simple mesh. Refusez également CrowdSec. Vous pourrez ajouter ces deux composants plus tard.

Le script écrit dans le répertoire courant : docker-compose.yml, config.yaml avec le mode 600, dashboard.env et traefik-dynamic.yaml si vous avez choisi Traefik intégré. Traitez ce répertoire comme un état persistant à conserver, car config.yaml contient la clé qui chiffre les données du store. Une réinstallation ne permet pas de corriger sa perte.

docker compose ps
docker compose logs -f netbird-server

Chaque service doit lire running, et le journal du serveur doit se stabiliser au lieu de redémarrer en boucle. Surveillez le certificat séparément :

docker compose logs traefik | grep -i acme

ACME (automatic certificate management environment) est le protocole que Traefik utilise pour obtenir le certificat. Les erreurs à ce stade sont presque toujours liées au DNS ou à la fermeture du port 80.

Créer le premier compte administrateur

Ouvrez https://netbird.example.com. Sur une installation neuve, cette adresse affiche une page de configuration et non un formulaire de connexion. Saisissez une adresse e-mail, un nom et un mot de passe, puis cliquez sur Create Account. Ce compte devient le premier administrateur, puis la page redirige vers le formulaire de connexion.

Ce compte est stocké dans le magasin d’utilisateurs de NetBird, fourni par un identity provider intégré au conteneur netbird-server. Aucun composant externe n’est utilisé. Il s’agit du principal changement par rapport à la version auto-hébergée de NetBird d’il y a un an. À l’époque, une installation fonctionnelle nécessitait d’abord de déployer Zitadel ou Keycloak, puis de copier quatre valeurs OIDC (OpenID Connect) dans setup.env avant que le moindre composant puisse démarrer.

Si votre navigateur affiche un avertissement concernant le certificat au lieu de la page de configuration, le certificat n’a pas été émis. Corrigez ce problème avant de continuer, car le dashboard communique avec l’API via le même hostname et son fonctionnement devient difficile à diagnostiquer avec un certificat incorrect.

Rejoindre votre premier pair

Installez le client sur n’importe quelle machine Linux, y compris le VPS lui-même si vous souhaitez l’ajouter au mesh :

curl -fsSL https://pkgs.netbird.io/install.sh | sh

Sur Debian et Ubuntu, ce script configure le dépôt de paquets NetBird, puis installe le client avec apt. Le gestionnaire de paquets en devient donc le propriétaire dans tous les cas. Si l’exécution d’un script envoyé dans un shell vous gêne, enregistrez-le d’abord avec curl -fsSL -o install.sh https://pkgs.netbird.io/install.sh et lisez-le avant d’exécuter sh install.sh. Dans tous les cas, vérifiez ce qui a été installé :

apt-cache policy netbird

netbird est le client en ligne de commande et le daemon. netbird-ui est l’application de barre d’état du bureau. Un serveur headless n’en a pas besoin.

Pointez maintenant le client vers votre serveur :

sudo netbird up --management-url https://netbird.example.com

Si vous omettez --management-url, le client s’enregistre auprès du service hébergé de NetBird, car il s’agit de la valeur par défaut compilée. La commande réussit malgré tout, la machine reçoit quand même une adresse et votre dashboard auto-hébergé reste vide. Cela arrive à presque tout le monde au moins une fois.

La commande affiche une URL à ouvrir dans un navigateur pour terminer la connexion. Ensuite :

netbird status
ip addr show wt0

Lisez quatre lignes avec netbird status : Management: Connected, Signal: Connected, une ligne Relays: indiquant tous les relais disponibles et une ligne NetBird IP: dans la plage de l’overlay. wt0 est l’interface WireGuard créée par NetBird. Elle doit porter cette même adresse.

Ajouter une deuxième machine sans intervention avec une setup key

La connexion via un navigateur ne fonctionne pas pour une machine qui n’en possède pas et devant laquelle personne n’est présent. Une setup key est un jeton de pré-authentification qui enregistre une machine sans étape interactive. Créez-en une dans le dashboard, sous Setup Keys.

Il en existe deux types. Une clé à usage unique authentifie exactement une machine, puis devient inutilisable. Une clé réutilisable enregistre plusieurs machines, avec éventuellement une limite sur leur nombre. Les deux types ont une date d’expiration et peuvent attribuer automatiquement le nouveau peer à un groupe. Les règles d’accès de ce groupe s’appliquent dès que la machine apparaît.

sudo netbird up --setup-key <SETUP-KEY> \
  --management-url https://netbird.example.com \
  --hostname build-runner-01

--hostname définit le nom affiché dans le dashboard. Sans cette option, le peer prend le nom que la machine s’attribue elle-même. Une liste de machines portant toutes le nom ubuntu n’est utile à personne.

Pour les conteneurs et les build agents temporaires, activez l’option ephemeral lors de la création de la clé. Les peers enregistrés avec une clé ephemeral sont supprimés automatiquement après plus de 10 minutes hors ligne. Cela évite de conserver des entrées obsolètes dans la liste des peers.

Une limite doit être comprise avant de planifier l’utilisation des setup keys : l’expiration ou la suppression d’une clé empêche les nouvelles inscriptions, mais ne déconnecte pas les machines déjà enregistrées avec cette clé. Pour supprimer l’accès d’une machine, vous devez supprimer son peer.

Avez-vous encore besoin d’un identity provider séparé ?

Pour une petite installation, non. Le user store intégré gère les comptes créés depuis le dashboard. Cela suffit pour quelques utilisateurs.

Un identity provider externe est utile si vous en utilisez déjà un et ne voulez pas gérer une seconde liste d’utilisateurs. NetBird accepte tous les providers compatibles avec OIDC. Enregistrez un client OIDC confidentiel auprès de votre provider, puis ajoutez-le dans le dashboard NetBird avec quatre valeurs : nom, client ID, client secret et issuer. NetBird vous fournit une redirect URL à recopier dans le provider. Des intégrations dédiées existent pour Google, Microsoft Entra ID, Okta, Zitadel, Keycloak, Authentik et Pocket ID. Les autres providers se configurent avec l’option OIDC générique. Si vous utilisez déjà Authentik comme solution de single sign-on auto-hébergée, cette méthode conserve une seule liste de comptes au lieu de deux.

La connexion locale reste disponible après l’ajout d’un provider, et chaque provider configuré apparaît sur la page de connexion. Conservez un compte administrateur local avec un mot de passe robuste. Une configuration OIDC défectueuse vous laissera ainsi toujours un accès.

NetBird ou Headscale : quel control plane devez-vous utiliser ?

Les deux suppriment la même dépendance : le control server hébergé que vos clients contacteraient sinon. Leur architecture de projet est différente.

Headscale réimplémente le control server de Tailscale, et vous continuez à utiliser les clients Tailscale officiels. Il n’existe pas de console web officielle. Vous gérez les utilisateurs et les pre-authentication keys avec la commande headscale, à partir d’un fichier de configuration. Il existe des interfaces web communautaires, mais elles ne font pas partie du projet. Cette solution convient aux personnes qui veulent stocker leur état dans des fichiers et versionner leurs modifications.

NetBird fournit le produit complet : son propre client, son propre dashboard, un identity provider intégré et des règles d’accès modifiables dans un navigateur. Cela ajoute davantage de composants sur votre VPS, mais il est beaucoup plus facile de confier l’administration à un collègue qui n’ouvrira jamais un terminal.

Utilisez Headscale si vous utilisez déjà les clients Tailscale ou si vous voulez le control plane le plus réduit possible. Utilisez NetBird si plusieurs personnes doivent gérer les peers et si vous voulez une console et le SSO sans devoir les assembler vous-même.

Quelle est la taille minimale du VPS nécessaire ?

Le minimum indiqué est de 1 CPU et 2 GB de mémoire. Les notes de NetBird situent désormais le seuil autour de 1 GB de RAM, car la gestion des utilisateurs est locale. L’ancienne architecture nécessitait 2 GB à 4 GB lorsqu’un déploiement complet de Zitadel faisait partie de la stack. Prenez 2 GB. Cette marge permet à une mise à niveau de télécharger de nouvelles images alors que les anciennes sont encore présentes sur le disque.

Sur une petite machine, vous pouvez laisser trois composants de côté sans risque. Désactivez le service NetBird Proxy. Il sert à publier des services internes sur des noms d’hôte publics et n’a aucun rapport avec la connexion des peers. Désactivez CrowdSec. Il est préférable de l’ajouter plus tard sur une machine exposée, plutôt que dès le premier jour. Conservez le stockage SQLite par défaut dans le volume netbird_data. Passez à PostgreSQL uniquement lorsque vous répartissez le déploiement sur plusieurs machines ou que vous rencontrez une concurrence réelle. La documentation indique que cette migration peut être effectuée ultérieurement.

Le relay est le seul composant indispensable. Lorsque le NAT de deux peers attribue un port différent pour chaque destination, ils ne peuvent jamais établir de tunnel direct. Le relay est alors le seul chemin permettant leur connexion. Le désactiver économise très peu de mémoire et interrompt les connexions d’une manière difficile à diagnostiquer.

Lorsqu’une seule machine ne suffit plus, commencez par déplacer les relays. Un relay autonome s’exécute avec NB_LISTEN_ADDRESS, NB_EXPOSED_ADDRESS, NB_AUTH_SECRET et NB_ENABLE_STUN. Le secret partagé doit être identique sur le relay et sur le serveur principal. Sinon, les clients ne peuvent pas s’y authentifier.

Modes de défaillance et symptômes observables

Le dashboard affiche un avertissement concernant le certificat. Traefik n’a pas obtenu de certificat. Exécutez docker compose logs traefik | grep -i acme. Deux causes sont possibles. Soit dig +short netbird.example.com ne renvoie pas encore vers ce VPS, soit le port TCP 80 est fermé quelque part entre Let's Encrypt et le conteneur, généralement au niveau du firewall réseau du fournisseur plutôt que sur ufw. Corrigez la cause avant de réessayer en boucle, car les validations échouées sont soumises à une limitation de débit et vous ne pourrez plus effectuer de nouvelles tentatives pendant une heure.

Le client indique qu’il s’est connecté, mais le dashboard est vide. Le client s’est enregistré auprès du service hébergé de NetBird, car --management-url était absent. Exécutez netbird status --detail et lisez la ligne Management:, qui indique le serveur avec lequel le client communique réellement. Si vous voyez Management: Connected to https://api.netbird.io:443, le client s’est connecté au cloud. Exécutez sudo netbird down, puis sudo netbird up --management-url https://netbird.example.com à nouveau.

Tous les peers affichent Connection type: Relayed. Aucun tunnel direct n’est établi. Tout le trafic traverse donc votre VPS et ajoute un saut réseau ainsi qu’une latence supplémentaire. Vérifiez UDP 3478 sur le firewall du VPS et sur celui du fournisseur, car STUN permet à un peer de déterminer sa propre adresse et son port publics. netbird status --detail affiche également Direct: false ainsi que les types de candidats ICE (interactive connectivity establishment) pour chaque peer. Cela indique jusqu’où la tentative a progressé. Sur certains réseaux, le relais est le seul résultat possible. Ce comportement n’indique alors aucun problème.

Un peer rejoint le réseau, mais ne peut rien atteindre. Le fait d’appartenir au mesh ne signifie pas que deux peers peuvent communiquer. Les access policies contrôlent les communications, et un groupe auquel aucune policy n’est associée ne peut rien atteindre. Vérifiez la policy dans le dashboard avant de commencer à diagnostiquer les routes et les firewalls.

netbird status signale un problème avec le daemon. Le service n’est pas en cours d’exécution. Utilisez sudo netbird service status et sudo netbird service start. Les journaux du client se trouvent dans /var/log/netbird/client.log. Pour tout problème que vous ne parvenez pas à identifier, netbird debug bundle --anonymize --system-info regroupe les journaux, l’état du système, les routes, la configuration DNS et l’état du firewall dans une seule archive.

Sauvegardes et mises à niveau

Deux éléments sont indispensables au fonctionnement de l’installation : le répertoire qui contient docker-compose.yml et config.yaml, ainsi que le volume Docker qui contient la base de données et les clés de chiffrement. Sauvegardez-les ensemble. config.yaml contient la clé qui chiffre les données du magasin. Une copie de la base de données sans cette clé ne permet donc de rien restaurer de lisible.

docker volume ls
docker compose down
sudo tar czf netbird-config.tgz -C ~ netbird
docker run --rm -v netbird_netbird_data:/data -v "$PWD":/backup \
  alpine tar czf /backup/netbird-data.tgz -C /data .
docker compose up -d

Compose préfixe les noms des volumes avec le répertoire du projet. Le volume documenté sous le nom netbird_data apparaît donc généralement sous le nom netbird_netbird_data. Exécutez d’abord docker volume ls et utilisez le nom qu’il affiche. Sinon, la commande docker run échoue en créant silencieusement un volume vide et en n’archivant rien. Conservez les archives en dehors du VPS. Si vous disposez déjà d’un outil de sauvegarde, restic ou BorgBackup prend en charge la partie externalisée.

La mise à niveau du serveur consiste à télécharger les nouvelles images, puis à recréer les conteneurs :

docker compose pull
docker compose up -d
docker compose ps

Avant de vous y fier, exécutez docker compose config | grep image:. Tout tag défini sur latest doit être remplacé par une version précise, pour la même raison que vous avez figé le script d’installation : vous devez savoir ce qui s’exécute et disposer d’une version vers laquelle revenir si une mise à niveau pose problème. Les clients se mettent à niveau avec le gestionnaire de paquets qui les a installés.

FAQ

Ai-je besoin de mon propre fournisseur d’identité pour auto-héberger NetBird ?

Non. Les versions actuelles intègrent un store utilisateur, vous pouvez donc créer le premier compte administrateur dans le navigateur à l’adresse https://netbird.example.com, puis ajouter des utilisateurs depuis le dashboard. Un fournisseur OIDC externe est facultatif et peut être ajouté ultérieurement avec quatre valeurs : nom, ID client, secret client et issuer. Les guides qui vous demandent de déployer Zitadel ou Keycloak avant NetBird décrivent une configuration qui n’est plus nécessaire. Les suivre vous impose d’exécuter un service supplémentaire.

Pourquoi tous mes peers affichent-ils Connection type: Relayed ?

Les connexions directes ne se forment pas. Le trafic passe donc par le relay sur votre VPS. La cause habituelle est le blocage de UDP 3478. Il s’agit du port STUN que les peers utilisent pour découvrir leur propre adresse et leur propre port publics. Ouvrez-le dans le firewall du VPS et dans le firewall réseau distinct de votre fournisseur, puis exécutez de nouveau netbird status --detail et lisez la ligne Direct:. Sur un réseau dont le NAT attribue un port différent selon la destination, relayed est le seul résultat possible. La configuration n’est alors pas incorrecte.

Mon client s’est connecté, mais le dashboard n’affiche aucun peer. Que s’est-il passé ?

Le client s’est enregistré auprès du service hébergé de NetBird au lieu de votre serveur. Cela se produit lorsque --management-url est omis. netbird status --detail affiche le serveur auquel le client se connecte sur la ligne Management:. Une valeur telle que https://api.netbird.io:443 le confirme. Exécutez sudo netbird down, puis sudo netbird up --management-url https://netbird.example.com. Le peer apparaît alors dans votre dashboard.

Quelle est la différence entre NetBird auto-hébergé et Headscale ?

Les deux solutions remplacent un serveur de contrôle hébergé par un serveur que vous exécutez vous-même. Headscale fournit uniquement le control plane. Vous l’administrez avec la commande headscale et un fichier de configuration. Il n’existe pas de console web officielle. Headscale pilote les clients Tailscale officiels. NetBird fournit son propre client, un dashboard d’administration et l’intégration avec un fournisseur d’identité dans la même stack. Headscale est plus léger à exécuter et conserve son état dans des fichiers. NetBird est plus facile à utiliser pour des personnes qui ne travaillent pas avec un terminal.

De quel type de VPS un serveur NetBird auto-hébergé a-t-il besoin ?

Le minimum indiqué dans la documentation est de 1 CPU et 2 GB de mémoire. C’est donc la configuration de 2 GB qu’il faut choisir. En pratique, le minimum est récemment descendu à environ 1 GB, car le fournisseur d’identité est désormais intégré au lieu d’être déployé séparément. Désactivez le proxy facultatif et les services CrowdSec pendant l’installation. Conservez le store SQLite par défaut jusqu’à ce que PostgreSQL soit réellement nécessaire.