I nomi smettono di risolversi nel momento in cui la VPN si connette, mentre un ping verso un indirizzo pubblico risponde ancora e lo stato del firewall non mostra nulla che sembri sbagliato. Nella politica non è cambiato nulla; ciò che è cambiato è che è comparsa una nuova interfaccia, e il rifiuto predefinito la copre dal primo pacchetto. UFW decide per direzione e interfaccia, quindi una regola scritta per il collegamento wireless non dice nulla sul traffico che esce dal tunnel. La riparazione è una manciata di regole strette applicate in un ordine preciso.

Il sintomo compare solo quando il tunnel è attivo

Una politica di rifiuto predefinito fa esattamente ciò che le è stato detto: tutto ciò che non ha una regola corrispondente viene rifiutato, su ogni interfaccia esistente. Il tunnel non esisteva quando sono state scritte le regole, quindi nessuna di esse può coprirlo, e il rifiuto che c'era sempre ora si applica alla risoluzione dei nomi. Il traffico diretto verso un indirizzo letterale può ancora funzionare quando lo copre un permesso più ampio, ed è per questo che un ping verso un resolver pubblico riesce mentre la ricerca di un nome fallisce. Il buco è una regola per un'interfaccia che la politica non ha mai visto.

Questo spiega anche perché il guasto si inverte in modo pulito: togli il tunnel e i nomi si risolvono di nuovo, perché la query torna a un'interfaccia che ha delle regole. Una politica che fallisce solo mentre il tunnel è attivo non è un problema DNS, e regolare il resolver stesso è ciò che qui fa perdere più tempo. Leggi l'elenco delle interfacce prima di leggere la configurazione del resolver.

Tre direzioni, tre insiemi di regole diversi

Una singola sessione tocca regole in più di una direzione, e un tunnel aggiunge una seconda interfaccia a quasi tutte. Ordinare il traffico prima per direzione e interfaccia rende meccanico il resto, perché ogni riga sotto ha bisogno della propria regola al proprio posto. Gli esempi usano tun0 e un pool di 10.8.0.0/24, quindi sostituisci i nomi e gli intervalli con quelli dell'output del client stesso.

DirectionExample packetRule that admits itWritten on
Client to the pushed resolverA DNS query to 10.8.0.1Destination port 53 over the tunnelThe client's tun0
Client to the VPN serverA handshake to the server's public addressServer address and port on the physical linkThe client's physical interface
Server to a serviceSSH from the pool to port 22Source pool, destination port, tunnel interfaceThe server's tun0
Anyone to the listenerThe VPN listener itself1194/udp on the public sideThe server's public interface

Due righe vengono spesso confuse perché entrambe citano il tunnel. Una regola per il resolver ammette il traffico che il client invia nel tunnel, mentre una regola per SSH ammette il traffico che il server ne riceve; vivono su macchine diverse e falliscono in modo indipendente. La riga che si dimentica più spesso è la seconda, perché il client non può affatto stabilire il tunnel finché il suo traffico verso l'indirizzo pubblico del server non è consentito. Lavora dall'alto verso il basso e ogni guasto ha una sola causa candidata.

Un resolver spinto ha bisogno della propria regola

Se il tunnel trasporta DNS dipende da ciò che invia il server. Un server che spinge un'opzione resolver installa un indirizzo privato nella configurazione del client, e quell'indirizzo è instradabile solo attraverso il tunnel. Se il server non spinge nulla, il client mantiene il resolver che aveva già e le regole sotto non hanno nulla da ammettere. Controlla lo stato spinto e il risultato attuale della query prima di scrivere qualsiasi cosa:

dig +short @10.8.0.1 example.com
resolvectl status tun0
sudo ufw status numbered

L'output di stato nomina il resolver in uso e il collegamento a cui è legato, e la ricerca di rotta dietro mostra quale interfaccia porterebbe una query a quell'indirizzo. Quando il resolver si trova su un altro collegamento, il problema è anteriore al firewall e nessuna regola aiuterà. Quando entrambi concordano sul tunnel, servono due regole, perché UDP trasporta la maggior parte delle query e TCP subentra quando una risposta viene troncata. Annota entrambi i valori, perché sono quelli che le regole nomineranno:

sudo ufw allow out on tun0 to 10.8.0.1 port 53 proto udp comment 'pushed resolver'
sudo ufw allow out on tun0 to 10.8.0.1 port 53 proto tcp comment 'truncated answers'

Apri il percorso esterno prima di quello interno

Il client deve raggiungere l'indirizzo pubblico del server prima che esista un tunnel, quindi la regola per farlo siede sul collegamento fisico e deve essere al suo posto per prima. Una politica che ammette il resolver ma dimentica il server lascia il client del tutto incapace di costruire il tunnel, e quel sintomo viene di solito attribuito a un kill switch. Poi ammetti i servizi che volevi davvero attraverso il tunnel, una regola stretta alla volta, invece di aprire l'interfaccia in blocco. Le regole strette sono il motivo per cui il rifiuto può restare al suo posto.

sudo ufw allow out to 198.51.100.10 port 1194 proto udp comment 'vpn server'
sudo ufw allow out on tun0 to any port 443 proto tcp comment 'web through tunnel'

L'ordine conta durante i test, perché la prima regola è ciò che permette al tunnel di salire. Aggiungila, connettiti e conferma che il tunnel è attivo prima di aggiungere la regola del servizio, perché fare entrambe le cose insieme significa che un guasto non ti dice nulla su quale metà sia sbagliata. Sostituisci l'indirizzo di documentazione qui sopra con l'endpoint per cui il client è configurato.

Termina il lato client disconnettendoti di proposito. Il rifiuto dovrebbe ancora respingere il traffico che hai escluso di proposito, perché un resolver che risponde mentre il tunnel è attivo copre solo metà di una politica che rifiuta in caso di dubbio.

Un client che si connette non è ancora ammesso

Il server ha la propria direzione da considerare, e un client che completa lo handshake non raggiunge comunque nulla che giri sul server finché il server non lo ammette. La regola del listener pubblico permette solo che il tunnel esista; non fa entrare il traffico del tunnel. Sul server sono due regole più un controllo che il servizio stia davvero ascoltando:

sudo ufw allow 1194/udp comment 'openvpn listener'
sudo ufw limit in on tun0 from 10.8.0.0/24 to any port 22 proto tcp comment 'admin over tunnel'
ss -ltn | grep ':22'

Il pool nella regola deve essere uguale all'intervallo che il server assegna, e il numero del tunnel deve corrispondere a quello creato dal server, perché una regola per un'altra interfaccia è indistinguibile da nessuna regola. limit è deliberato per una porta amministrativa, perché limita le connessioni ripetute invece di ammetterle senza limite. Il controllo del listener separa una porta chiusa da un pacchetto scartato, che dal client sembrano identici. Anche le regole numerate non sono tutta l'immagine: le regole before di UFW e qualsiasi riga nftables scritta a mano corrispondono prima e possono ancora rifiutare un pacchetto che la lista sembra permettere.

Articoli correlati