Guide de déploiement

Héberger Headscale sur un VPS : serveur de contrôle Tailscale

Déployer sur un VPS Cloud →

Tutoriel

Sécurité & Monitoring

Héberger Headscale sur un VPS : serveur de contrôle Tailscale

L’offre gratuite de Tailscale (Personal) s’arrête à 6 utilisateurs, le plan Standard se facture ensuite par siège, et dans tous les cas la carte de votre réseau est stockée dans le cloud de Tailscale. Headscale (BSD-3-Clause, plus de 45 000 étoiles sur GitHub) est un remplaçant open source direct du serveur de coordination Tailscale — déployez-le sur votre VPS et continuez à utiliser les clients Tailscale officiels sur chaque appareil. Votre équipe se connecte via des tunnels WireGuard zero-trust, du magic DNS et un contrôle d’accès basé sur des ACL, le tout auto-hébergé et sans limite. Ce guide couvre l’installation (Docker ou paquet `.deb`), le reverse proxy HTTPS, la vérification du maillage, la bascule d’une équipe déjà sur Tailscale, le calcul du seuil de rentabilité et ce que Headscale ne sait pas faire.

19 min de lecture21 étapes
Sommaire· Pourquoi auto-héberger le serveur de contrôle1/20
  1. 01Pourquoi auto-héberger le serveur de contrôle
  2. 02Ce que Headscale auto-hébergé vous apporte
  3. 03Prérequis
  4. 04Les ports à ouvrir sur le VPS
  5. 05Déployer Headscale avec Docker Compose
  6. 06Sans Docker : le paquet .deb officiel
  7. 07Installer Headscale avec le paquet .deb
  8. 08Exposer Headscale en HTTPS derrière Nginx
  9. 09Associer Headscale à Authelia pour un accès réseau protégé par MFA
  10. 10Vérifier que les nœuds se voient
  11. 11Contrôler le maillage depuis un client
  12. 12Cas d’usage : SSH entre VPS sans exposer le port 22
  13. 13Restreindre SSH au réseau maillé
  14. 14Migrer une équipe déjà sur Tailscale
  15. 15Basculer les clients vers Headscale
  16. 16Headscale vs Tailscale Cloud
  17. 17Tailscale Personal, Tailscale Standard et Headscale
  18. 18Ce que Headscale ne remplace pas
  19. 19Sauvegardes et mises à jour
  20. 20Dépannage : les erreurs les plus fréquentes

Pourquoi auto-héberger le serveur de contrôle

Tailscale est un logiciel exceptionnel — les performances de WireGuard, des clients multiplateformes, un magic DNS qui fonctionne du premier coup. Il ne transporte pourtant pas votre trafic : les paquets WireGuard circulent directement d’un nœud à l’autre, chiffrés de bout en bout. Ce qui tourne dans le cloud de Tailscale, c’est le plan de contrôle — le serveur de coordination qui échange les clés publiques, fait se découvrir les pairs, attribue les adresses 100.x.y.z, publie les noms MagicDNS, distribue les ACL et la carte des relais DERP. Sans lui, les nœuds ne se trouvent pas. Headscale réimplémente ce serveur de coordination en Go open source, avec le même protocole, pour que vous puissiez le faire tourner sur votre propre infrastructure : vos clients Tailscale ne changent que d’URL de connexion.

Au-delà du plafond de 6 utilisateurs de l’offre gratuite, la principale raison de l’auto-héberger est la résidence des données : le plan de contrôle sait quelles machines sont sur votre réseau, leurs IP, leurs noms et vos politiques d’ACL. Faire tourner Headscale signifie que ces informations restent sur votre VPS — et non dans le cloud de quelqu’un d’autre — et que votre réseau ne dépend plus d’une décision tarifaire ou d’une panne chez un tiers.

Ce que Headscale auto-hébergé vous apporte

  • Utilisateurs et appareils sans plafond : aucune limite imposé par le logiciel, pas de tarification par siège — votre réseau maillé grandit avec votre équipe, borné seulement par les ressources du VPS.
  • Les clients Tailscale officiels partout : Linux, macOS, Windows, iOS, Android — aucun fork maison ni client alternatif requis.
  • Tunnels WireGuard pair à pair : Headscale ne gère que l’échange de clés et la distribution des ACL ; tout le trafic réel circule directement en WireGuard entre les pairs.
  • Magic DNS : résolvez chaque nœud de votre réseau maillé par son nom d’hôte (poste.mesh.votre-domaine.com) sans modifier votre DNS public.
  • Politiques HuJSON : le même format de fichier de politique que Tailscale, avec les ACL et les Grants — définissez quels utilisateurs et quels appareils peuvent accéder à quels services.
  • Prise en charge des relais DERP : utilisez la carte DERP publique de Tailscale pour la traversée de NAT, ou activez le serveur DERP intégré à Headscale pour garder aussi les relais chez vous.
  • API et CLI headscale : créez des utilisateurs, émettez des clés de pré-authentification et gérez les nœuds par programmation.
  • Enregistrement sans compte tailscale.com : vos collaborateurs rejoignent le réseau avec une clé que vous générez, ou via le fournisseur OpenID Connect que vous utilisez déjà (Keycloak, Authelia, Google Workspace…).
  • Sous-réseaux, exit nodes, Taildrop et Tailscale SSH : les fonctions de base de Tailscale sont prises en charge par le serveur.
  • Moins de 50 Mo de RAM au repos — tourne confortablement sur un VPS de 1 Go aux côtés d’autres charges de travail.

Prérequis

Un VPS avec au moins 1 vCPU et 512 Mo de RAM (1 Go laisse de la marge au système) sous Ubuntu 22.04 ou plus récent, ou Debian 12 ou plus récent — ce sont les distributions que visent les paquets officiels. Pour la voie Docker, installez Docker et Docker Compose v2. Une IP publique est nécessaire ; une configuration double pile IPv4 + IPv6 est recommandée.

Un nom de domaine pointant vers le VPS est requis : les clients Tailscale se connectent au serveur de contrôle par URL, et le projet recommande fortement de servir Headscale en HTTPS sur le port 443, le client Tailscale supposant ce port dans certaines situations. Prévoyez un sous-domaine pour le serveur (vpn.votre-domaine.com) et un autre, distinct, pour les noms MagicDNS (mesh.votre-domaine.com) : Headscale refuse que le domaine MagicDNS soit celui de server_url.

Les ports à ouvrir sur le VPS

  • TCP 443 : obligatoire. C’est par HTTPS que les clients s’enregistrent et reçoivent la carte du réseau ; c’est le seul port indispensable au serveur de coordination.
  • TCP 80 : uniquement pour la validation Let’s Encrypt HTTP-01 et la redirection vers HTTPS.
  • UDP 3478 : uniquement si vous activez le serveur DERP intégré, qui en a besoin pour STUN. Avec la carte DERP publique de Tailscale, inutile de l’ouvrir.
  • TCP 8080 (Headscale), 9090 (métriques) et 50443 (gRPC) : à laisser sur 127.0.0.1. Le reverse proxy parle à 8080 en local ; n’exposez jamais l’interface d’administration gRPC sans en avoir besoin.

Déployer Headscale avec Docker Compose

  1. Rédiger le fichier Compose

    La stack ne compte qu’un seul service : l’image officielle docker.io/headscale/headscale:0.29.7, dernière version stable au 7 novembre 2026, lancée avec la commande serve. Headscale garde tout — clés, base de données, enregistrements des nœuds — dans deux dossiers de l’hôte : la configuration, montée en lecture seule sur /etc/headscale, et les données, sur /var/lib/headscale. Aucun service externe de base de données ou de cache n’est nécessaire ; SQLite est intégré.

    mkdir -p /opt/headscale/config /opt/headscale/lib
    cat > /opt/headscale/compose.yaml <<'EOF'
    services:
      headscale:
        image: docker.io/headscale/headscale:0.29.7
        container_name: headscale
        restart: unless-stopped
        read_only: true
        tmpfs:
          - /var/run/headscale
        ports:
          - "127.0.0.1:8080:8080"
        volumes:
          - /opt/headscale/config:/etc/headscale:ro
          - /opt/headscale/lib:/var/lib/headscale
        command: serve
        healthcheck:
          test: ["CMD", "headscale", "health"]
    EOF

    Le port n’est publié que sur 127.0.0.1 : c’est le reverse proxy qui fera face à Internet.

  2. Générer la configuration

    Partez du fichier d’exemple de la version exacte que vous déployez, puis ne modifiez que les clés ci-dessous. server_url est l’URL HTTPS à laquelle vos clients Tailscale se connecteront ; listen_addr doit écouter sur 0.0.0.0 à l’intérieur du conteneur. La base se déclare sous database (type: sqlite). Seule la clé noise reste à indiquer : Headscale la génère au premier démarrage si le fichier n’existe pas.

    curl -Lo /opt/headscale/config/config.yaml \
      https://raw.githubusercontent.com/juanfont/headscale/v0.29.7/config-example.yaml
    server_url: https://vpn.votre-domaine.com
    listen_addr: 0.0.0.0:8080
    noise:
      private_key_path: /var/lib/headscale/noise_private.key
    database:
      type: sqlite
      sqlite:
        path: /var/lib/headscale/db.sqlite
    dns:
      magic_dns: true
      base_domain: mesh.votre-domaine.com

    Sur ServOrbit, le job de provisioning écrit config.yaml à partir de votre domaine automatiquement.

  3. Démarrer le conteneur et vérifier

    Lancez docker compose up -d depuis /opt/headscale. Headscale génère sa clé noise, puis se met à écouter sur le port 8080. Vérifiez l’endpoint de santé : curl -s http://127.0.0.1:8080/health doit renvoyer {"status":"pass"}. L’image est construite sur une base distroless, sans shell, mais la CLI headscale s’appelle directement : docker exec headscale headscale version confirme la version en cours d’exécution, et docker logs --follow headscale affiche les journaux.

  4. Créer un utilisateur et générer une clé d’authentification

    Headscale organise les appareils en « utilisateurs » (auparavant appelés namespaces). Créez-en un, puis relevez son identifiant numérique : l’option --user de preauthkeys create attend cet ID, pas le nom.

    docker exec headscale headscale users create myteam
    docker exec headscale headscale users list
    docker exec headscale headscale preauthkeys create --user 1 --reusable --expiration 24h

    Sans --reusable, la clé ne sert qu’une fois, et sans --expiration elle expire au bout d’une heure. Copiez la clé affichée — vous l’utiliserez pour enregistrer chaque appareil.

  5. Enregistrer un appareil

    Sur n’importe quel appareil disposant du client Tailscale officiel, pointez-le vers votre instance Headscale : tailscale up --login-server https://vpn.votre-domaine.com --authkey <votre-clé-preauth>. L’appareil apparaît dans la liste des nœuds de Headscale en quelques secondes : docker exec headscale headscale nodes list. Sans clé, le client ouvre une page qui affiche un identifiant d’authentification ; approuvez-le côté serveur avec docker exec headscale headscale auth register --user myteam --auth-id <AUTH_ID>. Une fois enregistrés, les appareils communiquent par leur IP de maillage (100.64.x.y) ou par leur nom d’hôte magic DNS.

  6. Définir les politiques de contrôle d’accès

    Tant qu’aucune politique n’est chargée, Headscale laisse passer tout le trafic entre les nœuds — acceptable pour une petite équipe de confiance, pas dès que postes de développeurs, prestataires et serveurs de production cohabitent. Créez /opt/headscale/config/policy.hujson et déclarez-le dans config.yaml sous policy.path: /etc/headscale/policy.hujson. Headscale utilise le même format HuJSON que Tailscale : définissez des groupes d’utilisateurs, étiquetez les appareils comme serveurs ou postes de travail, et écrivez des règles précisant quels groupes peuvent atteindre quels ports. Le projet recommande les Grants plutôt que les ACL, que Tailscale considère comme historiques. Validez le fichier avec headscale policy check --file <fichier>, puis rechargez : la politique n’est relue qu’au rechargement (docker kill --signal=HUP headscale, ou systemctl reload headscale en natif). Versionnez ce fichier dans un dépôt Git privé pour garder l’historique des accès.

  7. Se connecter la première fois

    Headscale n’a pas d’interface web ni de compte : c’est le serveur de contrôle de votre réseau privé, piloté en ligne de commande. En SSH : docker exec -it headscale headscale users create monuser, puis la clé avec preauthkeys create --user <ID> --reusable --expiration 24h, et raccordez vos machines avec tailscale up --login-server https://<votre-domaine> --authkey <clé>. Les applications graphiques savent aussi viser un serveur personnalisé : sur macOS, Option + clic sur l’icône Tailscale, menu Debug, puis Custom Login Server ; sur iOS, Use custom coordination server dans le menu de connexion ; sur Android, Use an alternate server ; sur Windows, tailscale login --login-server dans PowerShell.

Sans Docker : le paquet .deb officiel

Le projet publie des paquets .deb pour Debian et Ubuntu, et les recommande sur ces distributions : ils créent l’utilisateur système headscale, posent une configuration par défaut et installent l’unité systemd. C’est la voie la plus simple si Headscale est seul sur son VPS ou si vous préférez un service natif à un conteneur. Les commandes de gestion sont les mêmes que plus haut, sans le préfixe docker exec headscale.

Installer Headscale avec le paquet .deb

  1. Télécharger et installer le paquet

    Récupérez le paquet de la version voulue sur la page des releases GitHub, pour votre architecture (amd64 ou arm64), et installez-le avec apt, qui résout les dépendances :

    HEADSCALE_VERSION="0.29.7"
    HEADSCALE_ARCH="amd64"
    wget --output-document=headscale.deb \
      "https://github.com/juanfont/headscale/releases/download/v${HEADSCALE_VERSION}/headscale_${HEADSCALE_VERSION}_linux_${HEADSCALE_ARCH}.deb"
    sudo apt install ./headscale.deb

    Vérifiez ensuite : headscale version doit afficher 0.29.7.

  2. Adapter la configuration

    Le paquet dépose la configuration dans /etc/headscale/config.yaml et un exemple à jour dans /usr/share/doc/headscale/examples/config-example.yaml. Modifiez les mêmes clés que pour Docker (server_url, database, dns.base_domain), mais gardez listen_addr: 127.0.0.1:8080 : le service tourne sur l’hôte, seul le reverse proxy doit l’atteindre. Les données vivent dans /var/lib/headscale.

  3. Redémarrer et vérifier le service

    Relancez le service pour qu’il relise la configuration, puis contrôlez son état et ses journaux :

    sudo systemctl restart headscale
    sudo systemctl status headscale
    sudo journalctl -u headscale -f

    La sortie doit afficher Active: active (running). Au premier démarrage, les erreurs les plus fréquentes sont une server_url sans schéma https:// et un domaine MagicDNS identique à celui du serveur.

  4. Utiliser la CLI sans être root

    La CLI parle au service par le socket Unix /var/run/headscale/headscale.sock, accessible par défaut au seul utilisateur headscale et à root. Passez par sudo, exécutez les commandes en tant qu’utilisateur headscale, ou ajoutez votre compte au groupe headscale. Vérifiez l’accès avec headscale users list.

Exposer Headscale en HTTPS derrière Nginx

Les clients Tailscale parlent à Headscale avec leur propre protocole, transporté par une connexion WebSocket ouverte en POST, dont l’en-tête Upgrade vaut tailscale-control-protocol. Le reverse proxy doit donc relayer les en-têtes Upgrade et Connection tels quels et ne pas mettre les réponses en tampon. La configuration ci-dessous suit l’exemple de la documentation du projet ; obtenez d’abord le certificat avec certbot (certbot certonly --nginx -d vpn.votre-domaine.com).

map $http_upgrade $connection_upgrade {
  default keep-alive;
  ''      close;
}

server {
  listen 80;
  server_name vpn.votre-domaine.com;
  location = /generate_204 { return 204; }
  location / { return 301 https://$server_name$request_uri; }
}

server {
  listen 443 ssl;
  http2 on;
  server_name vpn.votre-domaine.com;
  ssl_certificate     /etc/letsencrypt/live/vpn.votre-domaine.com/fullchain.pem;
  ssl_certificate_key /etc/letsencrypt/live/vpn.votre-domaine.com/privkey.pem;

  location / {
    proxy_http_version 1.1;
    proxy_set_header Upgrade $http_upgrade;
    proxy_set_header Connection $connection_upgrade;
    proxy_set_header Host $host;
    proxy_set_header X-Real-IP $remote_addr;
    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    proxy_set_header X-Forwarded-Proto $scheme;
    proxy_buffering off;
    proxy_pass http://127.0.0.1:8080;
  }
}

Laissez tls_cert_path et tls_key_path vides dans config.yaml : Nginx termine TLS, et l’avertissement listening without TLS au démarrage est alors attendu. Pour que les journaux de Headscale montrent la vraie IP des clients, déclarez le proxy comme source de confiance. En installation native, la boucle locale suffit ; en Docker, ajoutez aussi le réseau du pont Docker (docker network inspect), car le conteneur voit arriver le proxy depuis sa passerelle :

trusted_proxies:
  - 127.0.0.1/32
  - ::1/128

Caddy fonctionne aussi, avec un simple reverse_proxy 127.0.0.1:8080. En revanche, le proxy de Cloudflare et Cloudflare Tunnel ne sont pas pris en charge, faute de gérer les WebSocket en POST : l’enregistrement DNS du serveur doit rester en mode DNS seulement.

Associer Headscale à Authelia pour un accès réseau protégé par MFA

Headscale gère le contrôle d’accès au niveau réseau (quelles IP peuvent communiquer avec quels pairs), mais il n’applique pas d’authentification au niveau applicatif. Associez-le à Authelia sur le même VPS : faites passer vos services internes (accessibles uniquement via le maillage) par la couche forward-auth d’Authelia. Les utilisateurs doivent valider un MFA pour accéder aux services, même une fois sur le maillage — de la défense en profondeur pour les charges sensibles.

Vérifier que les nœuds se voient

Un nœud listé par headscale nodes list prouve seulement qu’il a joint le serveur de coordination. Avant d’y faire passer du trafic réel, vérifiez le chemin de bout en bout depuis les clients eux-mêmes.

Contrôler le maillage depuis un client

  1. Lire l’état du réseau

    Sur un nœud enregistré, lancez tailscale status. La commande liste les pairs avec leur IP de maillage, leur nom et le type de liaison : direct signifie que le tunnel WireGuard est établi sans intermédiaire, relay qu’il passe par un relais DERP — fonctionnel, mais avec une latence plus élevée.

  2. Tester la connectivité

    Relevez l’IP d’un pair dans tailscale status, puis ping 100.64.0.2, ou mieux tailscale ping <nom-du-nœud>, qui indique si la réponse arrive en direct ou par un relais. Si le pair est listé mais ne répond pas, tailscale netcheck mesure la latence vers chaque région DERP et signale un UDP sortant filtré.

  3. Tester la résolution MagicDNS

    Avec dns.magic_dns: true, chaque nœud répond à son nom court et à son nom complet : ping nom-du-noeud ou ping nom-du-noeud.mesh.votre-domaine.com. Aucun enregistrement DNS public n’est nécessaire pour ces noms internes. Si la résolution échoue, tailscale dns status montre la configuration DNS que le client a reçue du serveur.

Cas d’usage : SSH entre VPS sans exposer le port 22

Une fois vos VPS de développement et de production enregistrés sur le même maillage, SSH n’a plus besoin d’écouter sur l’interface publique : la connexion passe par l’adresse de maillage, dans le tunnel WireGuard. Gardez un accès console ouvert chez votre fournisseur avant de toucher au pare-feu, au cas où une règle vous enfermerait dehors.

Restreindre SSH au réseau maillé

  1. Repérer l’interface et l’adresse de maillage

    Sur chaque VPS, le client Tailscale crée l’interface tailscale0. tailscale ip -4 affiche l’adresse de maillage de la machine ; notez celle du serveur de production, par exemple 100.64.0.3.

  2. N’autoriser SSH que par tailscale0

    Sur le VPS de production, autorisez SSH sur l’interface de maillage avant de le refuser ailleurs — UFW applique la première règle qui correspond :

    ufw allow in on tailscale0 to any port 22 proto tcp
    ufw deny 22/tcp
    ufw enable
    ufw status verbose

    Le port 22 n’est plus joignable depuis Internet, mais reste ouvert à tous les nœuds du maillage autorisés par votre politique.

  3. Se connecter par le maillage

    Depuis le VPS de développement ou votre poste enregistré, connectez-vous par l’IP ou le nom MagicDNS : ssh [email protected] ou ssh [email protected]. Tout transite dans le tunnel chiffré ; restreignez ensuite dans la politique Headscale quels groupes peuvent atteindre le port 22 de ce serveur.

Migrer une équipe déjà sur Tailscale

La bascule ne demande aucune réinstallation : le client officiel accepte l’option --login-server, et il suffit de le déconnecter de l’ancien réseau puis de le reconnecter à votre serveur. Chaque machine est coupée quelques secondes pendant l’opération. Comme votre serveur attribue lui-même les adresses 100.x et les noms MagicDNS, prévoyez de mettre à jour les scripts, règles de pare-feu et fichiers de configuration qui citent les anciennes.

Basculer les clients vers Headscale

  1. Reprendre la politique d’accès

    Copiez le fichier de politique de votre tailnet depuis l’éditeur Access controls de la console Tailscale et repartez-en : le format HuJSON est le même. Contrôlez-le avec headscale policy check avant la bascule — certaines fonctions, comme les IP sets, ne sont pas prises en charge, et seul un sous-ensemble des autogroups existe.

  2. Déconnecter puis reconnecter chaque client

    Sur Linux ou en ligne de commande, enchaînez la déconnexion et la reconnexion avec une clé de pré-authentification :

    tailscale logout
    tailscale up --login-server https://vpn.votre-domaine.com --authkey <PREAUTHKEY>

    Sur macOS, iOS, Android et Windows, déconnectez le compte dans l’application, puis ajoutez le serveur personnalisé comme décrit plus haut.

  3. Commencer par les machines de test

    Basculez d’abord un poste et un serveur de test, vérifiez tailscale status et la résolution des noms, puis les machines de développement et, en dernier, la production. Tant que des machines restent de l’autre côté, les deux réseaux ne se voient pas : planifiez la bascule d’un service et de ses clients dans la même fenêtre.

  4. Fermer ou rétrograder le compte Tailscale

    Une fois tous les nœuds migrés et vérifiés, fermez le tailnet ou repassez sur le plan Personal si vous gardez un usage personnel. Générez une nouvelle clé de pré-authentification pour les prochains enregistrements plutôt que de garder indéfiniment celle de la migration.

Headscale vs Tailscale Cloud

Tailscale Cloud reste la voie la plus simple pour les petites équipes : aucun serveur à maintenir, des mises à jour automatiques, une facturation intégrée — et le plan Personal reste gratuit jusqu’à 6 utilisateurs. Au-delà, le plan Standard est affiché à 8 $ par utilisateur et par mois sur la grille entrée en vigueur le 8 avril 2026 : 40 $ par mois pour cinq personnes, 80 $ pour dix. Headscale coûte le prix du VPS, quel que soit l’effectif — sur ServOrbit, le VPS Solo (2 vCPU / 4 GB) à 99 DH/mois suffit pour des dizaines de nœuds — plus le temps d’exploitation : mises à jour, sauvegardes, surveillance.

Headscale prend donc tout son sens au-delà de 6 utilisateurs, lorsque la résidence des données impose de garder la topologie de votre réseau hors des serveurs tiers, ou lorsque vous voulez une auditabilité complète de vos logs de coordination. Les clients sont identiques — passer de Tailscale Cloud à Headscale revient à relancer tailscale up --login-server sur chaque appareil.

Tailscale Personal, Tailscale Standard et Headscale

Faites défiler le tableau

CritèreTailscale PersonalTailscale StandardHeadscale sur VPS
PrixGratuit8 $ par utilisateur et par moisLe coût du VPS
UtilisateursJusqu’à 6Sans plafondAucune limite logicielle
Appareils des utilisateursSans plafondSans plafondAucune limite logicielle
Serveur de coordinationCloud TailscaleCloud TailscaleVotre VPS, sous votre contrôle
ClientClient Tailscale officielClient Tailscale officielClient Tailscale officiel (`--login-server`)
MagicDNS, ACL, GrantsOuiOuiOui, sur votre propre domaine
Funnel et ServeProposés par TailscaleProposés par TailscaleNon pris en charge
MaintenanceNulle (service managé)Nulle (service managé)Mises à jour, sauvegardes, surveillance

Ce que Headscale ne remplace pas

Headscale implémente le serveur de coordination, pas toute la plateforme commerciale. Sa propre documentation liste ce qui manque : Tailscale Funnel (publier un service local sur Internet), Tailscale Serve (le partager dans le tailnet par un proxy local) et les journaux de flux réseau ne sont pas pris en charge ; les groupes OIDC ne peuvent pas servir dans les ACL. Il n’y a pas non plus de console web officielle : tout passe par la CLI ou l’API. Si votre usage se limite à la connectivité maillée, à MagicDNS, aux politiques d’accès, aux sous-réseaux et aux exit nodes, Headscale couvre le besoin ; si vous utilisez activement Funnel ou Serve, pesez ces fonctions face à l’économie avant de migrer — ou regardez NetBird, qui auto-héberge aussi son interface d’administration.

Sauvegardes et mises à jour

  • Sauvegardez avant chaque mise à jour : Headscale applique ses migrations de base au démarrage de la nouvelle version. Arrêtez le service, copiez la configuration et les données, puis relancez : cd /opt/headscale && docker compose stop, cp -aR /opt/headscale /opt/headscale.backup-$(date +%Y%m%d%H%M%S), docker compose up -d.
  • Le dossier de données contient db.sqlite et noise_private.key : perdre cette clé change l’identité du serveur et oblige tous les nœuds à se réenregistrer. Copiez-le aussi hors du VPS, par exemple vers un stockage objet.
  • Montez de version en version : le projet impose de passer par chaque version mineure stable (par exemple 0.27 puis 0.28 puis 0.29), toujours dans son dernier correctif, sans en sauter.
  • Lisez la note de version sur GitHub avant chaque mise à jour : elle signale les changements cassants de configuration. Comparez ensuite votre config.yaml au fichier d’exemple de la nouvelle version.

Dépannage : les erreurs les plus fréquentes

  • Le client n’arrive pas à s’enregistrer : vérifiez que https://vpn.votre-domaine.com/health répond depuis l’extérieur, que server_url correspond exactement au domaine du certificat, et que le proxy relaie bien les en-têtes Upgrade et Connection.
  • Connexions en relay au lieu de direct : un NAT strict ou un pare-feu bloque l’UDP entre les deux nœuds. Lancez tailscale netcheck des deux côtés pour voir ce qui est filtré ; le trafic passe quand même, par les relais DERP.
  • Nœud listé offline : le client a joint le serveur mais ne maintient pas la session. Vérifiez systemctl status tailscaled et journalctl -u tailscaled sur le nœud ; un pare-feu local qui coupe les connexions sortantes est la cause la plus courante.
  • Headscale refuse de démarrer après une mise à jour : une clé de configuration a été renommée ou retirée. Le journal la nomme ; reportez-vous au fichier d’exemple de la version installée.
  • MagicDNS ne résout pas : contrôlez que dns.magic_dns est à true et que dns.base_domain diffère du domaine de server_url, puis reconnectez le client pour qu’il récupère la nouvelle configuration DNS.

Déployez Headscale sur votre VPS en un clic

Auto-hébergez votre serveur de contrôle Tailscale avec des utilisateurs illimités et sans dépendance au cloud. ServOrbit provisionne une instance Headscale prête à l’emploi — configuration générée, HTTPS prêt, première clé d’authentification affichée dans la sortie du job.