SSD Nodes Learn Hosting plans →
Guide Matt ConnorDi Matt Connor · Aggiornato 2026-08-27

Come configurare un subnet router Tailscale su VPS

Scopri come pubblicizzare una rete privata dal VPS: approva la route, rendi persistente l'IP forwarding dopo il riavvio e usa --accept-routes su Linux.

Cosa fa un subnet router Tailscale

Un subnet router Tailscale è una macchina che pubblicizza al tuo tailnet un intero intervallo di indirizzi IP privati, in modo che ogni dispositivo nel tailnet possa raggiungere gli indirizzi di quell'intervallo anche se su tali dispositivi non è in esecuzione Tailscale. Il tailnet è la tua rete privata Tailscale: l'insieme dei dispositivi autenticati con lo stesso account o appartenenti alla stessa organizzazione. La funzionalità che viene confusa più spesso con il subnet router è l'exit node, che svolge il compito opposto. Invia tutto il traffico di un dispositivo attraverso il VPS, quindi il VPS diventa il percorso utilizzato da quel dispositivo per raggiungere Internet pubblico.

Una frase per ciascun concetto. Un subnet router rende raggiungibile una rete privata dal tailnet. Un exit node modifica il punto da cui il traffico pubblico esce verso Internet. Se ti serve la seconda funzionalità, consulta come configurare un exit node Tailscale su un VPS. Sono flag distinti e un VPS può svolgere entrambe le funzioni contemporaneamente, ma risolvono problemi diversi e possono non funzionare per cause diverse.

Quando serve un subnet router su un VPS

Il caso più comune riguarda una rete privata già fornita dal provider. Il VPS ha un indirizzo pubblico e una seconda interfaccia su un segmento privato, mentre gli altri server di quel segmento non hanno alcun indirizzo pubblico: un database su 10.0.0.20 e una destinazione per i backup su 10.0.0.30. Installa Tailscale su un VPS, pubblicizza 10.0.0.0/24 e il laptop potrà raggiungere direttamente quegli indirizzi privati. Non è necessario modificare gli altri sistemi del segmento e il database continua a non avere un indirizzo pubblico. Se da quel segmento ti serve soltanto un'applicazione web su una porta, pubblicizzare l'intero intervallo è più di quanto occorra; Tailscale serve aggiunge invece HTTPS soltanto a quella porta. Lo stesso ragionamento vale per un daemon che esegue intenzionalmente il bind solo su localhost, ad esempio dsh eseguito senza interfaccia sotto systemd, dove un indirizzo tailnet su quel VPS sostituisce il tunnel SSH che altrimenti dovresti mantenere aperto per raggiungere la relativa interfaccia.

L'altro caso riguarda una rete situata dall'altra parte del VPS. Può essere una LAN domestica o aziendale (local area network) dietro il proprio router, oppure un rack di appliance che non possono eseguire Tailscale, come uno switch gestito o un vecchio NAS con firmware bloccato. Un sistema Linux su quella rete diventa il subnet router per tutti gli altri dispositivi presenti. In ambito domestico, questo sistema è spesso una piccola VM su un hypervisor che già gestisci; prima di decidere su quale estremità del tunnel debbano risiedere i servizi, devi valutare il confronto dei costi tra un host Proxmox in casa e un VPS a noleggio.

Entrambi i casi hanno un requisito comune. Il subnet router deve poter raggiungere autonomamente l'intervallo che pubblicizza, usando la propria tabella di routing e il proprio firewall. Tailscale non crea questa connessione. Trasporta il traffico fino al router e lo consegna al kernel, che lo inoltra.

Installa Tailscale e verifica prima la route locale

curl -fsSL https://tailscale.com/install.sh | sh

Lo script rileva la distribuzione, aggiunge il repository dei pacchetti di Tailscale, installa il comando tailscale e il demone tailscaled, quindi abilita il servizio. Verifica il risultato con systemctl is-active tailscaled, che dovrebbe stampare active.

Prima di procedere, verifica che il VPS possa raggiungere la rete che prevedi di annunciare.

ip route show
ping -c3 10.0.0.20

ip route show deve elencare l'intervallo privato su un'interfaccia reale, ad esempio 10.0.0.0/24 dev enp7s0 proto kernel scope link src 10.0.0.5. Se il ping fallisce in questo punto, direttamente sul router, nessun flag di Tailscale potrà risolvere il problema. La causa è nella configurazione di rete del VPS oppure in un firewall sull'host di destinazione. Risolvi prima questo problema, perché tutti i test successivi dipendono da questa verifica.

Attivare l'inoltro IP e mantenerlo dopo un riavvio

Una macchina Linux scarta qualsiasi pacchetto non indirizzato a se stessa, a meno che l'inoltro non sia attivo. Inoltrare i pacchetti di altre macchine è il compito principale di un router di subnet, quindi questo passaggio è obbligatorio.

echo 'net.ipv4.ip_forward = 1' | sudo tee -a /etc/sysctl.d/99-tailscale.conf
echo 'net.ipv6.conf.all.forwarding = 1' | sudo tee -a /etc/sysctl.d/99-tailscale.conf
sudo sysctl -p /etc/sysctl.d/99-tailscale.conf

Verificatelo con sysctl net.ipv4.ip_forward, che dovrebbe stampare net.ipv4.ip_forward = 1.

Spesso questo passaggio viene completato solo in parte. sudo sysctl -w net.ipv4.ip_forward=1 funziona immediatamente, ma la modifica viene persa al riavvio successivo. Di conseguenza, il router di subnet può funzionare per settimane e poi smettere di funzionare la mattina successiva a un riavvio causato da un aggiornamento del kernel. La parte fuorviante è che nulla sembra non funzionare. tailscale status continua a mostrare il nodo online, la console di amministrazione continua a mostrare la route approvata e i client continuano ad avere la route installata. I pacchetti arrivano al VPS, ma il kernel li scarta senza registrare alcun messaggio. Scrivere i valori in /etc/sysctl.d/99-tailscale.conf consente di ripristinarli dopo un riavvio.

Se pubblicate le route mentre l'inoltro è ancora disattivato, tailscale up mostra un avviso in quel momento, con una riga simile a Warning: IPv4 forwarding is disabled. Subnet routes and exit nodes may not work correctly.. Leggete l'output di quel comando invece di ignorarlo.

Pubblicare le route

sudo tailscale up --advertise-routes=10.0.0.0/24

Su un VPS già autenticato nella tailnet, modifica direttamente l'impostazione:

sudo tailscale set --advertise-routes=10.0.0.0/24

Usa tailscale set per ogni modifica successiva. Eseguire di nuovo tailscale up con un solo flag reimposta i flag non specificati. La CLI interrompe l'operazione e segnala che, per modificare le impostazioni in questo modo, è necessario indicare tutti i flag non predefiniti. tailscale set modifica una sola impostazione e lascia invariate le altre.

Puoi specificare più intervalli in un unico elenco separato da virgole, senza spazi: --advertise-routes=10.0.0.0/24,192.168.50.0/24. Ogni voce deve essere un indirizzo di rete in notazione CIDR (classless inter-domain routing, nel formato 10.0.0.0/24). Se inserisci per errore l'indirizzo del tuo host, 10.0.0.5/24, l'operazione viene rifiutata perché i bit dopo il prefisso non sono impostati a zero. L'errore indica il prefisso probabilmente corretto. Per interrompere la pubblicazione, imposta un elenco vuoto con sudo tailscale set --advertise-routes=.

Approva la route nella console di amministrazione

La pubblicazione di una route è una richiesta, non una modifica immediata. Finché un amministratore non la approva, nessun client riceve la route e nessuna risorsa dell'intervallo è raggiungibile. Questo comportamento è intenzionale: una macchina che può aggiungersi alla tabella di routing di tutti potrebbe intercettare il traffico destinato a qualsiasi intervallo.

Approvala nella pagina Machines della console di amministrazione. Il VPS è elencato con un badge subnet. Apri la relativa riga, individua la sezione delle subnet, modifica le impostazioni della route, seleziona la route e salva.

L'approvazione riguarda ogni prefisso. Pubblica 10.0.0.0/24 oggi e 192.168.50.0/24 il mese prossimo: il nuovo prefisso arriva non approvato, mentre quello precedente continua a funzionare. Dal VPS, una route approvata e una route ignorata hanno lo stesso aspetto. Controlla quindi la console prima di eseguire qualsiasi altra attività di troubleshooting.

Puoi saltare il passaggio manuale con un blocco autoApprovers nel file delle policy della tailnet:

{
  "autoApprovers": {
    "routes": {
      "10.0.0.0/24": ["tag:subnet-router"]
    }
  }
}

Quindi avvia il nodo con quel tag, sudo tailscale up --advertise-routes=10.0.0.0/24 --advertise-tags=tag:subnet-router, e la route viene approvata nel momento stesso in cui viene pubblicata. Il tag deve esistere prima nella sezione tagOwners dello stesso file delle policy. Questa configurazione è utile se ricrei il VPS tramite uno script, perché un nodo ricreato è un nuovo nodo e le relative route tornano a essere non approvate.

Perché i client Linux ignorano la route senza --accept-routes

La route è ora annunciata e approvata. Il telefono e il Mac possono raggiungere 10.0.0.20. Il laptop Linux non può farlo e nella console di amministrazione non compare alcun problema.

Accettare una route di subnet significa aggiungere voci alla tabella di routing del client. Su Android, iOS, macOS, tvOS e Windows, il client Tailscale esegue automaticamente questa operazione. Su Linux non avviene, perché una macchina Linux è spesso un server o un router la cui tabella di routing è stata configurata intenzionalmente da un amministratore. L'inserimento automatico di una /24 appresa dalla rete potrebbe interrompere il traffico già gestito dalla macchina. Su Linux è quindi necessario abilitarlo esplicitamente su ogni client:

sudo tailscale set --accept-routes

Controllare quindi dove è stata installata la route:

ip route show table 52
ip route get 10.0.0.20

Su Linux, Tailscale non inserisce le route accettate nella tabella di routing principale. Le inserisce nella tabella di routing 52 e installa regole di policy, visibili con ip rule show nell'intervallo di priorità da 5210 a 5270, che inoltrano i pacchetti non corrispondenti a tale tabella. Di conseguenza, ip route show da solo non mostrerà mai 10.0.0.0/24 e chi controlla soltanto questo comando conclude che --accept-routes non ha avuto effetto. ip route show table 52 è il comando che mostra la situazione effettiva e dovrebbe elencare l'intervallo annunciato su tailscale0.

È utile conoscere un'eccezione. Se questo nodo Linux è anche un secondo subnet router per la propria rete locale, --accept-routes fa sì che il traffico destinato alla subnet direttamente connessa venga inviato attraverso l'altro router invece che tramite la propria interfaccia. Su un router di standby in una coppia ad alta disponibilità, lasciare --accept-routes disabilitato e limitarsi ad annunciare la route.

Modalità di errore: due router che annunciano intervalli sovrapposti

Due subnet router non devono annunciare intervalli identici. Gli intervalli sovrapposti con lunghezze di prefisso diverse sono consentiti e Tailscale sceglie la corrispondenza più specifica. Se il router A annuncia 10.0.0.0/24 e il router B annuncia 10.0.0.0/16, il traffico destinato a 10.0.0.20 passa da A.

Il comportamento in caso di indisponibilità di A può sorprendere. Tailscale non esegue il fallback alla route meno specifica. Il traffico verso 10.0.0.20 si interrompe, mentre quello verso 10.1.0.20 continua a funzionare tramite B. Il sintomo sembra indicare che metà della rete privata sia non raggiungibile, ma la causa è un nodo offline che mantiene il prefisso più specifico. Per ottenere il failover, configurare anche il router con l'intervallo più ampio in modo che annunci i prefissi più stretti. In questo modo entrambi coprono gli stessi indirizzi.

L'altra sovrapposizione si verifica più vicino al client. Se il client si trova su una rete alberghiera all'indirizzo 192.168.1.0/24 mentre il subnet router annuncia 192.168.1.0/24, le due route competono per le stesse destinazioni e la route scelta dipende dalla piattaforma. Su Linux, installare una regola con priorità superiore a quella usata da Tailscale, in modo che gli indirizzi locali usino la tabella principale:

sudo ip rule add to 192.168.1.0/24 priority 2500 lookup main

Questa regola non è persistente e viene rimossa al riavvio successivo. La soluzione effettiva consiste nello scegliere un intervallo privato che non si sovrapponga alle reti usate normalmente. 192.168.0.0/24 e 192.168.1.0/24 sono i valori predefiniti nella maggior parte dei router domestici; scegliere quindi un intervallo all'interno di 10.0.0.0/8 definito intenzionalmente. La stessa collisione causa problemi con una VPN WireGuard configurata manualmente, per lo stesso motivo: la route locale più specifica ha la precedenza e il traffico non entra mai nel tunnel.

Modalità di errore: il DNS risolve un indirizzo che nessuna route copre

Questo caso è difficile da diagnosticare perché non viene segnalato alcun errore. Il nome viene risolto. La connessione va in timeout.

Supponiamo che db.internal.example.com venga risolto in 10.0.5.20 tramite il nameserver privato e che sia stato annunciato 10.0.0.0/24. La ricerca ha esito positivo perché la risoluzione DNS (domain name system) e il routing IP sono passaggi separati e nessuno dei due verifica l'altro. Il pacchetto destinato a 10.0.5.20 non trova quindi una route corrispondente sulla tailnet, esce dal default gateway del client e va perso.

Due comandi separano i due passaggi:

nslookup db.internal.example.com
ip route get 10.0.5.20

Se la ricerca restituisce un indirizzo, ma ip route get non risponde con dev tailscale0, il nome è corretto e manca la route. Annuncia un intervallo che includa l'indirizzo, usando 10.0.0.0/16 oppure un secondo prefisso esplicito, quindi approva il nuovo prefisso nella console.

Esiste una trappola analoga sul nameserver stesso. Se imposti nella console di amministrazione un nameserver globale con un indirizzo privato come 10.0.0.53, quell'indirizzo deve rientrare in una route approvata, altrimenti i dispositivi non possono raggiungere il resolver. Se abiliti l'opzione che sostituisce i server DNS locali mentre punti a un resolver irraggiungibile, tutti i dispositivi della tailnet perdono immediatamente la risoluzione dei nomi, compresi quelli che funzionavano fino a un attimo prima. Annuncia e approva prima la route verso il resolver, quindi modifica l'impostazione DNS. Se il DNS all'interno di un tunnel è il problema che continui a dover risolvere, il funzionamento del DNS su un tunnel WireGuard descrive lo stesso meccanismo senza il livello di coordinamento aggiuntivo.

NAT di origine e collegamenti site-to-site

Per impostazione predefinita, il subnet router riscrive l'indirizzo di origine di ogni pacchetto inoltrato usando il proprio indirizzo privato. Si tratta di SNAT (source network address translation) e serve a fare funzionare le risposte senza modificare nulla nella rete privata: il database all'indirizzo 10.0.0.20 risponde al VPS, che sa già come raggiungerlo. Lo svantaggio è che il database vede ogni connessione della tailnet come proveniente dal VPS. Le regole firewall per origine e i log degli accessi non forniscono quindi informazioni utili.

Disattivatelo su Linux quando volete conservare l'indirizzo tailnet reale del client:

sudo tailscale set --snat-subnet-routes=false

Gli host della rete privata devono quindi avere una route verso 100.64.0.0/10, l'intervallo che Tailscale assegna ai dispositivi, con il subnet router come gateway. Senza questa route di ritorno, le risposte vengono inviate al gateway predefinito e non arrivano mai a destinazione. Le connessioni restano quindi bloccate dopo il primo pacchetto. Aggiungete la route statica al gateway della rete privata oppure lasciate SNAT attivo.

Un collegamento site-to-site consiste in due subnet router che svolgono contemporaneamente questa funzione. Ognuno annuncia la propria rete e accetta quella dell'altro:

sudo tailscale up --advertise-routes=10.0.0.0/24 --snat-subnet-routes=false --accept-routes

Eseguite il comando corrispondente sull'altro router, usando il relativo intervallo. I due intervalli devono essere diversi. Se i trasferimenti di grandi dimensioni si bloccano mentre ssh e ping funzionano correttamente, la causa è l'MSS (maximum segment size), cioè la dimensione massima dei dati trasportati da un pacchetto TCP. L'overhead del tunnel rende i pacchetti inoltrati troppo grandi per alcuni collegamenti intermedi. Il clamping risolve il problema:

sudo iptables -t mangle -A FORWARD -o tailscale0 -p tcp -m tcp --tcp-flags SYN,RST SYN -j TCPMSS --clamp-mss-to-pmtu

Salvate la regola con iptables-persistent, altrimenti scompare al riavvio successivo.

Manutenzione per mantenere il servizio operativo

Per impostazione predefinita, a partire da agosto 2026, le chiavi dei nodi scadono dopo 180 giorni. Quando scade la chiave del router di subnet, il nodo viene disconnesso e l'intero intervallo pubblicizzato diventa irraggiungibile, senza che vi sia alcuna modifica alla configurazione che lo spieghi. Disabilita la scadenza delle chiavi per questo computer nella pagina Machines della console di amministrazione, quindi annota di averlo fatto.

Tailscale preferisce una connessione diretta tra i peer e utilizza i propri server relay quando non riesce a stabilirne una. I relay funzionano, ma aggiungono latenza. Un VPS con un indirizzo pubblico è il caso più semplice: consenti il traffico UDP in ingresso sulla porta 41641 e la maggior parte dei peer si connetterà direttamente. Se il firewall è gestito da ufw, le regole ufw effettivamente necessarie su un VPS illustrano la sintassi.

Le regole di accesso sono l'altra parte della configurazione. In un tailnet predefinito, ogni tuo dispositivo può raggiungere tutti gli altri, quindi una route approvata funziona immediatamente. Dopo aver scritto una policy ACL, il lato di destinazione della regola deve indicare l'intervallo privato, perché 10.0.0.20 non è un indirizzo del tailnet e non è coperto dalle regole scritte usando indirizzi IP del tailnet o tag.

Infine, decidi se vuoi affidarti a un coordination server che non gestisci tu. Il control plane di Tailscale è un servizio hosted. Le tue chiavi restano sui tuoi computer, ma l'account e il file della policy risiedono su quel servizio. Prima di assegnargli una route verso la tua rete privata, conviene valutare cosa potrebbe effettivamente fare qualcuno in caso di compromissione del control plane o di furto delle credenziali di accesso all'identità. Il modello di trust di Tailscale descrive il punto in cui si trova questo confine. Il costo raramente spinge gli utenti ad abbandonarlo, perché il piano gratuito copre fino a sei utenti con un numero illimitato di dispositivi propri, anche se un subnet router avviato con un tag viene conteggiato in modo diverso da uno a cui hai effettuato l'accesso con il tuo account. Oltre quella soglia, il costo dipende dal numero di persone e non da quello dei computer, quindi conviene calcolare quanto paga effettivamente una famiglia o un team di cinque persone dopo l'esaurimento del piano gratuito prima di aggiungere l'account che fa superare il limite. L'esecuzione di Headscale, il control server self-hosted di Tailscale mantiene questo componente sul tuo VPS, ma richiede che sia tu a gestirlo. L'altra risposta alla stessa esigenza consiste nell'abbandonare anche i client Tailscale: l'esecuzione self-hosted del server VPN NetBird colloca il coordination layer e i relativi client mesh su un unico computer sotto il tuo controllo. Se stai ancora scegliendo tra questo modello e una configurazione scritta manualmente, il confronto tra WireGuard e Tailscale spiega quali vantaggi offre il coordination layer e quali costi comporta.

FAQ

Qual è la differenza tra un subnet router e un exit node?

Un subnet router pubblicizza un intervallo di indirizzi privati, così i dispositivi della tailnet possono raggiungere macchine su cui Tailscale non è in esecuzione. Un exit node si pubblicizza come route per l'intera Internet, quindi un dispositivo invia tutto il proprio traffico attraverso l'indirizzo pubblico di quel nodo. Un singolo VPS può svolgere entrambi i ruoli. Sono flag distinti, --advertise-routes e --advertise-exit-node, e per ciascuno è necessaria un'approvazione separata nella console di amministrazione.

Perché il mio client Linux ignora la subnet route pubblicizzata?

I client Linux non accettano le subnet route finché non lo si richiede esplicitamente. Esegui sudo tailscale set --accept-routes sul client. Poi verifica con ip route show table 52, non con ip route show. Tailscale installa le route accettate nella routing table 52 e le utilizza tramite policy rules, quindi la main table non le elenca e una route funzionante può sembrare assente.

La subnet ha smesso di funzionare dopo un riavvio. Che cosa si è guastato?

Molto probabilmente l'IP forwarding. Un valore impostato con sysctl -w non sopravvive a un riavvio, quindi scrivilo in /etc/sysctl.d/99-tailscale.conf e confermalo con sysctl net.ipv4.ip_forward. Se il forwarding è attivo e l'intervallo è ancora irraggiungibile, controlla il nodo nella console di amministrazione. Le node keys scadono dopo 180 giorni per impostazione predefinita e un subnet router con una chiave scaduta sembra un problema di rete, non un problema dell'account.

Due subnet router possono pubblicizzare lo stesso intervallo?

Non intervalli identici. Gli intervalli sovrapposti con prefix length diverse sono validi e prevale quello più specifico. Il failover richiede attenzione: quando il router che gestisce il prefisso più specifico va offline, Tailscale non utilizza la route più ampia come alternativa, quindi il traffico si interrompe. Per una vera coppia di standby, configura entrambi i router affinché pubblichino gli stessi prefissi specifici.

Il nome host viene risolto, ma la connessione va in timeout. Perché?

La risoluzione DNS e il routing sono passaggi distinti. Un nome può essere risolto in un indirizzo non coperto da alcuna route approvata; in questo caso il pacchetto esce attraverso il default gateway del client. Esegui ip route get <address> sul client. Se la risposta non include dev tailscale0, pubblicizza un intervallo che copra quell'indirizzo e approva il nuovo prefisso nella console di amministrazione.