Auto-héberger Headscale sur un serveur dédié : pas à pas
Headscale vous donne la moitié de Tailscale qui n'est pas open source : le serveur de coordination. Faites-le tourner vous-même, et les clients Tailscale officiels (avec leur excellent NAT traversal et leur prise en charge multiplateforme) se connectent à une infrastructure que vous contrôlez, sans tarification par utilisateur et sans qu'un tiers détienne les clés de votre réseau. Ce guide est le parcours pratique : installation depuis les packages officiels, TLS fait simplement, utilisateurs et ACL, le relais DERP intégré sur votre propre réseau, et les limites opérationnelles honnêtes d'un projet délibérément restreint.
Loading...
D'abord la réponse : ce que vous construisez
Un petit serveur qui fait tourner Headscale (l'implémentation open source du serveur de coordination de Tailscale), avec les applications Tailscale officielles sur chaque appareil pointées vers lui plutôt que vers le cloud de Tailscale. Même mesh WireGuard, mêmes clients, même NAT traversal ; le control plane (clés, listes de peers, ACL) vit sur votre propre matériel, sans coût par utilisateur. La mise en place prend environ une demi-heure et nécessite :
- Une petite machine Linux always-on avec une IP publique : l'empreinte de Headscale est minuscule ; le moindre serveur modeste ou la moindre tranche de VPS suffit largement.
- Un nom DNS qui pointe dessus (
headscale.example.com, à remplacer partout par le vôtre). - Ports : 443 (ou le port de votre choix) pour les clients ; 80 si vous utilisez le flux Let's Encrypt par défaut ; 3478/udp si vous activez le relais intégré.
Cela vaut la peine de le répéter depuis notre comparatif des VPN mesh (où cette option a remporté la place "UX de Tailscale, contrôle auto-hébergé") : Headscale est délibérément limité à un tailnet unique, un réseau, une équipe ou une organisation. C'est la réponse auto-hébergée pour l'infrastructure personnelle et les petites organisations, pas un clone multi-tenant de Tailscale pour entreprises. À cette échelle, c'est excellent.
Étape 1 : installation
La voie recommandée par le projet, ce sont ses packages .deb officiels (Ubuntu 22.04+/Debian 12+), qui mettent en place pour vous l'utilisateur headscale, le squelette de configuration et l'unité systemd. Récupérez la version actuelle (v0.29.x au moment de l'écriture, consultez les releases) :
wget https://github.com/juanfont/headscale/releases/download/v0.29.2/headscale_0.29.2_linux_amd64.deb
apt install ./headscale_0.29.2_linux_amd64.deb
(Des images Docker existent, mais le projet ne prend pas officiellement en charge le déploiement Docker ; sur votre propre serveur, le package est à la fois plus simple et la voie officiellement prise en charge.)
Étape 2 : configuration
Tout se trouve dans /etc/headscale/config.yaml. Le delta minimal fonctionnel par rapport à l'exemple fourni :
server_url: https://headscale.example.com:443
listen_addr: 0.0.0.0:443
# TLS, the simple way: built-in Let's Encrypt
tls_letsencrypt_hostname: headscale.example.com
Trois décisions qui méritent d'être prises consciemment :
- TLS : l'intégration Let's Encrypt intégrée est l'option avec le moins de pièces mobiles. Le challenge HTTP-01 par défaut nécessite que le port 80 soit joignable ; TLS-ALPN-01 valide alternativement directement sur le 443. Un reverse proxy (nginx/Caddy) devant fonctionne aussi et c'est courant, mais notez la mise en garde honnête de la documentation : le guide de reverse proxy est maintenu par la communauté, les upgrades WebSocket doivent être configurés, et le passage par un proxy Cloudflare n'est explicitement pas pris en charge. Moins de couches, moins de surprises : le TLS direct est la recommandation ici.
- Base de données : SQLite est le choix par défaut et la bonne réponse à cette échelle, un seul fichier dans
/var/lib/headscale/db.sqlite. - DNS : la section
dns:donne à votre mesh des noms MagicDNS (dans le stylebase_domain: ts.example.com) ; configurez-la maintenant, la renommer plus tard est pénible.
Ensuite :
systemctl enable --now headscale
headscale users create jesse
Étape 3 : connecter les clients
Sur chaque appareil, installez l'application Tailscale normale et pointez-la vers votre serveur :
tailscale up --login-server https://headscale.example.com
La commande affiche une URL ; la visiter vous donne la clé du node, que vous approuvez côté serveur (headscale nodes register --user jesse --key <key>). Pour les machines sans surveillance (serveurs qui rejoignent le mesh), passez l'étape interactive avec une clé de pré-authentification :
headscale preauthkeys create --user jesse --expiration 1h
tailscale up --login-server https://headscale.example.com --authkey <key>
Headscale prend en charge les dix dernières releases du client Tailscale sous Linux, Windows, macOS, iOS et Android (les plateformes mobiles et de bureau ont une petite étape supplémentaire pour définir un serveur personnalisé ; la documentation couvre chacune d'elles, et votre serveur sert même des pages d'aide sur /windows et /apple). Une fois deux appareils connectés, lancez tailscale status et pingez entre eux : vous avez un mesh.
Pour du SSO plutôt qu'une gestion des utilisateurs en CLI, la prise en charge OIDC de Headscale est solide : pointez-la vers Authentik, Keycloak, Entra ID ou Google (activez PKCE, comme le recommande la documentation), et l'enregistrement des appareils devient une simple connexion par navigateur.
Étape 4 : les ACL
Par défaut, chaque node atteint chaque node, ce qui convient pour une seule personne, pas pour un réseau avec des serveurs de sensibilités différentes. La policy est un fichier HuJSON (du JSON avec des commentaires), le même format que chez Tailscale :
// /etc/headscale/policy.hujson
{
"tagOwners": { "tag:server": ["jesse@"] },
"acls": [
// everyone reaches web things on servers
{ "action": "accept", "src": ["*"], "dst": ["tag:server:80,443"] },
// only jesse reaches SSH anywhere
{ "action": "accept", "src": ["jesse@"], "dst": ["*:22"] }
]
}
Référencez-le via policy.path dans la config et rechargez le service pour appliquer les changements. Remarques sur l'état actuel du projet : le moteur de règles est en v2 (groups, tags, autogroups comme autogroup:internet pour le contrôle des exit-nodes), la nouvelle syntaxe grants est la direction que prend le projet, et un manque honnête : les groups OIDC ne peuvent pas encore être utilisés dans les règles de policy. La logique du refus par défaut s'applique ici exactement comme dans n'importe quel firewall : écrivez les accepts que vous voulez vraiment, rien d'autre.
Étape 5 : votre propre relais DERP (facultatif, mais ça vaut le coup)
Quand deux peers n'arrivent pas à établir une connexion directe (NAT strict des deux côtés, UDP bloqué), le trafic retombe sur un relais DERP. Par défaut, cela veut dire la flotte de relais publique de Tailscale : fonctionnelle, mais le seul moment où votre mesh auto-hébergé dépend silencieusement de l'infrastructure de quelqu'un d'autre, avec la latence du node le plus proche, quel qu'il soit. Headscale intègre un serveur DERP ; l'activer garde le trafic relayé sur votre propre machine :
derp:
server:
enabled: true
stun_listen_addr: "0.0.0.0:3478"
Ouvrez 3478/udp directement vers le serveur (STUN ne peut pas passer par un reverse proxy). Les paquets qui transitent par le relais restent chiffrés WireGuard de bout en bout (DERP ne fait que transmettre du texte chiffré ; il ne peut rien lire), donc le gain ici porte sur la latence et l'autosuffisance, pas sur la confidentialité. Sur un réseau bien peeré, la différence est tangible : votre pire scénario devient un aller-retour vers votre propre serveur à faible latence, plutôt qu'un détour par un relais public lointain.
Exploitation
- Sauvegardes : l'état complet tient en trois éléments :
/var/lib/headscale/(base de données + clé noise),/etc/headscale/(config + policy). Faites-en des snapshots ou des sauvegardes de fichiers ; restaurer sur une machine neuve consiste à copier, puis démarrer. - Mises à jour : lisez le changelog (le projet est honnête sur les breaking changes : la v0.26 a remplacé le moteur de règles ; la v0.29 a changé la sémantique des wildcards), puis installez le nouveau .deb et redémarrez. Les clients se reconnectent automatiquement.
- Ressources : le projet ne publie aucun chiffre de dimensionnement et n'en a pas besoin ; il coordonne sans effort des centaines d'appareils sur du matériel minimal. La seule remarque des mainteneurs sur la montée en charge : le coût, c'est le recalcul de la map lié au CPU quand la topologie change beaucoup, donc ce qui compte, c'est le nombre de connexions et leur renouvellement, pas le trafic ; les données circulent en peer-to-peer et ne passent jamais par le serveur de coordination (sauf en cas de repli DERP, voir plus haut).
- Visibilité : il n'y a délibérément pas d'interface web intégrée ; la CLI couvre l'administration, et des interfaces tierces (headscale-admin, Headplane et consorts) existent comme projets communautaires ; traitez-les comme tel, et notez que certaines exigent la policy en mode
database.
Les limites, honnêtement
Choisissez Headscale en sachant ce qu'il n'est pas. Un tailnet unique : pas de multi-tenant, par conception et selon la FAQ. Géré par la communauté : c'est une réimplémentation open source indépendante (avec, historiquement, un employé de Tailscale qui contribuait à titre personnel), pas un produit éditeur avec un SLA ; les nouvelles fonctionnalités de Tailscale arrivent une fois réimplémentées, pas le jour de leur lancement. Vous êtes l'administrateur : les renouvellements TLS, les mises à jour, les sauvegardes et le bipeur à 3 heures du matin, c'est pour vous. Si ces compromis vous semblent des coûts plutôt que l'intérêt même de la démarche, l'offre gratuite hébergée de Tailscale (ou NetBird, selon notre comparatif) est l'outil qui vous conviendra mieux. Si vous y lisez plutôt de la souveraineté, allez-y : c'est l'un des projets auto-hébergés les plus gratifiants qui soient, avec une utilité élevée pour une surface opérationnelle minime.
Questions fréquentes
Headscale est-il prêt pour la production ?
Pour le périmètre visé (le tailnet d'une seule organisation, géré par quelqu'un à l'aise avec l'administration d'un service Linux) oui : le projet est mature, publié activement, et largement déployé exactement pour cet usage. Les réserves portent sur le périmètre, pas sur la qualité : pas de multi-tenant, pas de contrat de support éditeur, et parfois des breaking changes entre versions mineures, qui supposent un administrateur qui lit les changelogs. Adapté à une flotte de vos propres serveurs et appareils, c'est du solide ; poussez-le vers un "produit pour des clients" et vous sortez de son champ de conception.
Pourquoi mes appareils se connectent-ils, mais le trafic transite lentement par le serveur ?
Ils sont retombés sur le relayage DERP, généralement visible dans tailscale status sous forme d'un tag relay plutôt qu'une adresse directe. Les chemins WireGuard directs ne touchent jamais votre boîtier Headscale, donc si "tout transite par le serveur", cela signifie que le NAT traversal a échoué (NAT strict, UDP bloqué) et que les paquets empruntent le relais. Solutions dans l'ordre : vérifiez qu'UDP n'est bloqué d'aucun des deux côtés, activez le DERP intégré (pour que le repli soit au moins votre propre relais rapide), et pour les paires relayées en permanence, vérifiez si un côté peut ouvrir un port direct ; un serveur dédié avec UDP ouvert fait un excellent node ancre toujours joignable directement.
Puis-je utiliser mon mesh pour atteindre le réseau privé/de gestion de mes serveurs ?
Oui. C'est exactement le cas d'usage administrateur que mettait en avant l'article comparatif. Faites tourner un node dans le segment privé comme subnet router (tailscale up --advertise-routes=10.0.0.0/24 ..., approuvé avec headscale nodes approve-routes), et les membres autorisés du mesh atteignent tout le segment (IPMI, services internes) sans qu'aucun d'entre eux n'ait de listener public. Verrouillez la route derrière une ACL stricte et traitez le node subnet router avec le soin réservé à un bastion : c'est désormais le pont vers votre réseau le plus sensible.
Comment cela se compare-t-il à simplement faire tourner WireGuard ?
Headscale, c'est WireGuard en dessous ; ce que vous ajoutez, c'est le control plane : distribution automatique des clés, NAT traversal, MagicDNS, ACL, et des applications mobiles que des non-experts peuvent utiliser. Pour deux serveurs statiques, WireGuard nu reste plus simple. Le basculement survient avec des appareils nomades, un nombre croissant de peers, ou des utilisateurs qui méritent une application avec un simple interrupteur ; à ce moment-là, Headscale offre l'expérience produit tout en gardant la propriété de WireGuard nu qui comptait vraiment : l'infrastructure de personne d'autre dans votre control path.
Déploiement chez Serverside
Un hôte Headscale veut exactement ce qu'un petit serveur dédié ou une instance cloud apporte ici : une machine always-on avec une IP publique stable sur un réseau bien peeré (ASN 55285, là où votre relais DERP intégré tire vraiment parti de son avantage en latence) derrière une mitigation DDoS permanente, puisque l'unique listener public de votre serveur de coordination mérite une protection. Les meshes plus grands qui ancrent des subnet routers dans des réseaux privés trouvent naturellement leur place sur une ligne dédiée.
Lectures connexes : la décision VPN mesh que ce guide met en pratique, les règles de firewall pour l'hôte sous-jacent, et la checklist de durcissement à suivre avant tout cela.

Écrit par
Co-founder & CTO, Serverside.com
Jesse is the co-founder and CTO of Serverside.com, where he leads the engineering behind the company's bare-metal cloud: from the ASN 55285 backbone to the core automation that drives day-to-day operation. He writes about dedicated servers, operating systems, and running production workloads on bare metal.
Continuer la lecture
Voir tous les articlesCet article vous a plu ?
Recevez les nouveaux guides et articles techniques par e-mail. Sans spam, désinscription à tout moment.




canadien et
néerlandais