Headscale : héberger son propre serveur de coordination Tailscale
Tailscale simplifie WireGuard en gérant automatiquement les clés, les routes et la découverte des pairs via ses serveurs de coordination. Headscale reimplemente ce serveur de coordination en open source, permettant de l’héberger soi-même. Vous gardez le client Tailscale (qui ne change pas), mais le plan de contrôle tourne sur votre infrastructure.
Architecture : comment ça fonctionne
Dans Tailscale standard :
[Client A] ──→ [Serveurs Tailscale] ←── [Client B]
↓ coordination
[Client A] ←────────────→ [Client B]
(tunnel WireGuard direct)
Avec Headscale :
[Client A] ──→ [Votre serveur Headscale] ←── [Client B]
↓ coordination
[Client A] ←────────────────→ [Client B]
(tunnel WireGuard direct, identique)
Le trafic de données reste pair-à-pair (WireGuard direct). Seule la coordination (échange de clés publiques, gestion des ACLs, authentification) passe par Headscale.
Installation avec Docker
# docker-compose.yml
services:
headscale:
image: headscale/headscale:latest
container_name: headscale
volumes:
- ./config:/etc/headscale
- headscale-data:/var/lib/headscale
ports:
- "8080:8080"
- "9090:9090" # métriques Prometheus (optionnel)
command: serve
restart: unless-stopped
volumes:
headscale-data:
Configuration
# config/config.yaml
server_url: https://headscale.mon-domaine.com
listen_addr: 0.0.0.0:8080
metrics_listen_addr: 0.0.0.0:9090
private_key_path: /var/lib/headscale/private.key
noise:
private_key_path: /var/lib/headscale/noise_private.key
ip_prefixes:
- 100.64.0.0/10 # plage Tailscale standard
derp:
server:
enabled: false # utiliser les serveurs DERP Tailscale par défaut
urls:
- https://controlplane.tailscale.com/derpmap/default
db_type: sqlite
db_path: /var/lib/headscale/db.sqlite
dns_config:
magic_dns: true
base_domain: mon-reseau.internal
nameservers:
- 1.1.1.1
Exposition avec Caddy (HTTPS requis)
# Caddyfile
headscale.mon-domaine.com {
reverse_proxy headscale:8080
}
Headscale nécessite HTTPS — les clients Tailscale refusent une connexion en HTTP.
Gestion des utilisateurs et nœuds
Headscale s’administre via la CLI headscale dans le container :
# Alias pratique
alias hs='docker exec headscale headscale'
# Créer un utilisateur (équivalent d'un "tailnet")
hs users create alice
# Lister les utilisateurs
hs users list
# Générer une clé d'enregistrement pour un nœud
hs preauthkeys create --user alice --expiration 24h
# Lister les nœuds enregistrés
hs nodes list
# Supprimer un nœud
hs nodes delete --identifier 3
Connecter un client Tailscale à Headscale
Sur n’importe quel appareil avec le client Tailscale installé :
# Linux
sudo tailscale up --login-server https://headscale.mon-domaine.com
# macOS (depuis le terminal)
sudo tailscale up --login-server https://headscale.mon-domaine.com
# Windows (PowerShell en admin)
tailscale up --login-server https://headscale.mon-domaine.com
La commande affiche une URL de type :
To authenticate, visit: https://headscale.mon-domaine.com/register/nodekey:abc123...
Enregistrez le nœud depuis l’hôte Headscale :
hs nodes register --user alice --key nodekey:abc123...
Ou utilisez une pre-auth key pour l’enregistrement automatique (idéal pour CI/CD ou scripts) :
# Générer la clé
hs preauthkeys create --user alice --expiration 1h --reusable
# Sur le client
sudo tailscale up \
--login-server https://headscale.mon-domaine.com \
--authkey tskey-auth-XXXXX
ACLs (contrôle d’accès)
Les ACLs Headscale suivent la même syntaxe que Tailscale. Fichier config/acls.yaml :
acls:
# Les admins ont accès à tout
- action: accept
src: ["tag:admin"]
dst: ["*:*"]
# Les développeurs accèdent aux serveurs de dev
- action: accept
src: ["tag:dev"]
dst: ["tag:dev-server:*"]
# Tout le monde peut pinger
- action: accept
src: ["*"]
dst: ["*:icmp"]
tagOwners:
tag:admin: ["alice"]
tag:dev: ["alice", "bob"]
tag:dev-server: ["alice"]
Appliquer les ACLs :
hs policy set --policy-file /etc/headscale/acls.yaml
Routes et exit nodes
# Approuver un exit node (pour router tout le trafic via un nœud)
hs routes list
hs routes enable --route 3
# Côté client : utiliser l'exit node
sudo tailscale up --exit-node=100.64.0.3
Headscale UI (interface web)
Headscale est headless par défaut. Des interfaces web communautaires existent :
headscale-ui (goodieshq/headscale-ui) :
# Ajouter au docker-compose.yml
headscale-ui:
image: ghcr.io/goodieshq/headscale-ui:latest
ports:
- "8081:80"
restart: unless-stopped
# Caddyfile
headscale.mon-domaine.com {
handle /web* {
reverse_proxy headscale-ui:80
}
reverse_proxy headscale:8080
}
Métriques Prometheus
Headscale expose des métriques sur le port 9090 :
# prometheus.yml
scrape_configs:
- job_name: headscale
static_configs:
- targets: ["headscale:9090"]
Métriques disponibles : nombre de nœuds, connexions actives, latence des requêtes.
+ Les points forts
- Contrôle total — aucune dépendance aux serveurs Tailscale pour la coordination. Vos données ne transitent pas par des serveurs tiers
- Gratuit sans limite — Tailscale gratuit est limité à 3 utilisateurs et 100 appareils. Headscale n’a aucune limite
- Clients Tailscale inchangés — iOS, Android, Windows, macOS, Linux utilisent le même client officiel
- Compatible avec l’écosystème Tailscale — Magic DNS, DERP servers, subnet routing, exit nodes
- Open source — code auditable, pas de black box
- Les points faibles
- Pas de client mobile officiel — les apps iOS et Android de Tailscale ne permettent pas de changer le serveur de coordination facilement (nécessite une version custom ou un profil MDM)
- Maintenance à votre charge — mises à jour, sauvegardes, disponibilité du serveur Headscale sont votre responsabilité. Si Headscale tombe, les nœuds existants continuent de communiquer, mais les nouveaux nœuds ne peuvent pas s’enregistrer
- Pas de support Tailscale — Headscale n’est pas un produit officiel Tailscale. Certaines fonctionnalités récentes (Tailscale SSH, Taildrive) ne sont pas encore implémentées
- Configuration plus complexe — par rapport à Tailscale “clé en main”, Headscale demande un serveur exposé sur internet, HTTPS configuré, et une gestion manuelle des nœuds
Tailscale vs Headscale
| Tailscale | Headscale | |
|---|---|---|
| Hébergement | Cloud Tailscale | Votre serveur |
| Limite appareils (gratuit) | 100 | Illimité |
| Limite utilisateurs (gratuit) | 3 | Illimité |
| Applications mobiles | ✅ Officielles | ⚠️ Workarounds |
| Tailscale SSH | ✅ | ❌ (partiel) |
| Maintenance | Zéro | À votre charge |
| Prix | Gratuit / $6/mois | Gratuit |
En résumé
Headscale est le choix logique dès que vous avez plus de 3 utilisateurs ou que la souveraineté des données est une contrainte. Le réseau mesh WireGuard reste identique — seul le plan de contrôle bascule chez vous. Pour un usage personnel simple avec moins de 100 appareils, Tailscale en mode cloud reste plus pratique. Pour une équipe ou une infrastructure d’entreprise, Headscale supprime à la fois les limites et la dépendance au cloud.
Voir aussi :
- Tailscale — la version cloud dont Headscale est l’alternative auto-hébergée
- Coolify — déployer Headscale facilement sur un VPS
- Portmaster — contrôler les connexions réseau de vos clients Headscale