SSD Nodes Learn Hosting plans →
Gidsen Matt ConnorDoor Matt Connor · Bijgewerkt 2026-11-01

Headscale zelf hosten: eigen Tailscale server opzetten

Beheer uw eigen Tailscale control server op een VPS. Installeer de officiële .deb, configureer de server_url en verbind uw eerste node met de --login-server vlag.

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

Wat headscale is

Headscale is een zelfgehoste implementatie van de Tailscale-control server, waardoor de machine die uw privénetwerk coördineert een VPS is die u zelf beheert. Het is een communityproject en wordt niet beheerd door Tailscale Inc. Elke machine draait nog steeds de officiële tailscale-client, die met één vlag, --login-server, naar uw server wordt verwezen.

De control server is het onderdeel dat weet wie er bij het netwerk hoort. Deze geeft elk knooppunt een adres uit 100.64.0.0/10, distribueert publieke sleutels en vertelt knooppunten waar ze elkaar kunnen vinden. De tunnels blijven WireGuard, opgebouwd van knooppunt naar knooppunt. Verkeer tussen twee van uw machines loopt niet via de headscale-server, tenzij er geen direct pad kan worden opgebouwd en de knooppunten terugvallen op een relay. Het zelf uitvoeren van deze coördinerende rol verandert wie deze beheert, in plaats van wat deze kan doen. Het is daarom de moeite waard om te begrijpen wat een control server in dit model wel en niet kan bereiken voordat u deze stap louter als een beveiligingswinst beschouwt.

Headscale biedt per instantie één tailnet (één Tailscale-netwerk). Het project beschrijft dit als geschikt voor persoonlijk gebruik of een kleine organisatie. Met drie of vier machines vereist een eenvoudige WireGuard-VPN op een VPS die u zelf beheert minder software om te beheren en kan er minder misgaan. Headscale wordt interessant wanneer u niet langer voor elke nieuwe laptop handmatig een [Peer]-blok wilt schrijven. Kosten zijn vaak de reden waarom mensen dit eerst onderzoeken. Lees daarom wat het gratis gehoste plan daadwerkelijk dekt voordat u een server gaat beheren. Een handvol persoonlijke machines past daar meestal binnen. Als u die limiet al hebt overschreden, vergelijk dan de kosten met wat de betaalde plannen per gebruiker en per getagde resource kosten. Gebruikersapparaten zijn onbeperkt, terwijl voor getagde resources afzonderlijke limieten en kosten gelden. Als u een zelfgehoste control plane wilt, maar liever uw eigen client en een webinterface voor het beheer van peers gebruikt dan een directe vervanging van Tailscale, is NetBird op één VPS het alternatief dat u kunt overwegen. Beide transporteren uw verkeer via WireGuard. De keuze hangt daarom af van de manier waarop u toegangsregels schrijft en van het gedrag van relays. Het is de moeite waard om NetBird en Tailscale op deze punten te vergelijken voordat u een van beide installeert. Raadpleeg voor een bredere vergelijking van de twee modellen hoe WireGuard en Tailscale van elkaar verschillen.

Vereisten voor de installatie

  • Een VPS met Ubuntu 24.04, een publiek IPv4-adres en sudo-toegang. Als de server nieuw is, doorloop dan eerst de eerste tien minuten op een nieuwe VPS.
  • Een DNS A-record dat naar dat adres verwijst. Deze handleiding gebruikt headscale.example.com.
  • Een tweede domein of subdomein voor MagicDNS. Deze handleiding gebruikt tailnet.example.net. Dit mag niet hetzelfde domein zijn als het domein in server_url.
  • Eén clientmachine om verbinding te maken, draaiend op Linux, macOS, Windows, Android of iOS. Headscale 0.29.6 vereist Tailscale clientversie 1.80.0 of nieuwer.

Installatie van headscale via het officiële .deb-bestand

Het project publiceert .deb-pakketten op de GitHub-releasespagina. Per 27 oktober 2026 is de meest recente stabiele release 0.29.6, uitgebracht op 24 oktober 2026. Controleer eerst uw architectuur, aangezien deze in de bestandsnaam is verwerkt.

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

Dit commando toont amd64 op een standaard x86 VPS en arm64 op een Ampere- of Graviton-gebaseerd abonnement. Plaats het antwoord in de onderstaande variabele.

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

De ./ voor de bestandsnaam is vereist. Zonder dit zoekt apt naar een pakket genaamd headscale.deb in uw repositories, wat resulteert in een foutmelding.

Het pakket maakt een headscale-systeemgebruiker aan, schrijft een standaard /etc/headscale/config.yaml, installeert een systemd-unit en start vervolgens de service. headscale draait dus al op het moment dat apt terugkeert en sudo systemctl is-active headscale de waarde active toont. Bij een nieuwe installatie schakelt het pakket de unit echter niet in, waardoor de service na een herstart niet automatisch opkomt totdat u deze inschakelt; dit gebeurt in de onderstaande herstartstap. De service draait bovendien op de meegeleverde configuratie, die server_url naar http://127.0.0.1:8080 wijst; dit is geen adres dat uw clients kunnen bereiken. Er is nog niets blootgesteld, omdat de standaard listen_addr eveneens op loopback staat, maar voeg geen clients toe voordat u server_url heeft ingesteld en de service heeft herstart, zoals beschreven in de volgende twee stappen.

Configureer server_url voordat er clients verbinding maken

Bewerk /etc/headscale/config.yaml met sudo nano /etc/headscale/config.yaml, of pas dezelfde drie wijzigingen toe met sed. Bewaar een kopie van het origineel, aangezien het bestand lang is, uitgebreid van commentaar is voorzien en de beste referentie vormt voor de overige instellingen.

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 is het publieke adres dat headscale gebruikt bij het genereren van registratie-URL's. Clients gebruiken het control-adres dat is geconfigureerd met --login-server, dus gebruik dezelfde publieke naam met https:// op beide locaties, nooit 127.0.0.1. De documentatie van headscale stelt dat gewoon HTTP, of HTTPS op een andere poort dan 443, mogelijk is, maar voor productieomgevingen wordt HTTPS op poort 443 sterk aanbevolen; de rest van deze handleiding gaat hiervan uit.

listen_addr is de locatie waar het proces aan bindt. Laat dit op loopback staan. Een reverse proxy op dezelfde machine handelt de TLS (transport layer security) af en stuurt het verkeer door, waardoor niets buiten de server poort 8080 hoeft te bereiken.

base_domain is het MagicDNS-achtervoegsel, het domein waaronder uw nodes namen krijgen. Dit moet een volledig gekwalificeerde domeinnaam (FQDN) zijn zonder afsluitende punt, en het moet een ander domein zijn dan dat in server_url, omdat de twee naamruimten anders met elkaar in conflict zouden komen.

Wijzig de database-sectie niet. De standaardinstelling is SQLite op /var/lib/headscale/db.sqlite, in een map die door het pakket is aangemaakt en wordt beheerd. SQLite is voldoende voor een tailnet van deze omvang.

Herstart headscale en controleer of het proces actief is

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 geeft active weer, is-enabled geeft enabled weer en curl geeft 200 weer. De herstart is de stap die uw wijzigingen laadt. Headscale leest de configuratie slechts één keer bij het opstarten. Het proces dat door het pakket is gestart, blijft daarom de meegeleverde server_url gebruiken totdat u het herstart. sudo systemctl enable --now headscale voert deze taak niet uit: de service draait al, dus de --now start verandert niets en de oude waarde blijft actief. Het starten bij het opstarten van het systeem is de taak van enable, en dit gebeurt niet automatisch voor u: bij een nieuwe installatie start het pakket de service zonder deze in te schakelen. Voer daarom eenmalig sudo systemctl enable headscale uit, zoals hierboven beschreven.

Als is-active iets anders weergeeft dan active, of als de curl niet 200 weergeeft, lees dan het logboek met sudo journalctl -u headscale -n 50 --no-pager. Een fout in dit stadium wordt bijna altijd veroorzaakt door het configuratiebestand. Headscale parseert namelijk het volledige bestand voordat het een socket opent. Een onjuiste inspringing of een ongeldige vereiste instelling stopt het proces voordat er naar poorten wordt geluisterd. Herstel het bestand en voer daarna sudo systemctl restart headscale uit. Elke latere configuratiewijziging vereist dezelfde herstart. Clients maken daarna automatisch opnieuw verbinding. Als systemd-units nieuw voor u zijn, behandelt het beheren van uw eigen services en timers met systemd de commando's die hier worden gebruikt.

Controleer de statusbestanden terwijl u in de shell bent:

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

Beide regels beginnen met headscale, de gebruiker zonder privileges die door het pakket is aangemaakt. noise_private.key is de identiteit van de server voor zijn clients. Bewaar dit bestand. Als u het verwijdert, genereert headscale een nieuwe sleutel en moeten clients de nieuwe serversleutel ophalen voordat ze opnieuw verbinding kunnen maken; bestaande registraties blijven in de database staan.

Plaats TLS voor headscale

Clients moeten server_url bereiken via HTTPS. Caddy is de kortste route, omdat deze zelfstandig certificaten aanvraagt en vernieuwt.

sudo apt install -y caddy

Vervang /etc/caddy/Caddyfile door het blok uit de headscale-documentatie:

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 geeft adapted config to JSON weer wanneer het bestand correct wordt geparseerd. Een waarschuwing dat het bestand niet is geformatteerd is cosmetisch. Vanaf uw laptop zou curl -sS -o /dev/null -w '%{http_code}\\n' https://headscale.example.com/health ook 200 moeten weergeven. Deze enkele controle bewijst dat DNS, de firewall, het certificaat en de proxy correct samenwerken.

Hier is het detail over de proxy dat mensen vaak een avond kost. De Tailscale-control-verbinding is een HTTP-upgrade; deze wordt gestart met een POST in plaats van een GET, en de waarde van de Upgrade-header is tailscale-control-protocol. Caddy geeft dit door zonder extra configuratie. nginx doet dit niet, dus een nginx-frontend moet de Upgrade- en Connection-headers expliciet doorsturen. De headscale-documentatie doet dit met een upgrade-map:

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;
    }
}

Laat u deze regels weg, dan slagen gewone verzoeken nog steeds, wat de reden is dat /health een 200-statuscode retourneert en alles in orde lijkt, terwijl de control-verbinding nooit tot stand komt: nieuwe nodes kunnen niet registreren en bestaande nodes kunnen niet opnieuw verbinden of hun status als online rapporteren. Als u voor de nginx-route kiest, behandelt Certbot op Ubuntu 24.04 met nginx het gedeelte over certificaten.

Welke poorten moeten worden geopend in UFW

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

Poort 443 verwerkt de controleverbinding van elke client naar headscale. Als u later de ingebouwde DERP-relay inschakelt, is ook 3478/udp vereist, wat hieronder wordt behandeld. Poort 80 is aanwezig voor de ACME (automatic certificate management environment) HTTP-challenge en de redirect naar HTTPS. Caddy kan nog steeds een certificaat verkrijgen als poort 80 gesloten is, omdat het de TLS-ALPN-challenge op poort 443 kan gebruiken, maar met poort 80 open zijn beide challenges beschikbaar en worden standaard http://-verzoeken omgeleid.

Poort 8080 blijft gesloten. listen_addr is 127.0.0.1:8080, waardoor de proxy headscale bereikt via de loopback-interface en er geen firewallregel aan te pas komt. Het openen van 8080 in UFW stelt niets bloot, aangezien er van buitenaf niets op luistert, en het levert ook geen voordeel op. Houd er rekening mee dat de meeste providers een tweede firewall in hun configuratiescherm hebben, los van UFW, waardoor een poort op de server open kan staan terwijl deze aan de rand van het netwerk nog steeds gesloten is. Basisprincipes van de UFW-firewall op een VPS behandelt de syntaxis van de regels in meer detail.

Een gebruiker en een preauth-key aanmaken

sudo headscale users create alice
sudo headscale users list

Het headscale-commando is een client. Het communiceert met de actieve daemon via de unix-socket op /var/run/headscale/headscale.sock, die de modus 0770 heeft en eigendom is van de headscale-groep. Hieruit volgen twee zaken. Het commando faalt wanneer de service is gestopt, wat de reden is waarom de volgorde in deze handleiding van belang is, en het vereist sudo tenzij u uw eigen account toevoegt aan de headscale-groep.

users list toont een ID naast elke naam. U heeft dat nummer nodig, omdat het key-commando een numeriek user ID vereist en geen naam.

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

De key wordt eenmalig getoond. Kopieer deze nu. Een preauth-key is voor eenmalig gebruik en is één uur geldig, tenzij u anders aangeeft. Het is daarom de moeite waard om --expiration 24h in te stellen terwijl u nog aan het testen bent. Voeg --reusable toe voor een key die meerdere machines toevoegt, en behandel deze als een wachtwoord, aangezien iedereen die erover beschikt lid kan worden van uw netwerk.

Verbind uw eerste client met --login-server

Op de machine die u wilt toevoegen:

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 toont het adres dat headscale heeft toegewezen, vergelijkbaar met 100.64.0.1. Terug op de server toont sudo headscale nodes list de node met het bijbehorende ID, de gebruiker en de online status.

Gebruik het publieke HTTPS-adres van server_url voor --login-server. De client verwijdert automatisch afsluitende slashes van de control URL; er is geen strikte tekenreeksvergelijking die vereist dat u deze weglaat.

Een machine die voorheen was aangemeld bij de gehoste dienst van Tailscale behoudt die aanmelding. Voer eerst sudo tailscale logout uit op die machine en voer daarna tailscale up uit met --login-server.

Als u --auth-key weglaat, print de client een URL. Open deze URL; de pagina toont de identificatiecode voor die registratiepoging, die u vervolgens op de server goedkeurt:

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

Dat formulier is handiger voor uw eigen laptop. Preauth keys zijn beter voor gescripte processen, aangezien er geen menselijke tussenkomst vereist is. Zodra de VPS zelf een node is, kan deze ook het internetverkeer van uw andere machines afhandelen. Dit is de exit node configuratie, met als enige verschil dat u de geadverteerde route op de server goedkeurt met het headscale commando in plaats van in een gehoste beheerconsole. Als u toegang wilt tot een privénetwerk achter die VPS in plaats van een uitgang naar het internet, geldt dezelfde goedkeuringsstap voor het adverteren van dat subnet naar de rest van uw tailnet. Het publiceren van één applicatie vanaf een node, in plaats van het routeren van volledige netwerken via die node, is een andere taak. serve en funnel zijn de twee manieren om dit te doen, hoewel beide leunen op de eigen certificaat- en ingress-mechanismen van Tailscale. Lees deze daarom als functies van een gehost tailnet in plaats van als functionaliteit die headscale standaard biedt.

DERP, en wat verkeer doorstuurt wanneer een direct pad faalt

DERP (designated encrypted relay for packets) is het fallback-pad. Wanneer twee nodes geen directe WireGuard-verbinding kunnen openen, meestal omdat beide achter strikte NAT (network address translation) zitten, sturen ze pakketten via een relay. De relay bezit geen sleutels en kan uw verkeer daarom niet inzien. De relay ziet wel welke nodes met elkaar communiceren en hoeveel data er wordt verplaatst.

Wees duidelijk over wat de standaardconfiguratie doet. Headscale wordt geleverd met verwijzingen naar https://controlplane.tailscale.com/derpmap/default met auto_update_enabled: true en update_frequency: 3h, waardoor uw control plane van u is, terwijl uw relays van Tailscale zijn. Voor de meeste mensen is dat een acceptabele afweging. Als dat niet zo is, draai dan uw eigen relay.

Om uw eigen relay te draaien, stelt u enabled: true in onder derp.server in config.yaml, vervangt u de meegeleverde ipv4: 198.51.100.1 en ipv6: 2001:db8::1 door de publieke adressen van uw relay, of verwijdert u beide instellingen om DNS te gebruiken. Herstart daarna headscale en open de STUN (session traversal utilities for NAT) poort met sudo ufw allow 3478/udp. Deze adresinstellingen overschrijven DNS; het laten staan van een placeholder stuurt clients naar een onbereikbaar adres. Het configuratiebestand vermeldt de vereiste duidelijk: de server_url moet https gebruiken, omdat DERP TLS vereist. Het leegmaken van de derp.urls lijst verwijdert de relays van Tailscale uit de map; zorg voor een werkende ingebouwde of aangepaste relay voordat u dit doet. Headscale weigert te starten met een lege relay-map, en een map die alleen een onbereikbare relay bevat, zorgt ervoor dat nodes die geen directe verbinding kunnen maken, niet kunnen communiceren.

Vanaf een client print tailscale netcheck de latentie naar elke relay-regio die bekend is, en tailscale status toont direct met een adres of relay met een regiocode voor actieve peer-verbindingen. Een peer die vastzit op relay vereist een controle van het directe pad, inclusief NAT- en firewallregels. Een peer die direct is en toch traag blijft, is een ander vraagstuk, en het gebruikelijke antwoord daarop is MTU in plaats van de tunnel zelf.

Waarom wordt een node als offline weergegeven?

De proxy blokkeert de upgrade. Het kenmerk hiervan is dat /health een 200-statuscode retourneert, terwijl nieuwe registraties mislukken of bestaande nodes geen verbinding kunnen maken. De controleverbinding is een POST-verzoek met Upgrade: tailscale-control-protocol; een proxy die dit niet doorstuurt, blokkeert zowel de registratie als het kanaal dat de status van de node rapporteert. Vergelijk uw nginx-configuratie met de bovenstaande upgrade-regels of schakel over naar Caddy om de proxy als oorzaak uit te sluiten.

Het publieke controleadres is gewijzigd. Nodes blijven het adres proberen dat is geconfigureerd met --login-server; het wijzigen van server_url werkt die clientinstelling niet bij. Als het oude adres uw server niet meer bereikt, voer dan sudo tailscale up --login-server https://headscale.example.com --force-reauth uit op elke node.

De client draait niet. Controleer op de node sudo systemctl is-active tailscaled en sudo journalctl -u tailscaled -n 50 --no-pager. Een client die uw domein niet kan resolven of bereiken, logt daar de herstelpogingen.

De sleutel is verlopen. Dit wordt in de volgende sectie behandeld.

Voer sudo journalctl -u headscale -f uit op de VPS en herstart tailscaled op de client om de serverzijde te monitoren terwijl u test. Controleer ook het client-logboek: een verzoek dat headscale bereikt, genereert niet altijd een regel op het standaard logniveau. Stilte in de serverlogs bewijst dus niet dat er sprake is van een DNS-, firewall- of proxyfout.

Sleutelverloop en de node die weken later stopt met werken

Er bestaan twee afzonderlijke vormen van verloop, en het verwarren hiervan kost onnodig tijd.

Preauth-sleutels verlopen volgens ontwerp snel. De standaardinstelling is één uur en éénmalig gebruik. Als tailscale up de sleutel weigert, genereer dan een nieuwe op de server in plaats van instellingen op de client aan te passen.

Node-sleutels vormen het langdurige gedeelte. De sectie node van config.yaml stelt expiry: 0 in, en 0 betekent dat er geen standaard verloopdatum is; een expliciete verloopdatum voor de client of een OIDC-verloopdatum kan echter nog steeds van toepassing zijn. Getagde nodes zijn vrijgesteld van automatisch verloop, hoewel een beheerder ze expliciet kan laten verlopen. Stel expiry: 180d in als u een standaardtermijn van 180 dagen wilt voor niet-getagde registraties, maar een door de client aangevraagde verloopdatum krijgt voorrang en OIDC kan de standaardinstelling overschrijven. Het wijzigen van deze instelling heeft geen terugwerkende kracht op bestaande registraties. Een node met een verloopdatum vereist herauthenticatie vóór die deadline met behulp van sudo tailscale up --login-server https://headscale.example.com --force-reauth. Een headless server die door niemand opnieuw wordt geauthenticeerd, zal van het netwerk verdwijnen zodra de registratie verloopt.

Voer dit handmatig uit wanneer iemand een laptop verliest. sudo headscale nodes list geeft u het ID, vervolgens logt sudo headscale nodes expire -i 3 die node uit, en sudo headscale nodes delete -i 3 verwijdert deze volledig uit het netwerk.

Backups en upgrades

/var/lib/headscale en /etc/headscale vormen samen de volledige server. Stop de service voordat u deze kopieert, omdat SQLite schrijfacties in uitvoering kan hebben en een database die onder belasting wordt gekopieerd, inconsistent kan zijn.

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

Verplaats beide bestanden van de server. Ze bevatten de privésleutels en elke registratie, dus ze vereisen dezelfde zorg als de server zelf. restic backups vanaf een VPS beschrijft hoe u dit volgens een schema en versleuteld uitvoert.

Upgrades herhalen de installatie: download de nieuwe .deb, sudo apt install ./headscale.deb, start daarna opnieuw op en voer de is-active en /health controles opnieuw uit. Sinds 0.29 is het upgradepad strikt. Het overslaan van een minor-versie is geblokkeerd, evenals het downgraden naar een oudere minor-versie. Upgrade één minor-versie per keer, maak voor elke stap een back-up en lees eerst de release notes van die versie, aangezien diezelfde release het gedrag van het ACL-beleid heeft gewijzigd en diverse configuratiesleutels heeft verplaatst. Versie 0.29.6 bevat ook beveiligingsupdates voor certificaatvalidatie en dependencies, dus bestaande 0.29-installaties dienen deze patch-release te installeren.

FAQ

Draait headscale direct na de installatie van het .deb-pakket?

Ja. Het pakket start de service direct na installatie op de meegeleverde /etc/headscale/config.yaml, die alleen op loopback luistert en server_url instelt op http://127.0.0.1:8080. Bij een nieuwe installatie wordt de service niet ingeschakeld, waardoor deze pas bij het opstarten van het systeem actief wordt nadat u sudo systemctl enable headscale uitvoert. Het meegeleverde adres is onbruikbaar voor clients, dus bewerk server_url, listen_addr en base_domain, voer daarna sudo systemctl restart headscale uit en bevestig met sudo systemctl is-active headscale. Dit moet restart zijn: headscale leest het bestand alleen bij het starten, en enable --now op een service die al draait schakelt deze wel in voor de boot, maar herstart de service niet, waardoor de oude waarden actief blijven. Als het na de herstart mislukt, benoemt sudo journalctl -u headscale -n 50 --no-pager het probleem; in dit stadium is het bijna altijd een YAML-fout, aangezien headscale het volledige bestand parseert voordat het een poort bindt.

Moet ik nog steeds de normale Tailscale-client op mijn machines installeren?

Ja. Headscale vervangt alleen de control server. Elke node draait de officiële client van Tailscale, en u wijst deze naar uw server met sudo tailscale up --login-server https://headscale.example.com. Die flag bestaat in de standaard client, dus er hoeft niets gepatcht of opnieuw gecompileerd te worden.

Gaat mijn verkeer via de headscale-server?

Meestal niet. Headscale coördineert het netwerk en deelt sleutels en adressen uit, terwijl het datapad WireGuard is, direct tussen uw nodes. Verkeer neemt alleen een omweg wanneer twee nodes elkaar niet direct kunnen bereiken en terugvallen op een DERP-relay; met de standaardconfiguratie zijn die relays de publieke servers van Tailscale. Voer tailscale status uit op een node om te zien of een specifieke peer direct is of via een relay verloopt.

Waarom blijft mijn node offline nadat deze is geregistreerd?

Een node die in headscale nodes list verschijnt maar niet online komt, vereist een controle van de control-verbinding, inclusief de reverse proxy. Die verbinding is een HTTP-upgrade die als POST wordt verzonden met de header Upgrade: tailscale-control-protocol, en nginx verwerpt deze tenzij u de headers Upgrade en Connection expliciet doorstuurt met proxy_set_header, wat de bovenstaande configuratie doet via het map $http_upgrade $connection_upgrade-blok. Het weglaten van die headers voorkomt ook dat nieuwe nodes zich kunnen registreren. Caddy stuurt dit door zonder extra configuratie, wat het een snelle manier maakt om te testen of de proxy de oorzaak is.

Heb ik een domeinnaam en TLS nodig voor headscale?

Voor deze opzet wel: gebruik een domeinnaam en HTTPS. Certificaten kunnen ook bare IP-adressen dekken, maar het configuratiebestand stelt dat DERP TLS vereist. Een domein plus Caddy kost ongeveer vijf minuten en levert een HTTPS-endpoint op dat zichzelf vernieuwt. Gewone HTTP is mogelijk, maar de documentatie van headscale raadt HTTPS op poort 443 sterk aan voor productie, en merkt op dat de Tailscale-client in bepaalde situaties uitgaat van HTTPS op poort 443.

Was dit artikel nuttig?