Cybersécurité

Migrer de Tailscale Cloud à Headscale : tutoriel pas-à-pas 2026

12 min de lecture

📍 Article principal de la série : Headscale 2026 : guide pratique.

Vous payez 90 USD par mois pour 5 utilisateurs Tailscale Premium. Vous voulez basculer sur Headscale auto-hébergé sans casser la connectivité de votre équipe. Ce tutoriel détaille la procédure éprouvée chez plusieurs PME africaines : préparation, bascule par lots de 5 appareils, validation, et plan de rollback si quelque chose tourne mal.

Prérequis

  • Headscale en production avec HTTPS (voir Déployer Headscale).
  • Accès admin à votre compte Tailscale Cloud actuel.
  • Liste des appareils actifs avec propriétaire et rôle.
  • Niveau attendu : intermédiaire.
  • Temps estimé : 1 jour pour préparation, 1 à 3 jours pour bascule progressive.

Étape 1 — Audit de l’existant Tailscale Cloud

Listez via la CLI Tailscale Cloud :

tailscale status --json | jq '.Peer | to_entries | map({name: .value.HostName, ip: .value.TailscaleIPs[0], user: .value.UserID, online: .value.Online})'

Notez :

  • Nombre total d’appareils.
  • Appareils critiques (serveurs production, qui ne peuvent pas être déconnectés).
  • Subnet routers (annoncent des LAN).
  • Exit nodes éventuels.
  • ACL actuelles (export depuis Tailscale Admin Console).

Étape 2 — Reproduire les utilisateurs et ACL côté Headscale

Pour chaque utilisateur Tailscale Cloud, créer son équivalent Headscale :

headscale users create amadou
headscale users create fatou
headscale users create servers

Pour les ACL, exporter le HuJSON depuis Tailscale Admin Console (Settings → Access controls → Tailscale ACL) et copier-coller dans /etc/headscale/policy.hujson :

headscale policy set -f /etc/headscale/policy.hujson

Étape 3 — Test de bascule sur un appareil pilote

Choisir un appareil non-critique (votre laptop personnel). Procédure :

# Sur le pilote
tailscale logout
tailscale up --login-server=https://headscale.votre-entreprise.com --auth-key=PREAUTH_KEY

Vérifier sur Headscale :

headscale nodes list

Tester la connectivité vers les autres appareils encore sur Tailscale Cloud (impossible : les deux mesh sont distincts) puis vers les appareils sur Headscale (devrait marcher).

Étape 4 — Bascule par lots de 5 appareils

Stratégie : ne pas migrer en une fois pour limiter l’impact en cas de problème. Lot 1 : 3 développeurs + 1 serveur staging. Tester pendant 24h. Si tout va bien, lot 2 : 5 personnes du marketing + 1 serveur prod secondaire. Etc.

Pendant la bascule, les utilisateurs encore sur Tailscale Cloud ne voient plus les appareils déjà migrés. Communiquer clairement : « les serveurs production sont sur Headscale depuis 14h, reconfigurez votre client avant 18h ».

Étape 5 — Cas particulier : serveurs critiques en production

Pour un serveur Postgres production que vous ne pouvez pas déconnecter :

# Ne JAMAIS faire tailscale logout sur le serveur sans plan B
# Préparer la commande tailscale up Headscale avant
PREAUTH=$(headscale preauthkeys create -u servers --expiration 168h | tail -1)
echo "PREAUTH=$PREAUTH"

# Sur le serveur prod, dans une seule commande :
tailscale logout && \
  tailscale up --login-server=https://headscale.votre-entreprise.com --auth-key=$PREAUTH

L’opération prend 2 à 5 secondes. Si elle échoue, tailscale up sans argument se reconnecte à Tailscale Cloud (rollback automatique).

Étape 6 — Subnet routers et exit nodes

Pour les routeurs annonçant un LAN, mêmes flags qu’avec Tailscale Cloud :

tailscale up --login-server=https://headscale.votre-entreprise.com \
  --auth-key=PREAUTH \
  --advertise-routes=192.168.10.0/24 \
  --advertise-exit-node

Côté Headscale, valider les routes :

headscale routes list
headscale routes enable -r ROUTE_ID

Étape 7 — Décommissionnement Tailscale Cloud

Une fois tous les appareils migrés et stables pendant 7 jours :

  1. Tailscale Admin Console → Settings → Manage subscription.
  2. Choisir « Cancel subscription ».
  3. L’abonnement est annulé en fin de période, vous gardez l’accès jusqu’à la date.
  4. Au moment du cutoff, supprimer définitivement les appareils résiduels via Machines → Delete.

Erreurs fréquentes

Erreur Cause Solution
Client refuse de quitter Tailscale Cloud Tailscale Cloud verrouille certains réglages tailscale logout + redémarrer service
ACL HuJSON différentes entre Cloud et Headscale Versions de syntaxe Tester headscale policy check avant apply
MagicDNS ne fonctionne plus Base domain différent Updater configs DNS internes ou activer tailnet.ts.net miroir
Performances dégradées DERP relay éloigné Configurer DERP régional
Préauth key épuisée trop vite Non-réutilisable Flag --reusable + expiration longue pour les lots

Considérations propres à l’écosystème sous-régional

Trois précisions terrain. Bascule en heures décalées : effectuer les migrations entre 22h et 5h heure locale, quand l’usage est minimal. Pour une équipe couvrant Dakar/Lomé/Cotonou, choisir 23h GMT. Communication interne : en plus du mail, créer un canal Telegram ou WhatsApp Business « Migration Headscale » pour notifier en temps réel. Période de chevauchement : conserver l’abonnement Tailscale Cloud actif pendant 14 jours après bascule complète, comme rollback de sécurité. Coût : 90 USD que vous payez sur 14 jours, soit ~ 42 USD. Acceptable face au risque.

Tutoriels frères

FAQ

Mes données Tailscale Cloud (logs, métadonnées) sont-elles supprimées après cancel ? Tailscale annonce une suppression dans 30 jours après cancellation. Si conformité importante, demander confirmation écrite via support.

Puis-je avoir Tailscale Cloud et Headscale en parallèle pendant la bascule ? Pas sur le même appareil simultanément, mais oui en parallèle : un appareil peut basculer entre les deux selon la commande tailscale up exécutée.

Comment garder l’historique des connexions Tailscale Cloud ? Exporter via Admin Console → Logs → Export (CSV). Conserver localement dans archive chiffrée pendant 1 an pour audit.

Faut-il modifier les ACL applicatives (firewalls applicatifs) ? Non, les IPs internes Tailscale (100.64.0.0/10) restent les mêmes — seul le serveur de coordination change.

Les apps Tailscale Inc. continuent-elles de fonctionner après bascule ? Oui, identique. Aucune perte de fonctionnalité côté client (sauf SAML SSO Tailscale, à remplacer par OIDC Headscale).

Sur le même thème

Hébergement recommandé pour les lecteurs

Si vous n’avez pas encore d’hébergeur, Hostinger est celui que nous utilisons et que nous recommandons après plusieurs années d’usage.

Profiter de l’offre →

Lien d affiliation. Si vous achetez via ce lien, le blog reçoit une petite commission sans surcoût pour vous.

Étape 1 : poser le décor — pourquoi quitter Tailscale Cloud pour Headscale

Tailscale Cloud est confortable mais facture environ 6 USD/utilisateur/mois (~3 940 FCFA) au-delà du plan gratuit limité à 3 utilisateurs et 100 appareils. Pour une équipe technique de 15 personnes à Dakar, Abidjan ou Cotonou, la facture annuelle dépasse facilement 700 000 FCFA. Headscale, l’implémentation libre du serveur de coordination Tailscale, élimine cette dépense récurrente et vous redonne la souveraineté du plan de contrôle.

Le compromis : vous opérez vous-même le serveur de contrôle. Pas de magie. Comptez 1 h pour la migration initiale et 30 min/mois pour la maintenance courante (mises à jour, sauvegardes). Le coût hardware est négligeable : un VPS 2 vCPU / 2 Go RAM tient largement, soit ~5 USD/mois (~3 280 FCFA) chez Hetzner, OVH ou Scaleway.

Ce que vous gardez de Tailscale : le client officiel sur tous vos appareils (Linux, macOS, Windows, iOS, Android), le chiffrement WireGuard de bout en bout, le NAT traversal, MagicDNS. Ce que vous changez : le serveur qui distribue les clés et la topologie.

Étape 2 : provisionner le VPS et installer Headscale 0.26

Choisissez un VPS proche de vos utilisateurs principaux. Pour une équipe ouest-africaine, Hetzner Falkenstein (Allemagne) offre une latence ~80 ms vers Dakar et un excellent rapport qualité/prix. Provisionnez Debian 12 ou Ubuntu 24.04 LTS, ouvrez les ports 80, 443 et 8080 (provisoire pour les tests).

# Sur le VPS, en root
HEADSCALE_VERSION="0.26.1"
ARCH="amd64"
wget https://github.com/juanfont/headscale/releases/download/v${HEADSCALE_VERSION}/headscale_${HEADSCALE_VERSION}_linux_${ARCH}.deb
apt install ./headscale_${HEADSCALE_VERSION}_linux_${ARCH}.deb
systemctl enable --now headscale
headscale version

Résultat attendu : la commande retourne « v0.26.1 ». Si vous obtenez une erreur de service, vérifiez les logs avec journalctl -u headscale -n 50. La version 0.26 stabilise enfin l’API v1 et supporte nativement les politiques d’ACL en HuJSON.

Étape 3 : configurer Headscale avec un domaine et HTTPS Let’s Encrypt

Headscale a besoin d’un domaine public pour que les clients Tailscale s’y connectent. Créez un enregistrement A pointant headscale.votre-domaine.io vers l’IP du VPS. Editez ensuite la configuration principale.

# /etc/headscale/config.yaml (extraits clés)
server_url: https://headscale.votre-domaine.io
listen_addr: 0.0.0.0:8080
metrics_listen_addr: 127.0.0.1:9090
prefixes:
  v4: 100.64.0.0/10
  v6: fd7a:115c:a1e0::/48
dns:
  base_domain: ts.votre-domaine.io
  magic_dns: true
  nameservers:
    global:
      - 1.1.1.1
      - 9.9.9.9

Mettez Caddy ou Nginx devant Headscale pour gérer TLS automatiquement. Avec Caddy, deux lignes suffisent :

# /etc/caddy/Caddyfile
headscale.votre-domaine.io {
  reverse_proxy 127.0.0.1:8080
}

Redémarrez : systemctl restart caddy headscale. Vérifiez que https://headscale.votre-domaine.io/health renvoie un JSON avec status pass. Si Caddy refuse le certificat, vérifiez que le port 80 est bien ouvert vers Internet (Let’s Encrypt fait un challenge HTTP-01).

Étape 4 : créer les utilisateurs (anciennement namespaces)

Depuis Headscale 0.23, le terme « namespace » a été remplacé par « user ». Créez un utilisateur par personne ou par usage métier. Pour une PME de 10 personnes, vous aurez typiquement dev, ops, commercial, direction.

headscale users create dev
headscale users create ops
headscale users create commercial
headscale users list

Résultat type : tableau listant les utilisateurs créés avec leur ID. Notez ces ID, vous en aurez besoin pour les ACL. Les utilisateurs Headscale ne sont pas synchronisés avec votre IdP par défaut. Si vous voulez intégrer OIDC (Authentik, Keycloak, Entra ID), passez à l’étape 9.

Étape 5 : exporter les machines depuis Tailscale Cloud

Connectez-vous à login.tailscale.com, allez dans Machines, et listez l’ensemble des appareils enregistrés. Notez pour chacun : le nom, le tag, l’utilisateur propriétaire, l’OS, et la dernière date de connexion. Décidez quelles machines migrer (typiquement, retirez les machines obsolètes au passage).

Préparez un tableau de correspondance entre les utilisateurs Tailscale (souvent des emails) et les nouveaux utilisateurs Headscale (souvent des noms courts). Cette table sert de référence pour la phase de bascule.

Aucune commande automatique n’exporte les clés WireGuard de Tailscale Cloud : c’est by design (sécurité). Vous devrez ré-enrôler chaque appareil. Prévoyez une fenêtre où chaque utilisateur réenrôle ses propres machines, idéalement en 15 minutes par appareil.

Étape 6 : générer une pre-auth key et enrôler le premier nœud

Plutôt que d’utiliser la connexion interactive (qui ouvre un navigateur), générez une pre-auth key réutilisable. Elle simplifie l’enrôlement de masse et le scripting.

# Sur le serveur Headscale
headscale preauthkeys create --user dev --reusable --expiration 24h
# Output: une longue clé hexadecimale, copiez-la

# Sur la machine cliente (Linux par exemple)
sudo tailscale up \
  --login-server https://headscale.votre-domaine.io \
  --authkey tskey-auth-XXXXXXXXXXXXXXXX \
  --accept-routes

Résultat attendu : la commande tailscale up rend la main sans ouvrir de navigateur. Vérifiez avec tailscale status que l’IP 100.64.x.x est attribuée et que le serveur de coordination est bien votre Headscale, pas l’API Tailscale.

Étape 7 : ré-enrôler le parc machine progressivement

Migrez par vague de 3 à 5 machines pour limiter le risque. Ordre recommandé : 1) les serveurs (peu visibles côté UX), 2) les laptops dev (équipe technique tolérante), 3) les laptops bureautique en dernier. À chaque vague, vérifiez que la connectivité de bout en bout fonctionne avant de passer à la suivante.

# Désinscription propre de Tailscale Cloud
sudo tailscale logout
# Réinscription sur Headscale
sudo tailscale up --login-server https://headscale.votre-domaine.io --authkey ...
# Vérification
tailscale status
tailscale ping autre-machine-headscale

Si le ping échoue alors que la machine apparaît bien dans headscale nodes list, vérifiez les ACL (étape suivante). Par défaut, Headscale 0.26 n’autorise rien tant qu’aucune politique n’est définie : c’est sécurisant mais déroutant si on l’ignore.

Étape 8 : écrire la politique d’ACL en HuJSON

Headscale 0.26 utilise le format HuJSON (JSON avec commentaires) pour les ACL, identique à Tailscale. Créez un fichier /etc/headscale/acl.hujson et chargez-le.

{
  "groups": {
    "group:admins": ["ops"],
    "group:devs": ["dev"]
  },
  "tagOwners": {
    "tag:server": ["group:admins"]
  },
  "acls": [
    // Les admins voient tout
    { "action": "accept", "src": ["group:admins"], "dst": ["*:*"] },
    // Les devs accèdent à SSH (22) et HTTP (80,443) sur les serveurs
    { "action": "accept", "src": ["group:devs"], "dst": ["tag:server:22,80,443"] }
  ]
}

Chargez la politique : headscale policy set -f /etc/headscale/acl.hujson. Validez avec headscale policy check. Vous devriez obtenir : « Policy is valid ». Tout changement prend effet en moins de 30 secondes sur les clients connectés.

Étape 9 : brancher l’authentification OIDC (optionnel mais recommandé)

Pour une PME de plus de 10 personnes, branchez Headscale sur votre IdP via OIDC. Vous évitez de créer manuellement les utilisateurs et vous récupérez SSO + MFA. Configuration type avec Authentik (auto-hébergé sur le même VPS, gratuit).

# Dans /etc/headscale/config.yaml
oidc:
  only_start_if_oidc_is_available: true
  issuer: "https://auth.votre-domaine.io/application/o/headscale/"
  client_id: "headscale"
  client_secret_path: "/etc/headscale/oidc-secret"
  scope: ["openid", "profile", "email", "groups"]
  allowed_groups:
    - "headscale-users"

Côté Authentik, créez un Provider OAuth2/OpenID, un Application liée, et un groupe headscale-users auquel vous rattachez vos collaborateurs. Redémarrez Headscale. À la première connexion, le client Tailscale ouvrira l’écran de login Authentik au lieu de l’écran Headscale.

Étape 10 : sauvegarder, monitorer et automatiser les mises à jour

Headscale stocke tout dans une base SQLite (par défaut) à /var/lib/headscale/db.sqlite. Sauvegardez ce fichier toutes les nuits via cron, plus la configuration /etc/headscale/. Avec rclone vers un bucket Backblaze B2, comptez moins de 1 USD/mois (~656 FCFA).

# /etc/cron.daily/headscale-backup
#!/bin/bash
set -e
DATE=$(date +%Y%m%d)
DIR=/var/backups/headscale
mkdir -p $DIR
sqlite3 /var/lib/headscale/db.sqlite ".backup $DIR/db-$DATE.sqlite"
tar czf $DIR/config-$DATE.tar.gz /etc/headscale/
rclone copy $DIR b2:mes-backups/headscale/ --max-age 24h
find $DIR -mtime +30 -delete

Résultat type : un fichier db-AAAAMMJJ.sqlite et un tarball de config copiés chaque nuit dans le bucket. Testez la restauration tous les trimestres : remontez la sauvegarde sur un VPS de test et vérifiez que headscale nodes list retourne bien votre parc.

Activez les métriques Prometheus exposées sur 127.0.0.1:9090/metrics et branchez Grafana avec un dashboard simple : nombre de nœuds connectés, taille de la base, latence de l’API. Vous repérez ainsi en 30 secondes une dégradation. Pour étoffer le tableau sur le réseau privé, lisez notre tutoriel WireGuard pour PME et le guide Authentik SSO.

Partager