Pourquoi remplacer le serveur de coordination cloud de Tailscale
Tailscale délègue l'orchestration WireGuard à un service cloud tiers. Headscale reproduit cette fonction en open-source, sur votre VPS — aucune dépendance externe, les données de topologie restant dans votre infrastructure.
Tailscale ne transporte pas votre trafic réseau : les paquets WireGuard voyagent directement de nœud à nœud, chiffrés de bout en bout. Ce que Tailscale gère via son cloud, c'est le plan de contrôle — l'échange de clés publiques, la découverte des pairs, l'attribution des adresses IP du sous-réseau 100.x.x.x, la résolution MagicDNS et la distribution des relais DERP. Sans ce serveur de coordination, les nœuds ne peuvent pas se trouver. Headscale est l'implémentation open source de ce serveur : il parle exactement le même protocole que le contrôleur Tailscale, ce qui signifie que vos clients Tailscale existants fonctionnent sans modification — il suffit de leur indiquer une nouvelle URL de login.
- Confidentialité des métadonnées : aucune liste de vos machines, adresses IP internes ou noms de nœuds ne transite par un serveur tiers. Le plan de contrôle reste dans votre infrastructure.
- Pas de limite de nœuds imposée : Headscale ne fixe pas de plafond sur le nombre de machines enregistrées — vous êtes limité par les ressources de votre VPS, non par une grille tarifaire.
- Pas de limite d'utilisateurs : le plan gratuit Tailscale est restreint à 3 utilisateurs ; Headscale gère autant d'utilisateurs que vous en créez.
- BYOD sans compte Tailscale : vos collaborateurs se connectent via la pré-clé d'authentification que vous générez, sans avoir à créer un compte sur tailscale.com.
- Intégration OIDC optionnelle : Headscale supporte la délégation d'authentification à un fournisseur OIDC (Keycloak, Authelia, Google Workspace) pour les équipes qui ont déjà un SSO.
- Serveurs DERP personnalisables : vous pouvez configurer vos propres relais DERP sur vos VPS pour minimiser la latence des connexions qui ne peuvent pas être directes.
- Pérennité : votre réseau mesh ne dépend pas des décisions commerciales d'un éditeur tiers — ni d'une éventuelle indisponibilité de son infrastructure.
Prérequis avant de commencer
Avant d'installer Headscale, vérifiez que votre environnement répond aux exigences suivantes.
- Un VPS sous Debian 11/12 ou Ubuntu 22.04/24.04, avec au moins 1 Go de RAM et un accès root — Headscale consomme moins de 50 Mo en fonctionnement normal.
- Le port UDP 41641 accessible depuis Internet sur le VPS serveur : c'est le port de signalisation WireGuard que les clients Tailscale utilisent pour contacter le coordinateur.
- Le port TCP 443 ou 8080 ouvert pour l'API HTTP/HTTPS d'Headscale (les clients s'y connectent pour l'enregistrement et la récupération des configs).
- Un client Tailscale installé sur chaque nœud que vous souhaitez relier — l'application officielle Tailscale fonctionne telle quelle avec Headscale.
- Facultatif : un nom de domaine pointant vers votre VPS si vous souhaitez activer HTTPS avec un certificat Let's Encrypt et MagicDNS sur un suffixe personnalisé.
Installation d'Headscale sur le VPS Debian/Ubuntu
Headscale s'installe via le paquet .deb officiel. L'installation comprend le binaire, le service systemd et la configuration nginx qui sert l'API gRPC et l'interface DERP.
Télécharger et installer le binaire Headscale
Headscale distribue des paquets
.debpour amd64 et arm64. Récupérez la version récente depuis les releases GitHub et installez-la avecdpkg:HEADSCALE_VERSION=$(curl -s https://api.github.com/repos/juanfont/headscale/releases/latest | grep tag_name | cut -d '"' -f4 | tr -d 'v') curl -Lo /tmp/headscale.deb \ https://github.com/juanfont/headscale/releases/latest/download/headscale_${HEADSCALE_VERSION}_linux_amd64.deb dpkg -i /tmp/headscale.debSur ARM64 (Raspberry Pi, serveurs Ampere), remplacez
linux_amd64parlinux_arm64. Vérifiez l'installation :headscale versiondoit retourner le numéro de version installé.Créer le fichier de configuration YAML
Le paquet crée automatiquement l'utilisateur système
headscaleet le dossier/etc/headscale/. Éditez le fichier de configuration principal :nano /etc/headscale/config.yamlConfiguration minimale fonctionnelle :
server_url: https://votre-domaine.com listen_addr: 0.0.0.0:8080 metrics_listen_addr: 127.0.0.1:9090 grpc_listen_addr: 127.0.0.1:50443 grpc_allow_insecure: false private_key_path: /var/lib/headscale/private.key noise: private_key_path: /var/lib/headscale/noise_private.key ip_prefixes: - fd7a:115c:a1e0::/48 - 100.64.0.0/10 derp: server: enabled: false urls: - https://controlplane.tailscale.com/derpmap/default auto_update_enabled: true update_frequency: 24h disable_check_updates: false ephemeral_node_inactivity_timeout: 30m db_type: sqlite3 db_path: /var/lib/headscale/db.sqlite log: level: info dns_config: override_local_dns: true nameservers: - 1.1.1.1 domains: [] magic_dns: true base_domain: votre-domaine.comRemplacez
votre-domaine.compar votre domaine réel. La valeurserver_urldoit correspondre à l'URL que vos clients peuvent atteindre depuis Internet.Créer les dossiers de données et générer les clés
Créez le dossier de données et attribuez-lui les bonnes permissions :
mkdir -p /var/lib/headscale chown headscale:headscale /var/lib/headscaleLancez Headscale une première fois pour générer automatiquement les clés privées :
headscale generate private-keyLes fichiers
private.keyetnoise_private.keysont créés dans/var/lib/headscale/. Ne les partagez jamais et sauvegardez-les — ils signent l'identité de votre serveur de coordination.Activer et démarrer le service systemd
Le paquet
.debinstalle l'unité systemd automatiquement. Activez-la au démarrage et lancez le service :systemctl enable --now headscale systemctl status headscaleLa sortie doit afficher
Active: active (running). Consultez les logs en temps réel si le service ne démarre pas :journalctl -u headscale -fLes erreurs fréquentes au premier démarrage sont une
server_urlmal formée (elle doit commencer parhttps://ouhttp://) ou un dossier/var/lib/headscaleinaccessible.Exposer Headscale via un reverse proxy HTTPS (recommandé)
Pour que vos clients se connectent en HTTPS, placez Headscale derrière nginx avec un certificat Let's Encrypt. Installez certbot et créez la configuration nginx :
apt install -y nginx certbot python3-certbot-nginx certbot --nginx -d votre-domaine.comConfiguration nginx pour Headscale (
/etc/nginx/sites-available/headscale) :server { listen 443 ssl; server_name votre-domaine.com; ssl_certificate /etc/letsencrypt/live/votre-domaine.com/fullchain.pem; ssl_certificate_key /etc/letsencrypt/live/votre-domaine.com/privkey.pem; location / { proxy_pass http://localhost:8080; proxy_http_version 1.1; proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection "upgrade"; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; } }Activez le site et rechargez nginx :
ln -s /etc/nginx/sites-available/headscale /etc/nginx/sites-enabled/ nginx -t && systemctl reload nginx
Connexion des nœuds clients au serveur Headscale maison
Une fois le serveur Headscale opérationnel, chaque machine cliente exécute le daemon Tailscale pointé sur votre URL Headscale au lieu des serveurs Tailscale Inc.
Créer un utilisateur Headscale
Headscale organise les nœuds par utilisateurs (l'équivalent des « namespaces » dans les anciennes versions). Créez un premier utilisateur depuis le VPS serveur :
headscale users create mon-equipe headscale users listVous pouvez créer autant d'utilisateurs que nécessaire pour séparer les environnements (dev, prod, prestataires).
Générer une pré-clé d'authentification (preauthkey)
Une preauthkey permet d'enregistrer un nœud sans intervention manuelle. Générez-en une pour votre utilisateur :
headscale preauthkeys create --user mon-equipe --expiration 24hL'option
--reusablecrée une clé utilisable plusieurs fois — pratique pour enregistrer plusieurs machines en automatisation. Sans cette option, la clé est à usage unique. Copiez la valeur retournée.Connecter un nœud client avec l'option --login-server
Sur chaque machine cliente (Linux, macOS, Windows, iOS, Android), le client Tailscale officiel est utilisé. Lors de la première connexion, indiquez l'URL de votre serveur Headscale avec le drapeau
--login-server:Sur Linux :
tailscale up --login-server https://votre-domaine.com --authkey VOTRE_PREAUTHKEYSur macOS, lancez depuis le terminal :
tailscale up --login-server https://votre-domaine.com --authkey VOTRE_PREAUTHKEYSi vous ne passez pas de preauthkey, Tailscale affiche une URL d'authentification. Vous devez alors valider l'enregistrement manuellement côté serveur Headscale :
# Sur le serveur, listez les nœuds en attente headscale nodes register --user mon-equipe --key <NODE_KEY_AFFICHÉ_PAR_TAILSCALE>Vérifier l'enregistrement du nœud
Depuis le VPS serveur, listez les nœuds enregistrés :
headscale nodes listChaque nœud enregistré affiche son nom, son IP mesh (dans le préfixe
100.64.x.x), son utilisateur et son statut. Un statutonlineconfirme que le nœud est actif et a pu joindre le coordinateur.
Vérification : les nœuds se voient-ils bien ?
Après avoir enregistré les nœuds, vérifiez la connectivité end-to-end avant de déplacer du trafic réel dans le réseau mesh.
Consulter l'état du réseau depuis un nœud client
Depuis n'importe quel nœud client enregistré, lancez :
tailscale statusLa commande liste tous les pairs joignables avec leur IP mesh, leur nom et leur statut de connexion (
active (direct)ouactive (relay)). Un pair endirectsignifie que la connexion WireGuard est établie sans relais — c'est le cas nominal quand les deux nœuds peuvent s'atteindre directement.Tester la connectivité par ping
Identifiez l'IP mesh du nœud cible depuis
tailscale status(format100.64.x.x) puis pingez-le :ping 100.64.0.2Un ping qui répond confirme que le tunnel WireGuard est établi entre les deux nœuds et que le plan de contrôle Headscale fonctionne correctement. Si le ping échoue mais que le nœud apparaît dans
tailscale status, consultez la section dépannage.Tester la résolution MagicDNS
Si vous avez activé
magic_dns: truedans la configuration Headscale et défini unbase_domain, chaque nœud est joignable par son nom court. Testez depuis un nœud client :ping nom-du-noeud # ou avec le FQDN ping nom-du-noeud.votre-domaine.comLa résolution DNS fonctionne via le sous-réseau mesh — aucun enregistrement DNS public n'est nécessaire pour les noms internes. Si la résolution échoue, vérifiez que le client Tailscale utilise bien le résolveur DNS injecté par le mesh :
tailscale status --selfaffiche le serveur DNS actif.
Tailscale gratuit vs Headscale : comparaison factuelle
Faites défiler le tableau
| Critère | Tailscale gratuit | Headscale (autogéré) |
|---|---|---|
| Nombre d'utilisateurs | 3 utilisateurs maximum | Aucune limite imposée par le logiciel |
| Nombre de nœuds | 100 nœuds maximum | Aucune limite imposée par le logiciel |
| Serveur de coordination | Cloud Tailscale (infrastructure tierce) | Votre propre VPS, sous votre contrôle |
| Coût mensuel | Gratuit dans les limites du plan | Coût du VPS uniquement (à partir de quelques euros/mois) |
| Client utilisé | Client Tailscale officiel | Client Tailscale officiel (compatible, --login-server) |
| MagicDNS | Oui, sur tailnet géré par Tailscale | Oui, sur votre domaine personnalisé |
| OIDC / SSO | Disponible sur plans payants | Disponible gratuitement via configuration YAML |
| Maintenance opérationnelle | Nulle (service managé) | Mises à jour de paquet, sauvegarde des clés |
Cas d'usage : accès SSH entre VPS dev et prod sans exposer le port 22
Le réseau mesh Headscale permet l'accès SSH entre serveurs sans ouvrir le port 22 sur l'interface publique — la connexion passe par l'adresse IP Tailscale interne à travers le tunnel WireGuard.
L'un des cas d'usage les plus courants d'un réseau mesh est l'accès SSH entre machines sans exposer le port 22 à Internet. Avec Headscale, vos VPS dev et prod sont enregistrés sur le même réseau mesh. Voici comment verrouiller SSH pour qu'il ne soit accessible que via le mesh.
Identifier les interfaces et adresses mesh
Sur chaque VPS, l'interface WireGuard créée par Tailscale s'appelle
tailscale0. Récupérez l'IP mesh locale :ip addr show tailscale0 # ou tailscale ip -4Notez l'IP mesh du VPS prod (ex.
100.64.0.3) et celle du VPS dev (ex.100.64.0.2).Configurer UFW pour restreindre SSH au réseau mesh
Sur le VPS prod, modifiez les règles UFW pour autoriser SSH uniquement depuis le sous-réseau mesh et bloquer le reste :
# Autoriser SSH depuis le sous-réseau mesh Headscale ufw allow in on tailscale0 to any port 22 proto tcp # Bloquer SSH depuis Internet ufw deny 22 ufw enableVérifiez l'état des règles :
ufw status verboseLe port 22 n'est plus accessible depuis Internet, mais reste joignable depuis n'importe quel nœud du réseau mesh.
Se connecter en SSH via le réseau mesh
Depuis le VPS dev (ou votre poste de travail enregistré sur le même réseau mesh), connectez-vous au VPS prod via son IP mesh ou son nom MagicDNS :
ssh [email protected] # ou via MagicDNS si activé ssh [email protected]La connexion transite entièrement dans le tunnel WireGuard chiffré. Aucun port n'est ouvert publiquement sur le VPS prod.
Durcissement : activez les ACL Headscale (acls: dans config.yaml) pour définir précisément quels nœuds peuvent joindre quels autres nœuds et sur quels ports. Activez les logs d'audit (log: level: info) et configurez un envoi de logs vers un collecteur centralisé si vous gérez plusieurs nœuds. Mettez à jour Headscale régulièrement — la compatibilité avec les versions récentes du client Tailscale est maintenue dans les versions récentes du serveur.
Dépannage : les erreurs les plus fréquentes
Les problèmes les plus courants lors du déploiement d'Headscale portent sur la connectivité réseau, les certificats TLS et la synchronisation des clés WireGuard.
Port UDP 41641 fermé. C'est la cause la plus courante d'échec de connexion directe entre nœuds. Le port 41641 doit être ouvert en UDP sur le VPS serveur pour que les nœuds puissent établir leurs tunnels WireGuard. Vérifiez avec ufw status et ouvrez-le si nécessaire : ufw allow 41641/udp. Si le port reste fermé, les connexions passent en mode relais DERP — les nœuds fonctionnent mais avec une latence plus élevée.
Problème de DERP : nœuds visibles mais non joignables. Headscale utilise par défaut la carte DERP publique de Tailscale (controlplane.tailscale.com/derpmap/default). Si votre VPS est dans une région non couverte ou si l'accès HTTPS sortant est filtré, les relais DERP sont inaccessibles. Vérifiez avec tailscale netcheck depuis un nœud client — la commande mesure la latence vers chaque région DERP et indique celles qui sont inaccessibles.
Clock skew : erreur d'authentification. Headscale utilise des jetons JWT avec une expiration courte. Si l'horloge du VPS serveur ou d'un nœud client dérive de plus de quelques minutes, les tokens sont rejetés avec une erreur token is expired ou token is not yet valid. Synchronisez l'horloge : systemctl enable --now systemd-timesyncd sur Debian/Ubuntu.
Nœud qui s'enregistre mais apparaît offline. Le nœud a bien contacté le serveur lors de l'enregistrement, mais ne maintient pas de connexion continue. Vérifiez que le service Tailscale tourne sur le nœud : systemctl status tailscaled. Consultez les logs : journalctl -u tailscaled -f. Le problème est souvent un pare-feu local qui bloque les connexions sortantes UDP.
Headscale : reprendre le contrôle de votre réseau mesh
Headscale transforme un abonnement à un service cloud propriétaire en infrastructure réseau que vous opérez, auditez et étendez vous-même — sans changer l'expérience côté client.
Headscale déplace le serveur de coordination Tailscale de l'infrastructure d'un tiers vers votre propre VPS. Le résultat est un réseau WireGuard mesh fonctionnellement identique — les mêmes clients, la même MagicDNS, le même comportement de traversée NAT — mais entièrement sous votre contrôle. Pour les équipes qui dépassent les 3 utilisateurs ou 100 nœuds du plan gratuit Tailscale, Headscale représente une alternative directe sans changement d'outillage côté client. Pour ceux qui ne veulent tout simplement pas qu'un serveur tiers soit dans la boucle de leur infrastructure, c'est la seule option cohérente avec cette exigence. L'installation décrite ici tient en moins de vingt minutes ; la maintenance se résume à mettre à jour un paquet Debian et à sauvegarder deux fichiers de clés.