Tunnel completo WireGuard: AllowedIPs 0.0.0.0/0 non basta
0.0.0.0/0 e ::/0 scelgono solo cosa trasporta il peer. Il gestore del client, l’inoltro sul gateway, il DNS e la politica di errore vanno comunque configurati.
Mettere 0.0.0.0/0, ::/0 negli AllowedIPs di un peer è il passo che tutti ricordano, e decide solo quale traffico il peer può trasportare. Questi prefissi non creano rotte, non inoltrano nulla dall’altra parte e lasciano il resolver di ogni applicazione esattamente dov’era. Quattro cose separate devono valere insieme perché un tunnel completo sia completo, e conviene verificarle nell’ordine qui sotto, perché un controllo successivo non può salvare uno precedente. Ogni controllo qui sotto è un fatto che si legge da una macchina, non un’impostazione che speri sia stata applicata.
Cosa seleziona il prefisso del peer, e cosa no
AllowedIPs è insieme un selettore e un’autorizzazione. Dice al lato locale quali destinazioni possono essere inviate a questo peer, e dice al lato ricevente quali indirizzi di origine questo peer può presentare. È tutto il lavoro. Nulla in quella descrizione crea una rotta sull’host, abilita l’inoltro sul lato remoto o tocca la risoluzione dei nomi.
Per questo una configurazione può sembrare completa e comportarsi come un tunnel diviso. Il prefisso dice che il peer accetterebbe tutto; la tabella di routing dell’host decide cosa arriva davvero lì, e il gateway decide se qualcosa esce. Nessuna di queste tre decisioni vive nella sezione del peer.
Instradare il client, non solo l’elenco dei peer
Gestori come wg-quick programmano la tabella di routing dell’host per te, ed è per questo che due file di configurazione identici si comportano diversamente a seconda di come è salita l’interfaccia. Un profilo minimo è abbastanza breve da leggerlo in un colpo:
[Interface]
Address = 10.8.0.2/32
DNS = 10.8.0.1
[Peer]
AllowedIPs = 0.0.0.0/0, ::/0
Endpoint = vpn.example.net:51820
Due dettagli portano il lavoro. Il campo Address è un singolo prefisso host invece di una sottorete che il client crede di possedere, ed è il gestore a convertire gli AllowedIPs predefiniti in una rotta predefinita reale. Alza lo stesso file con ip link e wg setconf e non comparirà alcuna rotta, cosa che sembra un tunnel rotto ed è in realtà un tunnel sano con il passo di routing saltato. Il manuale di wg-quick documenta il routing e il Table comportamento che questi gestori aggiungono.
Leggi il risultato invece del file: ip route get 1.1.1.1 dovrebbe nominare l’interfaccia del tunnel, e wg show dovrebbe riportare un handshake recente con un contatore di trasferimento che si muove. Un handshake senza rotta significa che il gestore non è mai partito, e modificare di nuovo il profilo non lo risolverà. Avvia l’interfaccia come la avvierà l’utente, altrimenti il test misura la tua shell invece del deployment.
Tenere l’endpoint fuori dal tunnel
Un tunnel completo cattura ogni destinazione, compresa quella con cui deve parlare per esistere. I gestori lo gestiscono aggiungendo una rotta host per l’endpoint attraverso il gateway originale, ed è per questo che una configurazione corretta contiene quasi sempre un’eccezione deliberata. Applicare metà della configurazione con un gestore e l’altra metà a mano è il modo abituale in cui questa eccezione si perde.
Se l’endpoint è un nome host che risolve su più indirizzi, o su una famiglia che non trasporti, l’eccezione invecchia male e il tunnel può fallire dopo una riconnessione che sembrava routine. Fissa l’endpoint a un indirizzo che controlli, o conferma che il gestore lo rivaluti, e rileggi la rotta host dopo ogni cambio di rete.
Lo stesso meccanismo spiega perché un tunnel completo e un portale captive litigano. Il portale si aspetta di intercettare il traffico che ora il tuo tunnel cattura, quindi su reti di hotel e aeroporti alzi il tunnel dopo il login al portale, mai prima.
Inoltro e percorso di ritorno sul gateway
Sul gateway, abilita l’inoltro per la famiglia che trasporti, consenti la catena forward in entrambe le direzioni quando traduci, e conferma il percorso di ritorno con una ricerca specifica per la sorgente. Nulla di tutto ciò deriva da un handshake riuscito, perché un handshake dimostra solo che i due peer possono scambiarsi UDP. Non dice nulla su cosa accade dopo al pacchetto decapsulato.
sysctl net.ipv4.ip_forward net.ipv6.conf.all.forwarding
ip route get 1.1.1.1 from 10.8.0.2
La ricerca gira sul gateway e non sul client, altrimenti leggerai un’altra tabella di routing. Se nomina l’interfaccia sbagliata, o segnala che non c’è rotta, allora nessuna modifica lato client produrrà un’uscita internet. Quando il gateway traduce gli indirizzi dei client in uscita, la risposta dipende da quello stato di traduzione, quindi la regola deve esistere per entrambe le direzioni del flusso e non solo per quella uscente.
DNS e lo stato di errore, testati a parte
Il protocollo stesso non configura il resolver di nessuna applicazione. wg-quick applica la riga DNS tramite l’integrazione del resolver della distribuzione, container e browser con i propri stack possono ignorarla, e quindi un nome può fallire mentre il tunnel trasporta pacchetti perfettamente. Prova con un nome host invece di un indirizzo, e annota quale server ha risposto invece di dare per scontato che sia quello del profilo.
Le famiglie di indirizzi sono un test separato con una risposta separata. Una rotta predefinita v4 non dice nulla su cosa farà la connessione v6 di un’applicazione, e un tunnel che perde silenziosamente la seconda famiglia è peggio di uno che fallisce rumorosamente. Interroga un nome su ogni famiglia, leggi l’interfaccia usata da ogni richiesta, e controlla i contatori di traduzione prima e dopo, perché una regola che non corrisponde a nulla sembra identica a una regola mancante.
Infine, prova lo stato che vuoi quando il tunnel si ferma. Un tunnel completo dovrebbe fallire chiuso per il traffico che rivendica: se l’interfaccia cade e le applicazioni continuano in silenzio sul collegamento fisico, il progetto è un tunnel diviso con passi in più. Scrivi il comportamento di errore previsto, controllalo di proposito, e chiudi registrando le quattro risposte — quale gestore alza l’interfaccia, quale rotta porta quella predefinita, chi inoltra e traduce sul gateway, e quale resolver risponde.