Il tunnel è attivo, wg show segnala un handshake recente, puoi fare ping all’indirizzo del tunnel del server, e nulla oltre risponde. L’istinto è rigenerare le chiavi o ricondividere la configurazione. Questo cambia proprio la parte del percorso che è già dimostrato funzionare.

Un handshake completato dice che i due peer concordano sulle chiavi, che UDP raggiunge l’endpoint e che il routing crittografico accetta il pacchetto. Non dice nulla sulla possibilità che il pacchetto lasci poi il server.

Quindi segui un solo pacchetto invece di indovinare. Ci sono quattro punti in cui può morire, e ognuno lascia una traccia diversa.

Cosa dimostra davvero l’handshake

WireGuard è un protocollo UDP che stabilisce una sessione con un handshake Noise e poi cifra i pacchetti per un peer. Quando wg show mostra un handshake di pochi secondi e un contatore di trasferimento in crescita, l’endpoint, le chiavi e la chiave pubblica del peer sono tutti corretti.

Ciò che non dimostra è che il client invii davvero traffico verso internet nell’interfaccia, che il server sia disposto a inoltrarlo o che una risposta riesca a trovare la via del ritorno. Sono decisioni di routing del kernel e del firewall, e vengono prese fuori dal tunnel.

Per questo fare ping all’indirizzo del tunnel del server è un test così fuorviante. Quel pacchetto è indirizzato al server stesso, quindi termina localmente. Non ha mai bisogno di inoltro, mai di traduzione e mai di una rotta di ritorno da internet.

AllowedIPs è una decisione di routing

Sul client, AllowedIPs svolge due compiti. È la tabella di routing a chiave crittografica che decide quali indirizzi di destinazione entrano nel tunnel di questo peer, ed è l’elenco degli indirizzi sorgente che il peer accetterà da te. Se la configurazione del client elenca solo 10.8.0.0/24, le destinazioni pubbliche non entrano mai nell’interfaccia e la tua normale rotta predefinita le porta fuori dal tunnel. Allora il tunnel funziona perfettamente e non fa nulla di ciò che volevi.

Guarda cosa ha installato davvero il client invece di ciò che dice il file di configurazione:

wg show wg0 allowed-ips
ip route get 1.1.1.1

Il secondo comando è quello decisivo. Se la risposta nomina la tua interfaccia fisica e il gateway abituale, il pacchetto non viene incapsulato nel tunnel e nessuna modifica lato server lo risolverà. Aggiungi 0.0.0.0/0 per IPv4 e ::/0 per IPv6 separatamente; una regola che cattura tutto per una famiglia lascia l’altra sul suo percorso originale, ed è una causa comune di un tunnel IPv4 che funziona e di una risoluzione IPv6 bloccata.

Dove il pacchetto muore sul gateway

Se la rotta è corretta e il pacchetto continua a non andare da nessuna parte, arriva al server e si ferma lì. Quattro controlli coprono la maggior parte dei gateway.

Inoltro. sysctl net.ipv4.ip_forward che restituisce 0 è la risposta classica, e molte distribuzioni restano a 0 per impostazione predefinita. Deve essere 1, e va impostato in modo persistente in un file sysctl invece che con un comando che svanisce al riavvio. L’inoltro IPv6 è un interruttore separato.

La politica di filtro. Una catena FORWARD con politica di drop predefinita scarterà il traffico del tunnel mentre consente il traffico verso l’host stesso, il che corrisponde esattamente al sintomo. Leggi l’insieme di regole attivo, non un file salvato: nft list ruleset o iptables -S.

Traduzione o routing. I client con indirizzi di tunnel privati hanno bisogno o di NAT sorgente sull’interfaccia di uscita del server, o di un prefisso instradato che la rete a monte sappia restituire. La scelta tra i due segue il piano degli indirizzi. Aggiungere MASQUERADE a una rete che già instrada il tuo prefisso al ritorno è innocuo ma inutile, e ometterlo dove non esiste alcuna rotta lascia le risposte indirizzate a un intervallo privato non instradabile.

La via di ritorno. Nelle architetture instradate, il router a monte ha bisogno di una rotta che punti al tuo server. Anche la rete del provider può bloccarla: diversi cloud attivano un controllo di sorgente e destinazione sull’istanza, che scarta silenziosamente i pacchetti la cui sorgente non è l’indirizzo proprio dell’istanza finché quel controllo non viene disattivato.

Il DNS fallisce diversamente dal routing

Un pacchetto verso un indirizzo noto e una risoluzione di nome sono due guasti distinti, e i messaggi di errore ingannano in direzioni opposte. Se ping 1.1.1.1 funziona e un browser non carica nulla, la rotta va bene e la risoluzione dei nomi no. Se il ping stesso fallisce, il DNS è irrilevante e sei tornato alla sezione precedente.

wg-quick può impostare un resolver dalla riga DNS = della configurazione, e systemd-resolved ha un proprio comportamento per collegamento. Una VPN che sovrascrive il resolver con un indirizzo raggiungibile solo dentro il tunnel farà fallire ogni risoluzione nel momento in cui il tunnel cade, il che sembra che il tunnel stia rompendo internet.

SymptomLayer to inspect
Tunnel address pings, nothing else doesClient route, then gateway forwarding
Public IP pings, hostnames failResolver selection and reachability
Handshake completes, no reply everFORWARD policy or missing NAT on the server
Small requests work, large transfers stallMTU and TCP MSS clamping

Un ordine che produce prove

Esegui prima il controllo lato client, perché è un solo comando ed elimina metà delle possibilità. Poi conferma se il server è davvero pensato come uscita verso internet; un gateway costruito per l’accesso privato non è guasto quando le destinazioni pubbliche falliscono.

Sul server, osserva l’interfaccia mentre invii un ping dal client: tcpdump -ni wg0 icmp dovrebbe mostrare la richiesta, e tcpdump -ni eth0 icmp dovrebbe mostrare che esce, tradotta o no. Se compare sulla prima e mai sulla seconda, l’arresto è locale al server. Se esce e non torna alcuna risposta, il problema è più a monte, e quella è un’altra conversazione.

Infine fai in modo che la correzione sopravviva a un riavvio. L’inoltro appartiene a un file sysctl, le regole del firewall al servizio che le carica, e le rotte del client alla configurazione che alza l’interfaccia invece che a una shell che dimenticherai. Riconnettiti, ripeti gli stessi due test e conferma che i contatori si muovono.

Articoli correlati