ITSkillsCenter
Cybersécurité

ACL Headscale pour équipe distribuée : sécuriser un mesh Dakar/Abidjan/Casablanca

5 min de lecture

📍 Article principal du cluster : Headscale 2026 : guide complet.

Sans ACL, votre Headscale est un réseau plat où chaque appareil peut joindre chaque autre sur tous les ports. Pour une équipe de 30 personnes répartie entre Dakar, Abidjan et Casablanca, c’est un anti-pattern de sécurité majeur. Ce tutoriel détaille la mise en place de politiques HuJSON robustes : utilisateurs, groupes, tags, autorisations granulaires, exemples copier-coller.

Prérequis

  • Headscale en production (voir tutoriel d’installation).
  • Au moins 5 appareils enregistrés.
  • Notion de RBAC (Role-Based Access Control).
  • Niveau attendu : intermédiaire/avancé.
  • Temps estimé : 2 à 3 heures.

Étape 1 — Comprendre la structure HuJSON

Une politique Headscale comporte cinq sections principales :

  • groups : groupes d’utilisateurs (équivalents groupes RBAC).
  • tagOwners : qui peut assigner quels tags.
  • autoApprovers : routes et exit nodes pré-approuvés.
  • acls : règles d’autorisation effectives.
  • ssh : règles spécifiques SSH (Tailscale SSH).

Étape 2 — Définir les utilisateurs et groupes

Dans /etc/headscale/policy.hujson :

{
  "groups": {
    "group:admins": ["amadou@votre-entreprise.com"],
    "group:devs": ["amadou@...", "fatou@...", "ousmane@..."],
    "group:marketing": ["aicha@...", "moussa@..."],
    "group:finance": ["khadija@..."],
    "group:freelances": ["consultant1@external.com"]
  },
  "tagOwners": {
    "tag:server-prod": ["group:admins"],
    "tag:server-staging": ["group:devs"],
    "tag:database-prod": ["group:admins"],
    "tag:office-dakar": ["group:admins"]
  }
}

Étape 3 — Définir les ACL principales

"acls": [
  // Admins ont accès total
  {
    "action": "accept",
    "src": ["group:admins"],
    "dst": ["*:*"]
  },
  // Développeurs : SSH sur staging et prod, accès apps internes
  {
    "action": "accept",
    "src": ["group:devs"],
    "dst": ["tag:server-staging:22,80,443,5432,6379"]
  },
  {
    "action": "accept",
    "src": ["group:devs"],
    "dst": ["tag:server-prod:443"]
  },
  // Marketing : accès à Vaultwarden, Outline, Plausible uniquement
  {
    "action": "accept",
    "src": ["group:marketing"],
    "dst": ["100.64.0.10:443", "100.64.0.11:443", "100.64.0.12:443"]
  },
  // Finance : accès ERP uniquement
  {
    "action": "accept",
    "src": ["group:finance"],
    "dst": ["100.64.0.20:443"]
  },
  // Freelances : staging seulement, expire automatiquement
  {
    "action": "accept",
    "src": ["group:freelances"],
    "dst": ["tag:server-staging:80,443"]
  },
  // Subnet routers : autorisation pour LAN bureau Dakar
  {
    "action": "accept",
    "src": ["group:devs", "group:admins"],
    "dst": ["192.168.10.0/24:*"]
  }
]

Étape 4 — SSH avec Tailscale SSH

Tailscale SSH (et Headscale SSH) permet de SSH sans clé publique, l’authentification étant gérée par le mesh :

"ssh": [
  // Admins peuvent SSH partout en root
  {
    "action": "accept",
    "src": ["group:admins"],
    "dst": ["tag:server-prod", "tag:server-staging"],
    "users": ["root", "ubuntu", "debian"]
  },
  // Devs peuvent SSH sur staging avec leur propre user
  {
    "action": "accept",
    "src": ["group:devs"],
    "dst": ["tag:server-staging"],
    "users": ["autogroup:nonroot"]
  },
  // Devs peuvent SSH sur prod uniquement avec check 2FA (futur)
  {
    "action": "check",
    "src": ["group:devs"],
    "dst": ["tag:server-prod"],
    "users": ["autogroup:nonroot"],
    "checkPeriod": "1h"
  }
]

Étape 5 — Tester la politique avant application

headscale policy check -f /etc/headscale/policy.hujson
# Retourne : Policy is valid

headscale policy set -f /etc/headscale/policy.hujson
# Retourne : Policy applied successfully

Étape 6 — Assigner les tags aux serveurs

Sur le serveur Postgres production :

tailscale up --login-server=https://headscale.votre-entreprise.com \
  --auth-key=PREAUTH \
  --advertise-tags=tag:server-prod,tag:database-prod

Côté Headscale, approuver l’attribution :

headscale nodes tag -i ID_DU_NODE -t tag:server-prod,tag:database-prod

Étape 7 — Audit et conformité

Toutes les actions Headscale sont loggées. Pour un audit mensuel :

journalctl -u headscale --since "1 month ago" | grep -i "policy\|tag\|register"

Pour une PME soumise à RGPD ou ARTCI, exporter ces logs vers Loki + Grafana avec rétention 1 an minimum.

Cas spécial : équipe multi-sites

Pour une équipe répartie sur 3 villes (Dakar, Abidjan, Casablanca), définir des tags géographiques permet d’écrire des règles type « les devs Dakar peuvent SSH les serveurs Dakar, idem Abidjan » :

"groups": {
  "group:devs-dakar": [...],
  "group:devs-abidjan": [...],
  "group:devs-casa": [...]
},
"tagOwners": {
  "tag:server-dakar": ["group:devs-dakar"],
  "tag:server-abidjan": ["group:devs-abidjan"],
  "tag:server-casa": ["group:devs-casa"]
},
"acls": [
  {"action": "accept", "src": ["group:devs-dakar"], "dst": ["tag:server-dakar:*"]},
  {"action": "accept", "src": ["group:devs-abidjan"], "dst": ["tag:server-abidjan:*"]},
  // Sauf admins, qui ont tout
  {"action": "accept", "src": ["group:admins"], "dst": ["*:*"]}
]

Erreurs fréquentes

Erreur Cause Solution
Politique vide bloque tout Pas de règle accept par défaut Ajouter règle {"action":"accept","src":["*"],"dst":["*:*"]} au début pour tester
Erreur HuJSON syntaxe Virgule manquante headscale policy check indique la ligne
Tag refusé tagOwners absent Ajouter le tag dans tagOwners
Freelance toujours connecté Compte non supprimé headscale users destroy nom
SSH par tag refusé tag non assigné côté server Vérifier tailscale status sur le serveur
Updates ne propagent pas Cache client Forcer reconnect : tailscale set --auto-update

Adaptation au contexte ouest-africain

Trois ajustements concrets. Freelances et stagiaires : très fréquents en Afrique, créer un groupe dédié group:temporaires avec ACL strictes (staging only, ports limités, SSH read-only). Suppression auto possible via cron : headscale users destroy temporaire-X après 30 jours d’inactivité. Sites distribués : pour un cabinet d’avocats à Casablanca/Tanger/Marrakech, tagger chaque site permet d’isoler les ressources locales. Conformité ARTCI : exiger les ACL en lecture/écriture sur les serveurs production uniquement pour les comptes traçables (pas de compte partagé).

Tutoriels frères

FAQ

Combien de règles ACL Headscale supporte-t-il ? Plusieurs centaines sans impact perceptible. Les tests Tailscale ont validé jusqu’à 10 000 règles.

Comment auditer qui a accédé à quoi ? Logs Headscale + logs SSH côté serveurs (auditd ou rsyslog). Croiser les deux donne une trace complète.

Politique HuJSON Tailscale Cloud compatible ? 95% oui. Quelques différences sur SSH check mode et certaines features Enterprise non supportées.

Que faire en cas d’erreur de politique en prod ? Garder une politique « safe rollback » testée dans Git. headscale policy set -f safe.hujson rétablit l’ancien état en 5 secondes.

Comment imposer un check 2FA pour SSH prod ? Mode "action": "check" avec checkPeriod. À la première session SSH, l’utilisateur doit confirmer via app mobile ou clé matérielle.

Pour aller plus loin

Besoin d'un site web ?

Confiez-nous la Création de Votre Site Web

Site vitrine, e-commerce ou application web — nous transformons votre vision en réalité digitale. Accompagnement personnalisé de A à Z.

À partir de 250.000 FCFA
Parlons de Votre Projet
Publicité