Headscale: come ospitare il tuo server Tailscale
Installa headscale su un VPS dal pacchetto .deb ufficiale, imposta server_url, riavvia il servizio e collega il primo nodo alla tua rete privata.
Che cos'è headscale
Headscale è un'implementazione self-hosted del server di controllo di Tailscale. Il server che coordina la rete privata è quindi un VPS di tua proprietà. È un progetto della community e non è gestito da Tailscale Inc. Ogni macchina esegue comunque il client ufficiale tailscale, configurato per usare il tuo server con un'unica flag, --login-server.
Il server di controllo determina chi appartiene alla rete. Assegna a ogni nodo un indirizzo nell'intervallo 100.64.0.0/10, distribuisce le chiavi pubbliche e comunica ai nodi dove trovarsi a vicenda. I tunnel restano tunnel WireGuard, creati direttamente tra i nodi. Il traffico tra due macchine non passa attraverso il server headscale, a meno che non sia possibile creare un percorso diretto e i nodi debbano usare un relay. Gestire autonomamente questo ruolo cambia chi lo controlla, non le funzioni che può svolgere. Prima di considerare la migrazione un miglioramento della sicurezza di per sé, conviene quindi capire a quali risorse può e non può accedere un server di controllo in questo modello.
Headscale gestisce un tailnet (una rete Tailscale) per istanza. Il progetto lo considera adatto all’uso personale o a una piccola organizzazione. Con tre o quattro macchine, una semplice VPN WireGuard su un VPS di tua proprietà richiede meno software da gestire e offre meno componenti che possono guastarsi. Headscale diventa utile quando non vuoi più scrivere manualmente un blocco [Peer] per ogni nuovo laptop. Spesso il costo è il motivo per cui si prende in considerazione questa soluzione. Prima di gestire un server, conviene quindi leggere che cosa copre effettivamente il piano gratuito hosted, perché in genere una manciata di macchine personali rientra nei suoi limiti. Se hai già superato tale soglia, confronta il totale con il costo dei piani a pagamento per utente e per risorsa con tag, perché i dispositivi degli utenti sono illimitati, mentre le risorse con tag hanno limiti e costi separati. Se vuoi un control plane self-hosted, ma preferisci un client proprietario e un’interfaccia web per gestire i peer invece di un sostituto drop-in di Tailscale, NetBird su un singolo VPS è l’alternativa da valutare. Entrambe le soluzioni trasportano il traffico tramite WireGuard. La scelta dipende quindi dal modo in cui scrivi le regole di accesso e dal comportamento dei relay. Prima di installare una delle due soluzioni, conviene confrontare NetBird e Tailscale sotto questi aspetti. Per un confronto più ampio tra i due modelli, consulta le differenze tra WireGuard e Tailscale.
Prerequisiti per l'installazione
- Una VPS con Ubuntu 24.04, un indirizzo IPv4 pubblico e accesso sudo. Se il server è nuovo, segui prima i primi dieci minuti su una nuova VPS.
- Un record DNS A che punti a quell'indirizzo. Questa guida usa
headscale.example.com. - Un secondo dominio o sottodominio per MagicDNS. Questa guida usa
tailnet.example.net. Non deve corrispondere al dominio indicato inserver_url. - Una macchina client da aggiungere, con Linux, macOS, Windows, Android o iOS. Headscale 0.29.6 richiede Tailscale client versione 1.80.0 o successiva.
Installare headscale dal file .deb ufficiale
Il progetto pubblica pacchetti .deb nella pagina delle release di GitHub. Al 27 ottobre 2026, l'ultima release stabile è la 0.29.6, pubblicata il 24 ottobre 2026. Verifica prima l'architettura, perché il nome del file la indica.
sudo apt update
sudo apt install -y wget
dpkg --print-architectureIl comando stampa amd64 su un VPS x86 standard e arm64 su un piano di tipo Ampere o Graviton. Inserisci il risultato nella variabile seguente.
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 versionIl ./ davanti al nome del file è obbligatorio. Senza di esso, apt cerca nei repository un pacchetto chiamato headscale.deb e termina con un errore.
Il pacchetto crea un utente di sistema headscale, scrive una configurazione predefinita /etc/headscale/config.yaml, installa un'unità systemd e avvia il servizio. Di conseguenza, headscale è già in esecuzione quando apt restituisce il controllo e sudo systemctl is-active headscale stampa active. In una nuova installazione, però, il pacchetto non abilita l'unità. Il servizio quindi non verrà riavviato dopo un reboot finché non lo abiliti. Il passaggio di riavvio riportato di seguito esegue anche questa operazione. Il servizio è inoltre in esecuzione con la configurazione fornita dal pacchetto. Questa configurazione imposta server_url su http://127.0.0.1:8080, che non è un indirizzo raggiungibile da nessun tuo client. Al momento non è esposto nulla, perché anche il listen_addr fornito dal pacchetto è associato al loopback. Non aggiungere però alcun client finché non avrai impostato server_url e riavviato il servizio, come fanno i due passaggi successivi.
Configura server_url prima che si connetta qualsiasi client
Modifica /etc/headscale/config.yaml con sudo nano /etc/headscale/config.yaml oppure applica le stesse tre modifiche con sed. Conserva una copia dell’originale, perché il file è lungo e ampiamente commentato e rappresenta il riferimento migliore per le altre impostazioni.
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.yamlserver_url è l’indirizzo pubblico che headscale usa per creare gli URL di registrazione. I client usano l’indirizzo di controllo configurato con --login-server, quindi usa lo stesso nome pubblico con https:// in entrambe le posizioni, mai 127.0.0.1. La documentazione di headscale indica che è possibile usare HTTP semplice oppure HTTPS su una porta diversa da 443, ma raccomanda vivamente HTTPS sulla porta 443 in produzione e il resto di questa guida presuppone questa configurazione.
listen_addr indica l’indirizzo su cui il processo resta in ascolto. Lascialo sull’interfaccia di loopback. Un reverse proxy sullo stesso server gestisce la terminazione TLS (transport layer security) e inoltra le richieste al processo, quindi nessun host esterno deve poter raggiungere la porta 8080.
base_domain è il suffisso MagicDNS, cioè il dominio sotto il quale i nodi ricevono i propri nomi. Deve essere un nome di dominio completo senza punto finale e deve essere diverso dal dominio indicato in server_url, altrimenti i due spazi dei nomi entrerebbero in conflitto.
Lascia invariata la sezione del database. Il valore predefinito è SQLite in /var/lib/headscale/db.sqlite, all’interno di una directory creata e gestita dal pacchetto, e SQLite è sufficiente per una tailnet di queste dimensioni.
Riavviare headscale e verificare che sia in esecuzione
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/healthis-active stampa active, is-enabled stampa enabled e curl stampa 200. Il riavvio carica le modifiche. Headscale legge la configurazione una sola volta, all'avvio, quindi il processo avviato dal pacchetto continua a usare il server_url fornito dal pacchetto finché non lo riavvii. sudo systemctl enable --now headscale non svolge questo compito: il servizio è già in esecuzione, quindi il comando --now non modifica nulla e il vecchio valore resta attivo. L'avvio al boot è gestito da enable e non viene eseguito automaticamente: in una nuova installazione il pacchetto avvia il servizio senza abilitarlo, quindi esegui sudo systemctl enable headscale una volta, come sopra.
Se is-active stampa un valore diverso da active oppure curl non stampa 200, consulta il journal con sudo journalctl -u headscale -n 50 --no-pager. Un errore in questa fase riguarda quasi sempre il file di configurazione, perché headscale analizza l'intero file prima di aprire un socket. Di conseguenza, un'indentazione errata o un'impostazione obbligatoria non valida arresta il processo prima che possa mettersi in ascolto. Correggi il file, quindi esegui sudo systemctl restart headscale. Ogni modifica successiva alla configurazione richiede lo stesso riavvio. I client si riconnettono autonomamente in seguito. Se non hai familiarità con le unità systemd, eseguire i propri servizi e timer con systemd illustra i comandi usati qui.
Controlla i file di stato mentre sei nella shell:
stat -c '%U %n' /var/lib/headscale/db.sqlite /var/lib/headscale/noise_private.keyEntrambe le righe iniziano con headscale, l'utente senza privilegi creato dal pacchetto. noise_private.key è l'identità del server per i client. Conservalo. Se lo elimini, headscale ne genera uno nuovo e i client devono recuperare la nuova chiave del server prima di riconnettersi; le registrazioni esistenti restano nel database.
Configura TLS davanti a headscale
I client devono raggiungere server_url tramite HTTPS. Caddy è la soluzione più rapida, perché richiede e rinnova autonomamente il certificato.
sudo apt install -y caddySostituisci /etc/caddy/Caddyfile con il blocco della documentazione di 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 caddyvalidate stampa adapted config to JSON quando il file viene analizzato correttamente. Un avviso che segnala una formattazione non uniforme è solo estetico. Dal laptop, anche curl -sS -o /dev/null -w '%{http_code}\\n' https://headscale.example.com/health dovrebbe stampare 200. Questo singolo controllo dimostra che DNS, firewall, certificato e proxy funzionano insieme.
Ecco il dettaglio del proxy che può richiedere un'intera serata di troubleshooting. La connessione di controllo di Tailscale è un upgrade HTTP, viene avviata con una richiesta POST anziché GET e il valore dell'header Upgrade è tailscale-control-protocol. Caddy inoltra questo traffico senza configurazione aggiuntiva. nginx non lo fa, quindi un front end nginx deve inoltrare esplicitamente gli header Upgrade e Connection. La documentazione di headscale usa una mappa per l'upgrade:
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;
}
}Se ometti queste righe, le richieste ordinarie continuano ad avere esito positivo. Per questo /health restituisce 200 e tutto sembra funzionare, mentre la connessione di controllo non viene mai stabilita: i nuovi nodi non possono registrarsi e quelli esistenti non possono riconnettersi né segnalare di essere online. Se scegli nginx, Certbot su Ubuntu 24.04 con nginx descrive la configurazione dei certificati.
Quali porte aprire in UFW
sudo ufw allow OpenSSH
sudo ufw allow 80/tcp
sudo ufw allow 443/tcp
sudo ufw enable
sudo ufw status verboseLa porta 443 trasporta la connessione di controllo di ogni client a headscale. Se in seguito abiliti il relay DERP integrato, serve anche la porta 3478/udp, descritta di seguito. La porta 80 serve per la challenge HTTP di ACME (ambiente per la gestione automatica dei certificati) e per il redirect a HTTPS. Caddy può comunque ottenere un certificato con la porta 80 chiusa, perché può usare la challenge TLS-ALPN sulla porta 443. Con la porta 80 aperta, però, entrambe le challenge sono disponibili e le richieste http:// in chiaro vengono reindirizzate.
La porta 8080 resta chiusa. listen_addr è 127.0.0.1:8080, quindi il proxy raggiunge headscale tramite l'interfaccia loopback e non è necessaria alcuna regola del firewall. Aprire la porta 8080 in UFW non esporrebbe nulla, perché dall'esterno non vi è alcun processo in ascolto su quella porta, e non offre alcun vantaggio. Tieni presente che la maggior parte dei provider gestisce un secondo firewall nel pannello di controllo, separato da UFW. Di conseguenza, una porta può essere aperta sul server ma restare chiusa sul perimetro di rete. Nozioni di base sul firewall UFW su un VPS descrive in maggiore dettaglio la sintassi delle regole.
Crea un utente e una chiave preautenticata
sudo headscale users create alice
sudo headscale users listIl comando headscale è un client. Comunica con il demone in esecuzione tramite il socket Unix /var/run/headscale/headscale.sock, che ha modalità 0770 ed è di proprietà del gruppo headscale. Questo comporta due conseguenze. Il comando non funziona se il servizio è arrestato, motivo per cui l'ordine indicato in questa guida è importante, e richiede sudo, a meno che tu non aggiunga il tuo account al gruppo headscale.
users list stampa un ID accanto a ogni nome. Ti serve quel numero, perché il comando per creare la chiave richiede un ID utente numerico e non un nome.
sudo headscale preauthkeys create --user 1 --expiration 24hLa chiave viene stampata una sola volta. Copiala subito. Una chiave preautenticata è monouso e resta valida per un'ora, salvo diversa indicazione. Per questo conviene impostare --expiration 24h durante la fase di test. Aggiungi --reusable per creare una chiave che registri più macchine. Trattala come una password, perché chiunque ne sia in possesso può unirsi alla tua rete.
Collega il primo client con --login-server
Sulla macchina che vuoi aggiungere:
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 -4tailscale ip -4 stampa l'indirizzo assegnato da headscale, simile a 100.64.0.1. Torna al server ed esegui sudo headscale nodes list per visualizzare il nodo con il relativo ID, l'utente e lo stato online.
Per --login-server usa l'indirizzo HTTPS pubblico indicato da server_url. Il client rimuove gli slash finali dall'URL del control server; non esegue un confronto esatto delle stringhe che richieda di ometterne uno.
Una macchina che in precedenza aveva effettuato l'accesso al servizio ospitato di Tailscale conserva quella sessione. Esegui prima sudo tailscale logout, quindi esegui tailscale up con --login-server.
Se ometti --auth-key, il client stampa invece un URL. Aprilo: la pagina mostra l'identificatore del tentativo di registrazione, che devi approvare sul server:
sudo headscale auth register --user alice --auth-id PASTE-THE-ID-FROM-THE-PAGEQuesta procedura è più comoda per il tuo laptop. Le chiavi di preautenticazione sono preferibili per tutto ciò che viene eseguito tramite script, perché non è necessario che una persona controlli il processo. Una volta che lo stesso VPS è diventato un nodo, può anche trasportare il traffico Internet delle altre macchine, tramite la configurazione del nodo di uscita. L'unica differenza è che devi approvare la route pubblicizzata sul server con il comando headscale, anziché usare una console di amministrazione del servizio ospitato. Se vuoi raggiungere una rete privata situata dietro quel VPS, invece di usarlo come punto di uscita verso Internet, la stessa procedura di approvazione permette di pubblicizzare quella subnet al resto del tuo tailnet. Pubblicare una singola applicazione da un nodo, anziché instradare intere reti attraverso di esso, è un'attività diversa. serve e funnel sono i due strumenti per farlo, ma entrambi si basano sui certificati e sul sistema di ingress di Tailscale. Considerali quindi funzionalità del tailnet ospitato, non funzionalità fornite da headscale.
DERP e il relay del traffico quando il percorso diretto non è disponibile
DERP (designated encrypted relay for packets) è il percorso di fallback. Quando due nodi non riescono ad aprire una connessione WireGuard diretta, in genere perché si trovano entrambi dietro NAT (network address translation) restrittivo, inviano i pacchetti attraverso un relay. Il relay non dispone di alcuna chiave, quindi non può leggere il traffico. Può però vedere quali nodi comunicano e quanti dati vengono trasferiti.
È importante capire cosa fa la configurazione predefinita. Headscale viene fornito configurato per puntare a https://controlplane.tailscale.com/derpmap/default con auto_update_enabled: true e update_frequency: 3h, quindi il control plane è gestito da te, mentre i relay appartengono a Tailscale. Per la maggior parte degli utenti è un compromesso ragionevole. In caso contrario, esegui un relay autonomo.
Per eseguire un relay autonomo, imposta enabled: true in derp.server all'interno di config.yaml, sostituisci ipv4: 198.51.100.1 e ipv6: 2001:db8::1 forniti con gli indirizzi pubblici del tuo relay oppure rimuovi entrambe le impostazioni per usare DNS, quindi riavvia headscale e apri la porta STUN (session traversal utilities for NAT) con sudo ufw allow 3478/udp. Queste impostazioni degli indirizzi hanno precedenza sul DNS, quindi lasciare uno dei placeholder invia i client a un indirizzo irraggiungibile. Il file di configurazione indica chiaramente il requisito: server_url deve usare https, perché DERP richiede TLS. Svuotare l'elenco derp.urls rimuove i relay di Tailscale dalla mappa; prima di farlo, assicurati di disporre di un relay embedded o personalizzato funzionante. Headscale rifiuta di avviarsi con una mappa dei relay vuota, mentre una mappa che contiene soltanto un relay irraggiungibile impedisce ai nodi che non possono connettersi direttamente di comunicare.
Da un client, tailscale netcheck stampa la latenza verso ogni area geografica DERP conosciuta, mentre tailscale status mostra direct con un indirizzo oppure relay con un codice di area geografica per le connessioni attive tra peer. Un peer bloccato su relay richiede un controllo del percorso diretto, incluse le regole NAT e firewall. Un peer che è direct ma continua a essere lento è un problema diverso; la causa abituale in questo caso è l'MTU, non il tunnel in sé.
Perché un nodo risulta offline?
Il proxy elimina l’upgrade. Il sintomo è che /health restituisce 200, mentre le nuove registrazioni falliscono oppure i nodi esistenti non riescono a riconnettersi. La connessione di controllo è una richiesta POST che contiene Upgrade: tailscale-control-protocol. Se il proxy non la inoltra, blocca sia la registrazione sia il canale che comunica lo stato del nodo. Confronta la configurazione di nginx con le direttive di upgrade riportate sopra oppure passa a Caddy per escludere il proxy dalle cause.
L’indirizzo di controllo pubblico è cambiato. I nodi continuano a connettersi all’indirizzo configurato con --login-server. La modifica di server_url non aggiorna questa impostazione nel client. Se il vecchio indirizzo non raggiunge più il server, esegui sudo tailscale up --login-server https://headscale.example.com --force-reauth su ogni nodo.
Il client non è in esecuzione. Sul nodo, esegui sudo systemctl is-active tailscaled e sudo journalctl -u tailscaled -n 50 --no-pager. Un client che non riesce a risolvere o raggiungere il tuo dominio registra lì i tentativi di riconnessione.
La chiave è scaduta. L’argomento è trattato nella sezione successiva.
Per monitorare il lato server durante i test, esegui sudo journalctl -u headscale -f sul VPS e riavvia tailscaled sul client. Controlla anche il journal del client: il fatto che una richiesta raggiunga headscale non garantisce la presenza di una riga al livello di log predefinito. Pertanto, il silenzio nei log del server, da solo, non dimostra un problema di DNS, firewall o proxy.
Scadenza delle chiavi e nodo che smette di funzionare dopo alcune settimane
Esistono due scadenze separate. Confonderle fa perdere tempo.
Le chiavi di preautenticazione scadono rapidamente per impostazione predefinita. La durata predefinita è di un'ora e una sola utilizzazione. Se tailscale up rifiuta la chiave, generatene una nuova sul server invece di modificare qualcosa sul client.
Le chiavi dei nodi hanno una durata maggiore. La sezione node di config.yaml imposta expiry: 0, mentre 0 indica che non esiste una scadenza predefinita; possono comunque applicarsi una scadenza esplicita del client o una scadenza OIDC. I nodi con tag sono esclusi dalla scadenza automatica, anche se un amministratore può farli scadere esplicitamente. Impostate expiry: 180d se volete una durata predefinita di 180 giorni per le registrazioni senza tag, ma la scadenza richiesta dal client ha la precedenza e OIDC può sostituire il valore predefinito. La modifica di questa impostazione non cambia retroattivamente le registrazioni esistenti. Un nodo con una scadenza deve eseguire nuovamente l'autenticazione prima di tale termine, usando sudo tailscale up --login-server https://headscale.example.com --force-reauth. Un server headless sul quale nessuno esegue nuovamente l'autenticazione viene rimosso dalla rete quando scade la registrazione.
Eseguite queste operazioni manualmente quando qualcuno perde un laptop. sudo headscale nodes list restituisce l'ID, quindi sudo headscale nodes expire -i 3 disconnette quel nodo e sudo headscale nodes delete -i 3 lo rimuove completamente dalla rete.
Backup e aggiornamenti
/var/lib/headscale e /etc/headscale costituiscono l'intero server. Arrestare il servizio prima di copiarli, perché SQLite potrebbe avere operazioni di scrittura in corso e una copia del database eseguita sotto carico potrebbe risultare incoerente.
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-*.tgzSpostare entrambi i file fuori dal server. Contengono le chiavi private e tutte le registrazioni, quindi devono essere protetti con la stessa attenzione del server stesso. backup restic da un VPS spiega come eseguire questa operazione secondo una pianificazione e con la cifratura.
Gli aggiornamenti ripetono la procedura di installazione: scaricare il nuovo .deb, sudo apt install ./headscale.deb, quindi riavviare ed eseguire nuovamente i controlli is-active e /health. A partire dalla versione 0.29, il percorso di aggiornamento è rigido. Non è possibile saltare una versione minor e non è possibile eseguire il downgrade a una versione minor precedente. Procedere una versione minor alla volta, creare un backup prima di ogni passaggio e leggere prima le note di rilascio della versione, perché quella stessa release ha modificato il comportamento dei criteri ACL e spostato diverse chiavi di configurazione. La versione 0.29.6 include inoltre aggiornamenti di sicurezza per la convalida dei certificati e le dipendenze, quindi le installazioni esistenti della versione 0.29 dovrebbero applicare questa patch release.
FAQ
headscale è già in esecuzione subito dopo l'installazione del file .deb?
Sì. Il pacchetto avvia il servizio appena viene installato, sull'/etc/headscale/config.yaml fornito, che resta in ascolto solo sull'interfaccia di loopback e imposta server_url su http://127.0.0.1:8080. In una nuova installazione il servizio non viene abilitato, quindi non verrà avviato al boot finché non esegui sudo systemctl enable headscale. L'indirizzo fornito non è utilizzabile dai client: modifica server_url, listen_addr e base_domain, quindi esegui sudo systemctl restart headscale e verifica con sudo systemctl is-active headscale. Deve essere restart: headscale legge il file solo all'avvio e enable --now su un servizio già in esecuzione lo abilita per il boot, ma non lo riavvia, quindi i vecchi valori restano attivi. Se il servizio non si avvia dopo il riavvio, sudo journalctl -u headscale -n 50 --no-pager identifica il problema. In questa fase si tratta quasi sempre di un errore YAML, perché headscale analizza l'intero file prima di mettersi in ascolto su una porta.
Devo comunque installare il normale client Tailscale sui miei computer?
Sì. Headscale sostituisce solo il server di controllo. Ogni nodo esegue il client ufficiale di Tailscale e lo indirizzi al tuo server con sudo tailscale up --login-server https://headscale.example.com. Questo flag è disponibile nel client standard, quindi non è necessario applicare patch o ricompilare il software.
Il mio traffico passa attraverso il server headscale?
Di norma no. Headscale coordina la rete e distribuisce chiavi e indirizzi, mentre il percorso dei dati usa WireGuard direttamente tra i tuoi nodi. Il traffico passa da un relay solo quando due nodi non riescono a raggiungersi direttamente e ricorrono a un relay DERP. Con la configurazione fornita, questi relay sono quelli pubblici di Tailscale. Esegui tailscale status su un nodo per verificare se un determinato peer è direct oppure si trova su un relay.
Perché il mio nodo resta offline dopo la registrazione?
Un nodo che compare in headscale nodes list ma non risulta mai online richiede un controllo della connessione di controllo, incluso il reverse proxy. Questa connessione è un upgrade HTTP inviato con una richiesta POST e l'header Upgrade: tailscale-control-protocol. nginx lo elimina se non inoltri esplicitamente gli header Upgrade e Connection tramite proxy_set_header, operazione che la configurazione precedente esegue nel relativo blocco map $http_upgrade $connection_upgrade. L'eliminazione di questi header impedisce anche la registrazione di nuovi nodi. Caddy li inoltra senza configurazione aggiuntiva, quindi permette di verificare rapidamente se il problema dipende dal proxy.
Ho bisogno di un nome di dominio e di TLS per headscale?
Per questa configurazione, sì: usa un nome di dominio e HTTPS. I certificati possono coprire anche indirizzi IP nudi, ma il file di configurazione specifica che DERP richiede TLS. Un dominio insieme a Caddy richiede circa cinque minuti di configurazione e fornisce un endpoint HTTPS che rinnova automaticamente il certificato. È possibile usare HTTP semplice, ma la documentazione di headscale raccomanda fortemente HTTPS sulla porta 443 in produzione e segnala che, in alcune situazioni, il client Tailscale presuppone HTTPS sulla porta 443.