Due decisioni indipendenti riguardano lo stesso pacchetto, e ciascuna può terminare la richiesta in silenzio. La ricerca della rotta sceglie un'interfaccia e un next hop, poi il filtro dei pacchetti decide se quella combinazione è consentita. Un timeout vi dice che una delle due ha rifiutato, non quale. Seguite le fasi in ordine e la riparazione di solito smette di essere un'ipotesi.

Due decisioni, un pacchetto, due proprietari

La ricerca della rotta consulta prima le regole di policy, poi la tabella a cui puntano, e sceglie il prefisso più specifico che corrisponde alla destinazione. Un client che ha installato una rotta di tunnel possiede quella decisione, e nulla in una regola del firewall può sostituirla. Quando la ricerca punta a un luogo inatteso, ogni fase successiva lavora sul pacchetto sbagliato.

Il filtraggio è separato. Su un host Linux gli hook di netfilter dividono il traffico in base a chi è destinato il pacchetto: l'output lascia la macchina, l'input termina su di essa, il forward la attraversa. Un gateway che accetta client VPN e li instrada verso una LAN ha bisogno del percorso di forward, ed è esattamente la catena che la maggior parte delle configurazioni predefinite lascia vuota.

La selezione della sorgente appartiene alla stessa decisione, ed è qui che si nascondono la maggior parte dei disallineamenti. Il kernel sceglie un indirizzo sorgente dall'interfaccia in uscita a meno che la rotta non ne indichi uno, quindi una regola di filtro scritta per la sottorete LAN non corrisponde mai a un pacchetto che esce con l'indirizzo del tunnel.

Leggete cosa ha scelto davvero la ricerca

Stampate la decisione invece di dedurla. Il comando seguente risolve la rotta che il kernel userebbe per quella destinazione, comprese l'interfaccia e la sorgente che sceglierebbe:

ip route get 10.8.0.5
ip route get 10.8.0.5 from 192.0.2.44
ip rule show
ip route show table all | sed -n '1,40p'

I client VPN installano spesso regole di policy a priorità inferiori alla tabella principale, quindi una tabella principale pulita non dimostra nulla da sola. Confrontate le priorità delle regole con le tabelle che selezionano, e verificate se la rotta del tunnel sopravvive a una riconnessione invece di essere aggiunta a mano una volta.

L'IPsec basato su policy aggiunge una terza fase di corrispondenza che il routing non copre, come descrivono le note di forwarding di strongSwan per le configurazioni tunnel e transport. La policy di sicurezza seleziona il traffico per prefisso e protocollo, mentre la rotta decide solo dove andrebbe un pacchetto non protetto. Una sottorete instradata ma senza selettore corrispondente o resta non protetta o viene scartata, a seconda della configurazione, e nessuno dei due esiti sembra un problema del firewall. Stampate la policy e confrontate i suoi selettori con i prefissi che vi aspettavate che il tunnel trasportasse.

Il filtraggio si applica a un hook, non a una rotta

Una regola che consente il listener VPN è una regola sul traffico indirizzato al gateway stesso. Non dice nulla sui client che raggiungono host dietro quel gateway, perché il traffico inoltrato attraversa una catena diversa. Leggere l'insieme di regole come un unico elenco piatto è la ragione abituale per cui una regola dall'aspetto corretto non scatta mai.

I contatori risolvono subito la questione. Una regola con conteggio pacchetti zero non è mai stata raggiunta, il che indica la catena sbagliata, l'interfaccia sbagliata o uno scarto precedente. Una regola con conteggio crescente sotto una policy di scarto è il confine che cercavate, e il pacchetto viene scartato invece di essere instradato male.

Inviate una sonda lungo il percorso che usa il client

I test eseguiti sul gateway stesso passano per output e input, con l'indirizzo sorgente del gateway. È un percorso diverso dalla richiesta inoltrata di un client, quindi un curl locale riuscito dimostra meno di quanto sembri. Provate dalla macchina che fallisce, oppure fissate esplicitamente interfaccia e sorgente.

nc -vz -w 3 10.8.0.5 443
ping -c 3 -W 1 10.8.0.5
tcpdump -ni any host 10.8.0.5 and port 443
iptables -vnL FORWARD --line-numbers
nft list ruleset | sed -n '1,60p'

Una cattura su entrambe le estremità separa i casi rimanenti. Un SYN che lascia il client e non arriva mai significa routing, cifratura o una lista di accesso a monte. Un SYN che arriva e non riceve risposta significa il servizio o il suo filtro host, e il tunnel non è mai stato il problema.

Il traffico di ritorno merita un esame a parte. Il routing asimmetrico più il filtraggio del percorso inverso scartano le risposte che arrivano sull'interfaccia sbagliata, il che si manifesta come connessione unidirezionale invece che come porta bloccata. Controllate il valore sysctl prima di dare la colpa al firewall per un sintomo che non ha causato.

Il logging funziona come seconda opinione, non come primo passo. Un'istruzione di log temporanea sulla catena di forward nomina l'interfaccia e gli indirizzi che l'hanno colpita, ed è facile da rimuovere dopo. Lasciatela in permanenza e avrete costruito un problema di volume dei log invece di una risposta.

Mettete ogni modifica dove sopravvive a una riconnessione

Una rotta aggiunta con ip route add vive finché l'interfaccia non cade. Salvatela invece nel profilo di connessione: NetworkManager accetta rotte aggiuntive sulla connessione, e netplan le conserva tra i riavvii. La stessa regola vale per un'eccezione del firewall lato client, che sparisce dopo il successivo ricaricamento.

Le regole lato server appartengono al file di configurazione che il servizio carica all'avvio, non a una sessione interattiva che finisce quando la chiudete. Scrivete la regola, ricaricate e confermate che il contatore si è mosso, perché un ricaricamento che ha rifiutato la sintassi lascia silenziosamente in piedi il vecchio insieme di regole.

Poi ripetete la richiesta originale dell'applicazione da capo a fondo e annotate quale livello è cambiato. Una correzione di rotta che richiedeva anche un cambio di filtro fallirà comunque, e il secondo fallimento si legge molto più facilmente quando sapete che il primo è sparito. Annotate la data e la versione del client accanto al risultato, perché i valori predefiniti di routing e filtraggio si muovono entrambi tra le versioni. Tenete quella nota sul ticket così la prossima persona parte da dove vi siete fermati invece di ripetere il percorso in due fasi.

Articoli correlati