UFW scarta il server DNS della VPN appena il tunnel è attivo
La politica di rifiuto predefinito di UFW copre anche l'interfaccia del tunnel. Ordina il traffico per direzione, ammetti il resolver spinto su tun0, poi apri il percorso esterno.
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.
| Direction | Example packet | Rule that admits it | Written on |
|---|---|---|---|
| Client to the pushed resolver | A DNS query to 10.8.0.1 | Destination port 53 over the tunnel | The client's tun0 |
| Client to the VPN server | A handshake to the server's public address | Server address and port on the physical link | The client's physical interface |
| Server to a service | SSH from the pool to port 22 | Source pool, destination port, tunnel interface | The server's tun0 |
| Anyone to the listener | The VPN listener itself | 1194/udp on the public side | The 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 numberedL'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.