WireGuard: instradare il traffico verso la LAN di casa
Handshake WireGuard attivo ma 192.168.20.10 non risponde? Verifica AllowedIPs, IP forwarding e route di ritorno: ecco i 4 punti da controllare.
Perché la LAN domestica non risponde tramite WireGuard
Per instradare il traffico verso la LAN domestica tramite WireGuard, devono essere coerenti quattro impostazioni separate. Anche tre impostazioni su quattro producono un tunnel che sembra perfettamente funzionante, rendendo il problema difficile da diagnosticare. wg show segnala un handshake recente, ping 10.8.0.1 risponde in pochi millisecondi e ping 192.168.20.10 non restituisce alcun risultato.
Di seguito è riportato l'elenco completo, nell'ordine in cui un pacchetto incontra queste impostazioni. LAN significa rete locale, ovvero la rete privata dietro il router domestico.
AllowedIPssul client deve includere la subnet remota, altrimenti il pacchetto non entra mai nel tunnel.AllowedIPssul server deve includere l'indirizzo del tunnel del client, altrimenti il pacchetto viene scartato non appena viene decrittografato.net.ipv4.ip_forwarddeve essere1sul server, perché Linux scarta ogni pacchetto non indirizzato al server stesso.- La LAN deve conoscere una route di ritorno verso
10.8.0.0/24, tramite una regola di masquerade sul server oppure una route statica sul router domestico.
Tutte queste impostazioni possono fallire senza generare messaggi di errore. Non viene scritto alcun log, non viene visualizzato alcun avviso e l'handshake continua a funzionare per tutto il tempo. Verificale nell'ordine indicato: l'impostazione errata viene individuata in circa un minuto.
La rete utilizzata da questa guida
Tutti gli indirizzi riportati di seguito sono esempi. Sostituiteli con i vostri e mantenete la coerenza tra i valori, perché una configurazione aggiornata solo in parte è la seconda causa più comune di questo problema.
- La LAN domestica è
192.168.20.0/24. Il router domestico è192.168.20.1. - Il server WireGuard è un sistema Linux collegato a questa LAN. La sua interfaccia LAN
enp1s0contiene192.168.20.5, mentre l’interfaccia tunnelwg0contiene10.8.0.1. - L’host che volete raggiungere è un NAS (network attached storage) all’indirizzo
192.168.20.10. - Il client è un laptop situato altrove,
10.8.0.2all’interno del tunnel.
Il server è un computer collegato alla LAN, non il router stesso. È la configurazione normale: ad esempio un Raspberry Pi o un vecchio mini PC. Questo è importante per la regola 4: il router non sa che esiste il tunnel finché non glielo indicate e ogni host della LAN invia al router il traffico destinato a reti esterne alla propria subnet.
Se la connessione domestica non dispone di un indirizzo IP pubblico, questa configurazione non funziona autonomamente, perché nessun sistema su Internet può avviare un handshake verso la vostra rete domestica. La sezione dedicata all’inserimento di un VPS come intermediario tratta questo caso. Le stesse quattro regole restano valide, con un peer aggiuntivo da considerare.
AllowedIPs indica due concetti diversi
Un'unica impostazione svolge due funzioni. Interpretarla nello stesso modo su entrambe le estremità è la causa della maggior parte di questi ticket. WireGuard definisce questo meccanismo cryptokey routing, descritto in maggiore dettaglio in come WireGuard associa le chiavi pubbliche agli intervalli IP.
In uscita, AllowedIPs è una tabella di routing. wg-quick trasforma ogni voce in una route che punta a wg0. Un pacchetto destinato a 192.168.20.10 viene cifrato e inviato a un peer solo se un peer dichiara un intervallo che contiene quell'indirizzo. Se si elenca soltanto 10.8.0.0/24, il laptop invia invece il traffico LAN tramite la rete Wi-Fi locale, dove il traffico può interrompersi oppure raggiungere un 192.168.20.10 completamente diverso.
In ingresso, AllowedIPs è una lista di controllo degli accessi. Dopo aver decifrato un pacchetto proveniente da un peer, WireGuard confronta l'indirizzo sorgente interno con AllowedIPs di quel peer e scarta il pacchetto se non corrisponde. Non viene registrato nulla, a meno che non siano attivati i messaggi di debug del kernel. L'unica traccia è il contatore degli errori di ricezione in wg0, visualizzato da ip -s link show wg0, mentre il pacchetto scompare semplicemente.
Pertanto, i due file di configurazione non sono mai immagini speculari. Il client elenca ciò che vuole raggiungere tramite il server. Il server elenca gli indirizzi sorgente che quel client è autorizzato a utilizzare.
La coppia corrispondente di file di configurazione
Client, /etc/wireguard/wg0.conf:
[Interface]
PrivateKey = <laptop private key>
Address = 10.8.0.2/32
[Peer]
PublicKey = <server public key>
Endpoint = home.example.com:51820
AllowedIPs = 10.8.0.0/24, 192.168.20.0/24
PersistentKeepalive = 25Server, /etc/wireguard/wg0.conf:
[Interface]
PrivateKey = <server private key>
Address = 10.8.0.1/24
ListenPort = 51820
[Peer]
PublicKey = <laptop public key>
AllowedIPs = 10.8.0.2/32Anche il router di casa deve avere un port forwarding, UDP 51820 verso 192.168.20.5, altrimenti l'handshake non inizia mai e il client registra Handshake for peer 1 did not complete after 5 seconds, retrying. Questa guida presuppone che questo passaggio sia già stato completato.
Quattro righe differiscono da una configurazione full tunnel standard, e ciascuna ha uno scopo preciso.
AllowedIPs = 10.8.0.0/24, 192.168.20.0/24sul client, invece di0.0.0.0/0, ::/0. Questo è uno split tunnel: la subnet del tunnel e la LAN domestica passano attraversowg0, mentre tutto il resto continua a usare la route locale. La navigazione web non passa attraverso la connessione di casa, che in genere è ciò che serve quando si deve accedere soltanto al NAS.AllowedIPs = 10.8.0.2/32sul server, con un solo indirizzo invece di un intervallo. Scrivere10.8.0.0/24in quel punto consente a quel singolo client di usare qualsiasi indirizzo all'interno del tunnel. Se in seguito si aggiunge un secondo peer con un intervallo sovrapposto, il traffico viene inviato al peer configurato per ultimo, senza che venga visualizzato alcun errore.PersistentKeepalive = 25soltanto sul client. Il client si trova dietro NAT (network address translation) e il router elimina la mappatura UDP dopo uno o due minuti di inattività; di conseguenza, il server non riesce più a raggiungerlo. Il server ha un indirizzo pubblico e non richiede il keepalive.- Per ora non è presente alcuna riga
DNS =. Aggiungerne una modifica la risoluzione dei nomi per l'intero computer client. La sezione DNS seguente spiega il funzionamento prima di attivarla.
Un full tunnel consente comunque di raggiungere la LAN, perché 0.0.0.0/0 corrisponde a ogni indirizzo. Tuttavia, instrada tutto il traffico attraverso il tunnel e introduce una collisione di subnet che non è possibile correggere dal client.
Perché la stessa subnet alle due estremità causa il problema
Scegli una subnet domestica usata da pochissime altre reti, ad esempio 192.168.20.0/24 o 10.44.7.0/24. 192.168.1.0/24 e 192.168.0.0/24 sono le impostazioni predefinite di fabbrica sulla maggior parte dei router consumer. Prima o poi, quindi, il laptop si collegherà a una rete di un bar o di un hotel che usa esattamente quell'intervallo.
La sovrapposizione blocca la connessione, ma il problema si manifesta in modo diverso nei due casi. Con uno split tunnel, wg-quick prova ad aggiungere una route per un prefisso già presente sull'interfaccia Wi-Fi. Se la route esistente ha la stessa metrica, ip route add rifiuta l'operazione e l'interfaccia non viene attivata:
RTNETLINK answers: File existsSu un laptop gestito da NetworkManager, la route Wi-Fi ha di solito una metrica come 600. L'aggiunta riesce quindi e la route del tunnel, con metrica 0, ha la precedenza. Il NAS risponde, ma ogni host della rete del bar compreso in quell'intervallo, spesso incluso il relativo server DNS, passa ora attraverso il tunnel.
Con un full tunnel, wg-quick installa regole di policy routing che escludono intenzionalmente le route più specifiche della tabella principale. La route locale 192.168.1.0/24 prevale sul tunnel. Ogni pacchetto destinato alla LAN remota esce quindi dal collegamento locale. Il tunnel è attivo, l'handshake funziona, ma il NAS non è raggiungibile. Rinumerare la LAN domestica è l'unica correzione effettiva.
Trasforma il server in un router
ip route show default
printf 'net.ipv4.ip_forward = 1\n' | sudo tee /etc/sysctl.d/99-wireguard.conf
sudo sysctl --system
sysctl net.ipv4.ip_forwardIl primo comando mostra il nome effettivo dell’interfaccia LAN. Le immagini attuali usano nomi come enp1s0 o ens3, più raramente eth0, e una regola di masquerade che indica l’interfaccia errata non corrisponde ad alcun pacchetto. L’ultimo comando dovrebbe stampare net.ipv4.ip_forward = 1. Un semplice sudo sysctl -w imposta lo stesso valore, ma il valore viene perso al riavvio successivo. Questo è il classico caso in cui «ha funzionato fino a martedì».
L’inoltro deve essere consentito anche dal firewall. Su Ubuntu con ufw attivo, i pacchetti inoltrati vengono eliminati se DEFAULT_FORWARD_POLICY="ACCEPT" non è impostato in /etc/default/ufw. Docker, con il backend iptables predefinito, imposta autonomamente la stessa policy quando deve abilitare l’inoltro all’avvio, a meno che ip-forward-no-drop non sia impostato in /etc/docker/daemon.json. Quindi, se sudo iptables -S FORWARD | head -1 stampa -P FORWARD DROP su un sistema su cui non hai configurato manualmente un firewall, di solito significa che lo ha impostato Docker, anche se può farlo anche uno script di provisioning o un altro gestore del firewall. In ogni caso, il traffico del tunnel richiede una regola di accettazione esplicita.
Perché le risposte non tornano indietro
Se le regole da 1 a 3 sono corrette, il ping raggiunge effettivamente il NAS. Tuttavia non si vede alcuna risposta, perché il pacchetto di risposta non ha un percorso per tornare indietro. Il NAS risponde a 10.8.0.2, un indirizzo esterno alla propria subnet, quindi consegna il pacchetto al gateway predefinito, il router di casa all'indirizzo 192.168.20.1. Quel router non conosce 10.8.0.0/24, quindi inoltra la risposta al proprio gateway predefinito, cioè la connessione Internet, dove il pacchetto viene scartato. La richiesta arriva, ma la risposta viene eliminata.
Opzione A: masquerade sul server WireGuard. Il server riscrive l'indirizzo sorgente di ogni pacchetto del tunnel che inoltra da enp1s0 a 192.168.20.5, cioè l'indirizzo LAN della relativa interfaccia. Il NAS vede quindi una richiesta proveniente da un host vicino nella propria subnet, risponde direttamente al server e il server annulla la riscrittura, inviando la risposta nel tunnel. Non è necessario modificare nessun altro dispositivo della LAN.
Inseriscila nel blocco [Interface] del server, in modo che la regola venga aggiunta e rimossa insieme all'interfaccia:
PostUp = iptables -t nat -A POSTROUTING -s 10.8.0.0/24 -o enp1s0 -j MASQUERADE
PostDown = iptables -t nat -D POSTROUTING -s 10.8.0.0/24 -o enp1s0 -j MASQUERADESu un sistema già gestito con nftables, inseriscila invece in /etc/nftables.conf:
table ip nat {
chain postrouting {
type nat hook postrouting priority srcnat; policy accept;
ip saddr 10.8.0.0/24 oifname "enp1s0" counter masquerade
}
}Mantieni la parola chiave counter. Senza di essa, sudo nft list ruleset visualizza la regola senza il conteggio dei pacchetti. Quel conteggio indica precisamente se la regola viene utilizzata.
Masquerade offre anche un secondo vantaggio, facile da trascurare. Molti host eseguono un firewall che accetta connessioni soltanto dalla propria subnet. La condivisione di file di Windows funziona così per impostazione predefinita, come anche diversi pannelli di amministrazione dei NAS. Su questi host, un pacchetto proveniente da 10.8.0.2 viene scartato anche quando il routing è corretto. Dopo il masquerade, l'indirizzo sorgente è un indirizzo LAN, quindi queste regole corrispondono. Lo svantaggio è che nei log di ogni host della LAN tutti i client del tunnel risultano come 192.168.20.5. Non è quindi possibile distinguerli e le regole per singolo client sui dispositivi LAN non possono funzionare.
Opzione B: una route statica sul router di casa. Indica al router che 10.8.0.0/24 si trova dietro 192.168.20.5. Su un router Linux basta un comando:
sudo ip route add 10.8.0.0/24 via 192.168.20.5I router consumer hanno una pagina denominata Static Routes o Routing nelle impostazioni avanzate: destinazione 10.8.0.0, maschera 255.255.255.0, gateway 192.168.20.5. Salva la modifica nella configurazione persistente del router, perché un ip route add inserito su un sistema Linux viene perso al riavvio successivo.
In questo modo viene mantenuto l'indirizzo reale del client, quindi i log e le regole per singolo client nella LAN restano significativi. È necessario un router che supporti le route statiche e la soluzione funziona soltanto per gli host che usano quel router come gateway predefinito. Qualsiasi host con un firewall locale limitato alla subnet deve comunque avere una propria regola per 10.8.0.0/24. Inizia con masquerade, perché non richiede modifiche al di fuori del sistema già sotto il tuo controllo, e passa alla route statica quando vuoi mantenere gli indirizzi reali dei client.
Come individuare quale dei quattro elementi è errato
Procedere dal client verso l'esterno. Ogni passaggio indica se il pacchetto è arrivato fino a quel punto.
Il pacchetto entra nel tunnel? Sul client:
ip route get 192.168.20.10La risposta dovrebbe indicare dev wg0. Se indica l'interfaccia Wi-Fi, la regola 1 è errata e AllowedIPs del client non include la subnet LAN, oppure sta prevalendo una route locale per lo stesso intervallo: è la collisione tra subnet descritta sopra. Un ping: connect: Network is unreachable indica lo stesso problema.
I pacchetti arrivano al server? Eseguire questo comando sul server, quindi eseguire il ping del NAS dal client:
sudo tcpdump -ni wg0 icmpUn percorso funzionante mostra IP 10.8.0.2 > 192.168.20.10: ICMP echo request. ICMP è l'Internet Control Message Protocol, utilizzato da ping. Se non compare nulla, mentre l'handshake è corretto, quasi sempre il problema riguarda la regola 2: AllowedIPs del server per quel peer non include 10.8.0.2, quindi il pacchetto è stato scartato durante la decrittografia, prima di raggiungere wg0. L'aumento del contatore degli errori RX in ip -s link show wg0 sul server a ogni ping lo conferma. Se il contatore non cambia, verificare la presenza di un firewall sul client che blocca il traffico in uscita verso il tunnel.
I pacchetti escono verso la LAN? Sul server, monitorando il lato LAN:
sudo tcpdump -ni enp1s0 icmpSe le richieste sono visibili su wg0 ma non qui, il problema riguarda la regola 3: l'inoltro è disabilitato oppure una regola FORWARD ha scartato il pacchetto. Più raramente, il reverse-path filtering rigoroso (rp_filter) lo scarta perché la route del server verso l'origine passa da un'interfaccia diversa. Se le richieste sono visibili qui con origine 10.8.0.2 ma non arrivano risposte, di solito il problema riguarda la regola 4: la risposta non ha una route di ritorno. Tuttavia, il risultato è identico se l'host ignora il ping o risponde soltanto alla propria subnet. Se le richieste sono visibili qui con origine 192.168.20.5 ma non arrivano risposte, la regola di masquerade funziona e il sistema di destinazione non sta rispondendo. Verificare quindi il firewall sul NAS e, su un host Linux, se net.ipv4.icmp_echo_ignore_all è impostato per ignorare il ping. Lo stesso percorso diagnostico funziona per qualsiasi altro servizio: basta sostituire icmp con port 445 o con la porta richiesta.
Posso raggiungere l'indirizzo IP, ma non il nome
ssh 192.168.20.10 funziona e ssh nas.home.arpa non funziona:
ssh: Could not resolve hostname nas.home.arpa: Name or service not knownIl tunnel non presenta problemi. La risoluzione dei nomi segue un percorso separato e il laptop continua a interrogare il resolver ricevuto dalla rete Wi-Fi locale. Quel resolver non conosce i nomi della rete domestica.
Perché i nomi della rete domestica funzionino, devono essere vere due condizioni. L'indirizzo del resolver deve rientrare in AllowedIPs sul client; in caso contrario, la query DNS (domain name system) non entra mai nel tunnel. Inoltre, il resolver deve accettare una query con indirizzo sorgente 10.8.0.2. Molti resolver domestici rifiutano queste richieste per impostazione predefinita: dnsmasq eseguito con local-service risponde soltanto alle query provenienti da una subnet direttamente connessa, mentre Pi-hole viene distribuito con una modalità di ascolto che consente soltanto le richieste locali. Una regola di masquerade nasconde il problema, perché dopo la riscrittura la query arriva da 192.168.20.5.
Sul client è sufficiente una riga:
DNS = 192.168.20.1Su un client Linux è necessario openresolv o un equivalente; in caso contrario, wg-quick termina con resolvconf: command not found. Prima di impostarlo, verifica il suo comportamento su un sistema con systemd-resolved: wg-quick registra esclusivamente questi server, quindi, mentre il tunnel è attivo, le ricerche dal laptop vengono inviate al resolver domestico, non soltanto quelle relative ai nomi della rete domestica. Solo i nomi appartenenti a un dominio più specifico dichiarato da un'altra interfaccia continuano a essere risolti altrove. Verifica il risultato con resolvectl status wg0. Se vuoi risolvere i nomi della rete domestica a casa e tutti gli altri localmente, si tratta di split DNS; la correzione del DNS su un tunnel WireGuard descrive la configurazione completa.
Nessun IP pubblico a casa? Usa un VPS come nodo intermedio
Se la pagina di stato del router mostra un indirizzo WAN nell'intervallo 100.64.0.0/10, sei dietro CGNAT (carrier grade network address translation) e nessun handshake proveniente da Internet può raggiungere la rete domestica. Un indirizzo 192.168.x.x privato indica in genere la presenza di un secondo router davanti al tuo, cioè un doppio NAT: imposta il modem router dell'ISP in modalità bridge oppure configura anche lì l'inoltro della porta UDP 51820. Se non puoi modificare quel dispositivo, oppure anche il suo indirizzo WAN non è pubblico, trattalo come un caso di CGNAT. Un handshake in uscita continua a funzionare normalmente, quindi la soluzione consiste nell'aggiungere un terzo nodo con un indirizzo pubblico. Un VPS di piccole dimensioni esegue il ruolo di hub e il dispositivo di casa si connette a esso dall'interno.
Le quattro regole non cambiano. Ora si applicano su due hop, quindi la gestione degli indirizzi raddoppia.
- Sul VPS, la voce peer del dispositivo di casa riceve
AllowedIPs = 10.8.0.3/32, 192.168.20.0/24: il proprio indirizzo del tunnel e la subnet per la quale è autorizzato a inoltrare il traffico. - Sul VPS, la voce peer del laptop resta
AllowedIPs = 10.8.0.2/32. - Sul laptop, il peer del VPS riceve
AllowedIPs = 10.8.0.0/24, 192.168.20.0/24, perché ora tutto il traffico passa dall'hub. - Sul dispositivo di casa, il peer del VPS riceve
AllowedIPs = 10.8.0.0/24e il dispositivo di casa gestiscePersistentKeepalive = 25, perché ora si trova sul lato dietro NAT. - Anche il VPS richiede
net.ipv4.ip_forward = 1e la sua catena di forwarding deve consentirewg0awg0, perché il traffico del laptop arriva ed esce dalla stessa interfaccia. Un firewall configurato per un VPS full-tunnel standard blocca esattamente questo traffico.
Se non hai ancora configurato il lato VPS, configurare WireGuard su un VPS illustra la generazione delle chiavi, il firewall e l'unità systemd. Il modello generale per raggiungere una macchina che non può accettare connessioni in ingresso è descritto in aprire un reverse tunnel dietro CGNAT. Quando la gestione manuale degli indirizzi peer diventa poco pratica, eseguire un router subnet Tailscale svolge lo stesso lavoro di routing automatizzando la gestione degli indirizzi.
Rendere la configurazione persistente dopo un riavvio
sudo systemctl enable --now wg-quick@wg0
sudo systemctl enable --now nftables
sudo wg showenable --now è il passaggio che molti saltano. Un wg-quick up wg0 eseguito manualmente scompare dopo il successivo aggiornamento del kernel e il riavvio. wg show dovrebbe elencare il peer con una riga latest handshake recente e contatori di trasferimento diversi da zero in entrambe le direzioni.
L'aggiunta successiva di un secondo client non richiede un riavvio, che disconnetterebbe tutti gli utenti attualmente connessi:
sudo bash -c 'wg syncconf wg0 <(wg-quick strip wg0)'wg-quick strip stampa la configurazione senza le chiavi comprese soltanto da wg-quick, mentre syncconf applica la differenza senza interrompere le sessioni attive. Aggiorna soltanto i peer. La modifica di Address o l'aggiunta di una nuova riga PostUp richiede comunque un arresto e un avvio completi.
FAQ
Perché posso eseguire il ping al server WireGuard, ma non raggiungo nient'altro nella LAN domestica?
Il ping a 10.8.0.1 dimostra soltanto che il tunnel è attivo. Il resto della LAN presenta un problema di routing. AllowedIPs del client deve includere 192.168.20.0/24, altrimenti il pacchetto non entra mai nel tunnel. Sul server è necessario impostare net.ipv4.ip_forward su 1, altrimenti il server scarta tutto ciò che non è indirizzato a se stesso. Anche la LAN deve avere una route di ritorno verso 10.8.0.0/24. Esegui sudo tcpdump -ni enp1s0 icmp sul server mentre esegui il ping: le richieste che escono con origine 10.8.0.2 senza ricevere risposte indicano in genere che manca il percorso di ritorno.
Devo configurare una route statica sul router domestico?
Solo se non usi la regola di masquerade. Una regola di masquerade sul server WireGuard sostituisce l'indirizzo sorgente del traffico del tunnel con l'indirizzo LAN del server. In questo modo gli host della LAN rispondono a un vicino che sanno già come raggiungere e il router non viene coinvolto. L'alternativa è una route statica per 10.8.0.0/24 tramite l'indirizzo LAN del server. Questa soluzione è utile quando vuoi visualizzare nei log degli host LAN gli indirizzi reali dei client o applicare regole firewall specifiche per client.
Perché la stessa subnet a entrambe le estremità interrompe il tunnel?
Il laptop non può usare contemporaneamente due route per lo stesso prefisso. Se la rete locale assegna 192.168.1.0/24 e anche la LAN domestica usa 192.168.1.0/24, un wg-quick up split-tunnel non riesce quando ip route add rifiuta con RTNETLINK answers: File exists oppure, se la route Wi-Fi ha una metrica più alta, si attiva ma nasconde dietro il tunnel gli host locali appartenenti a quell'intervallo. Un full tunnel si attiva comunque, ma wg-quick installa regole di policy che impediscono alle route più specifiche della tabella principale di avere effetto. Di conseguenza prevale la rete locale e la LAN remota resta irraggiungibile. Riassegna alla LAN domestica una subnet poco comune, ad esempio 192.168.20.0/24. Non esiste una correzione lato client.
Raggiungo il NAS tramite indirizzo IP, ma non tramite nome. Che cosa manca?
La risoluzione dei nomi non segue automaticamente il tunnel. Aggiungi DNS = 192.168.20.1, il resolver domestico, al blocco [Interface] del client e verifica che quell'indirizzo rientri in AllowedIPs del peer. In caso contrario, la query non entra mai nel tunnel. Controlla anche che il resolver accetti query provenienti dall'esterno della propria subnet, perché sia dnsmasq con local-service sia la modalità di ascolto locale di Pi-hole rifiutano queste richieste. Una regola di masquerade sul server WireGuard risolve il problema sostituendo l'indirizzo sorgente della query.
La mia connessione domestica non ha un IP pubblico. Posso comunque raggiungere la LAN?
Sì, usando un terzo nodo. Dietro CGNAT, l'indirizzo WAN del router non è pubblico. Nessun peer su Internet può quindi avviare un handshake con il router, mentre un handshake in uscita funziona normalmente. Esegui WireGuard su un VPS con un indirizzo pubblico, configura il dispositivo domestico affinché si connetta a quel VPS tramite PersistentKeepalive = 25 e assegna alla voce del peer relativa al dispositivo domestico sul VPS un AllowedIPs che contenga il suo indirizzo del tunnel e 192.168.20.0/24. Sul VPS devi poi abilitare il forwarding e aggiungere una regola forward che consenta wg0 verso wg0.