SSD Nodes Learn Hosting plans →
Guides Matt ConnorPar Matt Connor · Mis à jour le 2026-11-01

Installer Headscale pour auto-héberger votre Tailscale

Déployez votre serveur de contrôle Tailscale sur un VPS : installez headscale avec le paquet .deb officiel, renseignez server_url et joignez votre premier nœud.

Verified Every command ran end-to-end on a fresh Ubuntu 24.04 server, July 30, 2026.

Ce qu’est headscale

Headscale est une implémentation auto-hébergée du serveur de contrôle Tailscale. La machine qui coordonne votre réseau privé est donc un VPS qui vous appartient. Il s’agit d’un projet communautaire, qui n’est pas géré par Tailscale Inc. Chaque machine exécute toujours le client officiel tailscale, configuré pour utiliser votre serveur avec un seul flag : --login-server.

Le serveur de contrôle connaît les machines qui appartiennent au réseau. Il attribue à chaque nœud une adresse dans 100.64.0.0/10, distribue les clés publiques et indique aux nœuds où se trouver les uns les autres. Les tunnels restent des tunnels WireGuard établis directement entre les nœuds. Le trafic entre deux de vos machines ne passe pas par le serveur headscale, sauf lorsqu’un chemin direct ne peut pas être établi et que les nœuds utilisent un relay. Gérer vous-même ce rôle de coordination change l’entité qui l’assume, mais pas ce qu’elle peut faire. Il est donc utile de comprendre ce qu’un serveur de contrôle peut et ne peut pas atteindre dans ce modèle avant de considérer ce changement comme un gain de sécurité à lui seul.

Headscale gère un tailnet (un réseau Tailscale) par instance. Le projet le présente comme adapté à un usage personnel ou à une petite organisation. Avec trois ou quatre machines, un VPN WireGuard classique sur un VPS que vous possédez demande moins de logiciels à administrer et offre moins de possibilités de panne. Headscale devient intéressant lorsque vous ne voulez plus écrire manuellement un bloc [Peer] pour chaque nouvel ordinateur portable. Le coût pousse souvent à étudier cette solution en premier. Il est donc utile de lire ce que couvre réellement l’offre gratuite hébergée avant de gérer un serveur, car quelques machines personnelles tiennent généralement dans ses limites. Si vous avez déjà dépassé ce plafond, comparez le coût avec le prix des offres payantes par utilisateur et par ressource marquée, car le nombre d’appareils des utilisateurs est illimité, tandis que les ressources marquées ont des quotas et des frais distincts. Si vous voulez un control plane auto-hébergé, mais préférez disposer de votre propre client et d’une interface web pour gérer les peers plutôt qu’un remplacement direct de celui de Tailscale, NetBird sur un VPS unique est l’alternative à étudier. Les deux solutions transportent votre trafic avec WireGuard. Le choix dépend donc de la manière dont vous écrivez les règles d’accès et du comportement des relais. Il est utile de comparer NetBird et Tailscale sur ces points avant d’installer l’une ou l’autre solution. Pour une comparaison plus générale des deux modèles, consultez les différences entre WireGuard et Tailscale.

Ce qu’il vous faut avant l’installation

  • Un VPS sous Ubuntu 24.04 avec une adresse IPv4 publique et un accès sudo. Si le serveur est neuf, commencez par suivre les dix premières minutes sur un nouveau VPS.
  • Un enregistrement DNS de type A pointant vers cette adresse. Ce guide utilise headscale.example.com.
  • Un deuxième domaine ou sous-domaine pour MagicDNS. Ce guide utilise tailnet.example.net. Il ne doit pas être identique au domaine indiqué dans server_url.
  • Une machine cliente à joindre, sous Linux, macOS, Windows, Android ou iOS. Headscale 0.29.6 nécessite la version 1.80.0 ou une version ultérieure du client Tailscale.

Installer headscale depuis le paquet .deb officiel

Le projet publie des paquets .deb sur sa page des releases GitHub. Au 27 octobre 2026, la dernière version stable est 0.29.6, publiée le 24 octobre 2026. Vérifiez d’abord votre architecture, car le nom du fichier l’indique.

sudo apt update
sudo apt install -y wget
dpkg --print-architecture

Cette commande affiche amd64 sur un VPS x86 standard et arm64 sur une offre de type Ampere ou Graviton. Placez la réponse dans la variable ci-dessous.

HEADSCALE_VERSION="0.29.6"
HEADSCALE_ARCH="amd64"
wget --output-document=headscale.deb \\
  "https://github.com/juanfont/headscale/releases/download/v${HEADSCALE_VERSION}/headscale_${HEADSCALE_VERSION}_linux_${HEADSCALE_ARCH}.deb"
sudo apt install -y ./headscale.deb
headscale version

Le ./ placé devant le nom du fichier est requis. Sans lui, apt recherche dans vos dépôts un paquet appelé headscale.deb et échoue.

Le paquet crée un utilisateur système headscale, écrit une configuration /etc/headscale/config.yaml par défaut, installe une unité systemd, puis démarre le service. headscale est donc déjà en cours d’exécution lorsque apt se termine, et sudo systemctl is-active headscale affiche active. Lors d’une nouvelle installation, le paquet n’active toutefois pas l’unité. Le service ne redémarrera donc pas après un reboot tant que vous ne l’aurez pas activé, ce que fait l’étape de redémarrage ci-dessous. Il fonctionne également avec la configuration fournie, qui le lie à http://127.0.0.1:8080 via server_url, une adresse qu’aucun de vos clients ne peut atteindre. Rien n’est encore exposé, car le listen_addr fourni écoute également sur la loopback, mais n’ajoutez aucun client avant d’avoir défini server_url et redémarré le service, ce que font les deux étapes suivantes.

Configurez server_url avant l’ajout du moindre client

Modifiez /etc/headscale/config.yaml avec sudo nano /etc/headscale/config.yaml, ou appliquez les trois mêmes changements avec sed. Conservez une copie de l’original, car le fichier est long et contient de nombreux commentaires. C’est la meilleure référence dont vous disposez pour les autres paramètres.

sudo cp /etc/headscale/config.yaml /etc/headscale/config.yaml.orig
sudo sed -i 's|^server_url:.*|server_url: https://headscale.example.com|' /etc/headscale/config.yaml
sudo sed -i 's|^listen_addr:.*|listen_addr: 127.0.0.1:8080|' /etc/headscale/config.yaml
sudo sed -i 's|^  base_domain:.*|  base_domain: tailnet.example.net|' /etc/headscale/config.yaml
sudo grep -E '^(server_url|listen_addr):|^  base_domain:' /etc/headscale/config.yaml

server_url correspond à l’adresse publique utilisée par headscale pour générer les URL d’inscription. Les clients utilisent l’adresse de contrôle configurée avec --login-server. Utilisez donc le même nom public avec https:// aux deux endroits, et jamais 127.0.0.1. La documentation de headscale indique que HTTP simple, ou HTTPS sur un port différent de 443, est possible. Elle recommande toutefois fortement HTTPS sur le port 443 en production. Le reste de ce guide part de cette hypothèse.

listen_addr indique l’adresse sur laquelle le processus écoute. Laissez-la sur la loopback. Un reverse proxy installé sur le même serveur termine le TLS (transport layer security) et lui transmet les requêtes. Aucun accès externe au port 8080 n’est donc nécessaire.

base_domain correspond au suffixe MagicDNS, c’est-à-dire au domaine sous lequel vos nœuds obtiennent leur nom. Il doit s’agir d’un nom de domaine pleinement qualifié, sans point final. Il doit aussi être différent du domaine indiqué dans server_url, car les deux espaces de noms entreraient sinon en conflit.

Ne modifiez pas la section de la base de données. La valeur par défaut utilise SQLite à l’emplacement /var/lib/headscale/db.sqlite, dans un répertoire créé et géré par le paquet. SQLite suffit pour un tailnet de cette taille.

Redémarrer headscale et vérifier qu’il fonctionne

sudo systemctl restart headscale
sudo systemctl enable headscale
sudo systemctl is-active headscale
sudo systemctl is-enabled headscale
curl -sS -o /dev/null -w '%{http_code}\\n' http://127.0.0.1:8080/health

is-active affiche active, is-enabled affiche enabled et curl affiche 200. Le redémarrage charge vos modifications. Headscale lit sa configuration une seule fois, au démarrage. Le processus lancé par le paquet continue donc d’utiliser le server_url fourni tant que vous ne le redémarrez pas. sudo systemctl enable --now headscale ne suffit pas : le service fonctionne déjà, donc la commande --now ne change rien et l’ancienne valeur reste active. Le démarrage automatique est géré par enable, mais il n’est pas configuré automatiquement : lors d’une nouvelle installation, le paquet démarre le service sans l’activer. Exécutez donc sudo systemctl enable headscale une fois, comme indiqué plus haut.

Si is-active affiche autre chose que active, ou si curl n’affiche pas 200, consultez le journal avec sudo journalctl -u headscale -n 50 --no-pager. À ce stade, l’échec vient presque toujours du fichier de configuration. Headscale analyse tout le fichier avant d’ouvrir un socket. Une indentation incorrecte ou un paramètre obligatoire invalide arrête donc le processus avant toute écoute. Corrigez le fichier, puis exécutez sudo systemctl restart headscale. Toute modification ultérieure de la configuration nécessite le même redémarrage. Les clients se reconnectent ensuite automatiquement. Si les unités systemd sont nouvelles pour vous, exécuter vos propres services et timers avec systemd présente les commandes utilisées ici.

Vérifiez les fichiers d’état depuis le shell :

stat -c '%U %n' /var/lib/headscale/db.sqlite /var/lib/headscale/noise_private.key

Les deux lignes commencent par headscale, l’utilisateur non privilégié créé par le paquet. noise_private.key est l’identité du serveur auprès de ses clients. Conservez-le. Si vous le supprimez, headscale en génère un nouveau et les clients doivent récupérer la nouvelle clé du serveur avant de se reconnecter. Les enregistrements existants restent dans la base de données.

Configurer TLS devant headscale

Les clients doivent accéder à server_url via HTTPS. Caddy est la solution la plus simple, car il demande et renouvelle lui-même le certificat.

sudo apt install -y caddy

Remplacez /etc/caddy/Caddyfile par le bloc fourni dans la documentation de headscale :

headscale.example.com {
    reverse_proxy 127.0.0.1:8080 {
        header_up True-Client-IP {remote_host}
        header_up X-Real-IP {remote_host}
    }
}
sudo caddy validate --adapter caddyfile --config /etc/caddy/Caddyfile
sudo systemctl restart caddy
sudo systemctl is-active caddy

validate affiche adapted config to JSON lorsque le fichier est correctement analysé. Un avertissement indiquant que le fichier n’est pas formaté est sans conséquence. Depuis votre ordinateur portable, curl -sS -o /dev/null -w '%{http_code}\\n' https://headscale.example.com/health doit également afficher 200. Ce contrôle unique confirme que le DNS, le pare-feu, le certificat et le proxy fonctionnent correctement ensemble.

Voici le détail du proxy qui peut faire perdre une soirée. La connexion de contrôle Tailscale est une mise à niveau HTTP. Elle est initialisée avec une requête POST, et la valeur de l’en-tête Upgrade est tailscale-control-protocol. Caddy transmet cela sans configuration supplémentaire. nginx ne le fait pas. Un front end nginx doit donc transmettre explicitement les en-têtes Upgrade et Connection. La documentation de headscale utilise une map pour la mise à niveau :

map $http_upgrade $connection_upgrade {
    default keep-alive;
    ''      close;
}

server {
    listen 443 ssl;
    server_name headscale.example.com;
    location / {
        proxy_http_version 1.1;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection $connection_upgrade;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_buffering off;
        proxy_pass http://127.0.0.1:8080;
    }
}

Si vous omettez ces lignes, les requêtes ordinaires continuent de fonctionner. C’est pourquoi /health renvoie 200 et que tout semble correct, alors que la connexion de contrôle ne s’établit jamais : les nouveaux nœuds ne peuvent pas s’enregistrer, et les nœuds existants ne peuvent pas se reconnecter ni signaler qu’ils sont en ligne. Si vous choisissez nginx, Certbot sur Ubuntu 24.04 avec nginx couvre la partie certificats.

Ports à ouvrir dans UFW

sudo ufw allow OpenSSH
sudo ufw allow 80/tcp
sudo ufw allow 443/tcp
sudo ufw enable
sudo ufw status verbose

Le port 443 transporte la connexion de contrôle de chaque client vers headscale. Si vous activez ensuite le relais DERP intégré, il a également besoin du port 3478/udp, présenté ci-dessous. Le port 80 sert au challenge HTTP de l’ACME (automatic certificate management environment) et à la redirection vers HTTPS. Caddy peut obtenir un certificat avec le port 80 fermé, car il peut utiliser le challenge TLS-ALPN sur le port 443. Toutefois, avec le port 80 ouvert, les deux challenges sont disponibles et les requêtes http:// en clair sont redirigées.

Le port 8080 reste fermé. listen_addr est 127.0.0.1:8080, le proxy communique donc avec headscale via l’interface loopback et aucune règle de pare-feu n’est nécessaire. Ouvrir le port 8080 dans UFW n’exposerait rien, car aucun service n’y est en écoute depuis l’extérieur. Cela ne présente donc aucun intérêt. Gardez à l’esprit que la plupart des fournisseurs exécutent un second pare-feu dans leur panneau de contrôle, séparé d’UFW. Un port peut donc être ouvert sur le serveur tout en restant fermé en périphérie. Principes du pare-feu UFW sur un VPS présente plus en détail la syntaxe des règles.

Créer un utilisateur et une clé de préauthentification

sudo headscale users create alice
sudo headscale users list

La commande headscale est un client. Elle communique avec le daemon en cours d’exécution via le socket Unix situé à /var/run/headscale/headscale.sock. Ce socket est en mode 0770 et appartient au groupe headscale. Cela entraîne deux conséquences. La commande échoue si le service est arrêté, ce qui explique aussi pourquoi l’ordre des étapes de ce guide est important. Elle nécessite également sudo, sauf si vous ajoutez votre propre compte au groupe headscale.

users list affiche un identifiant à côté de chaque nom. Vous avez besoin de ce numéro, car la commande de création de clé accepte un ID utilisateur numérique, pas un nom.

sudo headscale preauthkeys create --user 1 --expiration 24h

La clé n’est affichée qu’une seule fois. Copiez-la maintenant. Une clé de préauthentification est utilisable une seule fois et reste valide pendant une heure, sauf indication contraire. Il est donc utile de définir --expiration 24h pendant les tests. Ajoutez --reusable pour créer une clé permettant l’inscription de plusieurs machines. Traitez cette clé comme un mot de passe, car toute personne qui la détient peut rejoindre votre réseau.

Connecter votre premier client avec --login-server

Sur la machine que vous voulez joindre :

curl -fsSL https://tailscale.com/install.sh | sh
sudo tailscale up --login-server https://headscale.example.com --auth-key 'hskey-auth-PASTE-YOUR-KEY-HERE'
tailscale status
tailscale ip -4

tailscale ip -4 affiche l’adresse attribuée par headscale, par exemple 100.64.0.1. De retour sur le serveur, sudo headscale nodes list affiche le nœud avec son ID, son utilisateur et son état en ligne.

Utilisez l’adresse HTTPS publique de server_url pour --login-server. Le client supprime les barres obliques finales de l’URL de contrôle ; aucune comparaison exacte de chaînes ne vous oblige donc à en omettre une.

Une machine précédemment connectée au service hébergé de Tailscale conserve cette connexion. Exécutez d’abord sudo tailscale logout sur cette machine, puis tailscale up avec --login-server.

Si vous omettez --auth-key, le client affiche une URL. Ouvrez-la : la page affiche l’identifiant de cette tentative d’enregistrement, que vous approuvez sur le serveur :

sudo headscale auth register --user alice --auth-id PASTE-THE-ID-FROM-THE-PAGE

Cette méthode est plus pratique pour votre propre portable. Les clés de préauthentification conviennent mieux aux opérations automatisées, car personne n’a besoin de surveiller la procédure. Une fois que le VPS est lui-même un nœud, il peut également transporter le trafic Internet de vos autres machines. Il s’agit de la configuration du nœud de sortie, à une différence près : vous approuvez la route annoncée sur le serveur avec la commande headscale, et non dans une console d’administration hébergée. Si vous voulez accéder à un réseau privé situé derrière ce VPS, plutôt que disposer d’une sortie vers Internet, la même étape d’approbation permet d’annoncer ce sous-réseau au reste de votre tailnet. Publier une seule application depuis un nœud, au lieu d’y faire transiter des réseaux entiers, est une autre tâche. serve et funnel sont les deux méthodes permettant de le faire, mais toutes deux s’appuient sur les certificats et le mécanisme d’ingress de Tailscale. Considérez-les donc comme des fonctionnalités d’un tailnet hébergé, et non comme des fonctions fournies par headscale.

DERP et relais du trafic lorsqu’un chemin direct échoue

DERP (designated encrypted relay for packets) est le chemin de secours. Lorsque deux nœuds ne peuvent pas établir de connexion WireGuard directe, généralement parce qu’ils se trouvent tous les deux derrière un NAT strict (network address translation), ils envoient plutôt les paquets via un relais. Le relais ne possède aucune clé et ne peut donc pas lire votre trafic. Il voit toutefois quels nœuds communiquent et quelle quantité de données circule.

Il faut bien comprendre le fonctionnement de la configuration par défaut. Headscale est livré avec une configuration qui pointe vers https://controlplane.tailscale.com/derpmap/default, avec auto_update_enabled: true et update_frequency: 3h. Votre control plane vous appartient donc, tandis que vos relais sont ceux de Tailscale. Pour la plupart des utilisateurs, c’est un compromis acceptable. Si ce n’est pas votre cas, exécutez votre propre relais.

Pour exécuter votre propre relais, définissez enabled: true sous derp.server dans config.yaml, remplacez ipv4: 198.51.100.1 et ipv6: 2001:db8::1 fournis par les adresses publiques de votre relais, ou supprimez ces deux paramètres pour utiliser le DNS. Redémarrez ensuite headscale et ouvrez le port STUN (session traversal utilities for NAT) avec sudo ufw allow 3478/udp. Ces paramètres d’adresse prennent le pas sur le DNS. Si vous laissez l’un des espaces réservés en place, les clients essaieront de joindre une adresse inaccessible. Le fichier de configuration indique clairement cette exigence : le server_url doit utiliser https, car DERP nécessite TLS. Vider la liste derp.urls supprime les relais de Tailscale de la map. Conservez un relais embedded ou personnalisé fonctionnel avant de le faire. Headscale refuse de démarrer avec une map de relais vide. Une map contenant uniquement un relais inaccessible empêche les nœuds qui ne peuvent pas se connecter directement de communiquer.

Depuis un client, tailscale netcheck affiche la latence vers chaque région de relais connue, et tailscale status affiche direct avec une adresse ou relay avec un code de région pour les connexions actives entre pairs. Un pair bloqué sur relay nécessite une vérification de son chemin direct, notamment du NAT et des règles de firewall. Un pair qui est direct mais reste lent relève d’un autre problème, et la réponse habituelle concerne alors le MTU plutôt que le tunnel lui-même.

Pourquoi un nœud apparaît-il comme hors ligne ?

Le proxy bloque l’upgrade. Sa signature est la suivante : /health renvoie 200, tandis que les nouvelles inscriptions échouent ou que les nœuds existants ne peuvent pas se reconnecter. La connexion de contrôle est un POST qui transporte Upgrade: tailscale-control-protocol. Un proxy qui ne le transmet pas bloque donc l’inscription et le canal qui signale l’état des nœuds. Comparez votre configuration nginx avec les lignes d’upgrade ci-dessus, ou utilisez Caddy pour écarter le proxy comme cause.

L’adresse de contrôle publique a changé. Les nœuds continuent de contacter l’adresse configurée avec --login-server. Modifier server_url ne met pas à jour ce paramètre côté client. Si l’ancienne adresse n’atteint plus votre serveur, exécutez sudo tailscale up --login-server https://headscale.example.com --force-reauth sur chaque nœud.

Le client ne fonctionne pas. Sur le nœud, sudo systemctl is-active tailscaled et sudo journalctl -u tailscaled -n 50 --no-pager. Un client qui ne peut pas résoudre votre domaine ou l’atteindre journalise ses nouvelles tentatives à cet endroit.

La clé a expiré. Ce point est traité dans la section suivante.

Pour surveiller le serveur pendant vos tests, exécutez sudo journalctl -u headscale -f sur le VPS et redémarrez tailscaled sur le client. Consultez également le journal du client : le fait qu’une requête atteigne headscale ne garantit pas qu’une ligne soit écrite avec le niveau de journalisation par défaut. L’absence de messages dans le journal du serveur ne suffit donc pas à prouver un problème de DNS, de firewall ou de proxy.

Expiration des clés et nœud qui cesse de fonctionner plusieurs semaines plus tard

Deux types d’expiration distincts existent. Les confondre fait perdre du temps.

Les clés de pré-authentification expirent rapidement, par conception. La valeur par défaut est d’une heure et d’une utilisation. Si tailscale up refuse la clé, générez-en une nouvelle sur le serveur au lieu de modifier quoi que ce soit sur le client.

Les clés de nœud constituent la partie à longue durée de vie. La section node de config.yaml définit expiry: 0, et 0 signifie qu’aucune expiration par défaut n’est appliquée. Une expiration explicite définie sur le client ou une expiration OIDC peut toutefois s’appliquer. Les nœuds avec un tag ne sont pas concernés par l’expiration automatique, mais un administrateur peut les faire expirer explicitement. Définissez expiry: 180d si vous voulez une valeur par défaut de 180 jours pour les enregistrements sans tag. Une expiration demandée par le client est prioritaire et OIDC peut remplacer la valeur par défaut. Modifier ce paramètre ne change pas rétroactivement les enregistrements existants. Un nœud avec une expiration doit se réauthentifier avant cette échéance avec sudo tailscale up --login-server https://headscale.example.com --force-reauth. Un serveur headless sur lequel personne ne se réauthentifie disparaîtra du réseau lorsque son enregistrement expirera.

Faites-le manuellement lorsqu’une personne perd un ordinateur portable. sudo headscale nodes list vous donne l’ID, puis sudo headscale nodes expire -i 3 déconnecte ce nœud et sudo headscale nodes delete -i 3 le supprime entièrement du réseau.

Sauvegardes et mises à niveau

/var/lib/headscale et /etc/headscale constituent l’ensemble du serveur. Arrêtez le service avant de les copier, car SQLite peut encore effectuer des écritures et une base de données copiée pendant son utilisation peut être incohérente.

sudo systemctl stop headscale
sudo tar czf /root/headscale-state.tgz -C /var/lib headscale
sudo tar czf /root/headscale-config.tgz -C /etc headscale
sudo systemctl start headscale
sudo chmod 600 /root/headscale-*.tgz

Copiez les deux fichiers hors du serveur. Ils contiennent les clés privées et toutes les informations d’enregistrement. Ils nécessitent donc le même niveau de protection que le serveur lui-même. La section sauvegardes restic depuis un VPS explique comment automatiser cette opération et chiffrer les sauvegardes.

Les mises à niveau reprennent les étapes de l’installation : téléchargez le nouveau .deb et sudo apt install ./headscale.deb, redémarrez, puis exécutez de nouveau les vérifications is-active et /health. Depuis la version 0.29, le chemin de mise à niveau est strict. Le saut d’une version mineure est bloqué, tout comme le retour à une version mineure plus ancienne. Passez à la version mineure suivante une étape à la fois, effectuez une sauvegarde avant chaque étape et lisez d’abord les notes de version correspondantes, car cette version a également modifié le comportement de la stratégie ACL et déplacé plusieurs clés de configuration. La version 0.29.6 inclut aussi des mises à jour de sécurité concernant la validation des certificats et les dépendances. Les installations existantes en 0.29 doivent donc appliquer cette version corrective.

FAQ

headscale s’exécute-t-il déjà juste après l’installation du fichier .deb ?

Oui. Le paquet démarre le service dès son installation, avec le /etc/headscale/config.yaml fourni, qui écoute uniquement sur loopback et définit server_url sur http://127.0.0.1:8080. Sur une installation neuve, il n’active pas le service ; celui-ci ne démarrera donc pas au boot tant que vous n’aurez pas exécuté sudo systemctl enable headscale. L’adresse fournie est inutilisable par les clients. Modifiez donc server_url, listen_addr et base_domain, puis exécutez sudo systemctl restart headscale et vérifiez avec sudo systemctl is-active headscale. La valeur doit être restart : headscale ne lit le fichier qu’à son démarrage, et enable --now sur un service déjà démarré l’active au boot sans le redémarrer. Les anciennes valeurs restent donc actives. Si le service échoue après le redémarrage, sudo journalctl -u headscale -n 50 --no-pager indique le problème. À ce stade, il s’agit presque toujours d’une erreur YAML, car headscale analyse l’intégralité du fichier avant d’écouter sur un port.

Dois-je toujours installer le client Tailscale standard sur mes machines ?

Oui. Headscale remplace uniquement le serveur de contrôle. Chaque nœud exécute le client officiel de Tailscale, et vous l’orientez vers votre serveur avec sudo tailscale up --login-server https://headscale.example.com. Ce flag existe dans le client standard. Aucun correctif ni recompilation n’est donc nécessaire.

Mon trafic passe-t-il par le serveur headscale ?

En général, non. Headscale coordonne le réseau et distribue les clés et les adresses, tandis que le chemin des données utilise directement WireGuard entre vos nœuds. Le trafic ne fait un détour que lorsque deux nœuds ne peuvent pas communiquer directement et utilisent un relais DERP. Avec la configuration fournie, ces relais sont ceux, publics, de Tailscale. Exécutez tailscale status sur un nœud pour vérifier si un peer donné est direct ou utilise un relay.

Pourquoi mon nœud reste-t-il hors ligne après son enregistrement ?

Un nœud qui apparaît dans headscale nodes list mais ne passe jamais en ligne nécessite une vérification de sa connexion de contrôle, y compris du reverse proxy. Cette connexion est une mise à niveau HTTP envoyée avec une requête POST et l’en-tête Upgrade: tailscale-control-protocol. nginx la supprime si vous ne transmettez pas explicitement les en-têtes Upgrade et Connection avec proxy_set_header. La configuration ci-dessus le fait dans son bloc map $http_upgrade $connection_upgrade. La suppression de ces en-têtes empêche également l’enregistrement des nouveaux nœuds. Caddy les transmet sans configuration supplémentaire. Il permet donc de vérifier rapidement si le proxy est en cause.

Ai-je besoin d’un nom de domaine et de TLS pour headscale ?

Pour cette configuration, oui : utilisez un nom de domaine et HTTPS. Les certificats peuvent également couvrir des adresses IP brutes, mais le fichier de configuration indique que DERP nécessite TLS. Un domaine associé à Caddy se configure en environ cinq minutes et fournit un endpoint HTTPS qui se renouvelle automatiquement. HTTP simple est possible, mais la documentation de headscale recommande fortement HTTPS sur le port 443 en production. Elle précise également que le client Tailscale suppose HTTPS sur le port 443 dans certaines situations.

Cet article vous a-t-il été utile ?