Vai al contenuto
EuroVPSEuroVPS

Conntrack: quando gli health check passano e il traffico si ferma

Un firewall stateful decide il percorso di una connessione una volta sola, alla creazione, così un flusso di lunga durata può tenersi una decisione stantia mentre ogni nuovo probe passa.

Di EuroVPS EngineeringLa sala macchine

5 min di lettura
In questo articolo 5 sezioni
In breve
  • Un firewall stateful prende la decisione di inoltro e di NAT per una connessione sul suo primo pacchetto e la conserva nella tabella di stato per tutta la vita del flusso. Le modifiche al routing e alle policy non si applicano ai flussi che esistono già.
  • Un flusso continuo come il syslog su TCP, la replica di un database, un forwarder di metriche o un tunnel può tenere aperta una connessione per settimane. Se la rete cambia sotto di esso, quel flusso si tiene la vecchia decisione mentre i ping e le nuove connessioni ricevono quella nuova, e così ogni controllo passa.
  • Monitorate ciò che arriva, non ciò che è acceso: contatori di byte contro il volume atteso, occupazione della tabella di stato, e un controllo end-to-end che i dati siano arrivati. Un flusso congelato si corregge cancellando la sua voce di stato, non riavviando il firewall.

La decisione si prende una volta sola

Il connection tracking esiste perché un firewall valuti la policy una volta per flusso invece che una volta per pacchetto. Il primo pacchetto viene confrontato con le regole, il risultato di inoltro e di NAT viene scritto nella tabella di stato, e ogni pacchetto successivo di quel flusso è un lookup su hash. Il conntrack di netfilter, la tabella di stato di pf in OPNsense e la tabella delle connessioni in Cisco Firepower funzionano tutti così. La voce vive finché il flusso si chiude o il suo timeout di inattività scade, e per una connessione TCP established quel timeout si misura in giorni.

La conseguenza sfugge facilmente: una modifica al routing, a una regola di NAT o a un'interfaccia ha effetto sul flusso successivo, non sui flussi già in tabella.

Due modi in cui questo perde traffico in silenzio

Il percorso stantio. Una rotta cambia, un'interfaccia si sposta, un pool di NAT viene modificato. Le nuove connessioni prendono il nuovo percorso. Un flusso di lunga durata si tiene l'interfaccia di uscita o il binding NAT originale, così i suoi pacchetti escono alla vecchia maniera, verso un next hop che non li inoltra più o senza la traduzione che l'altro capo ormai si aspetta. Lo stack TCP del mittente ritrasmette pazientemente su una connessione che considera ancora established, il destinatario non vede nulla, e nessun processo da nessuna delle due parti è andato in errore.

La tabella piena. Si raggiunge nf_conntrack_max, di solito a causa di uno scanner, di un client dietro NAT con migliaia di flussi brevi o di timeout lunghi su una macchina trafficata. Il kernel registra una riga di log e comincia a scartare il primo pacchetto delle nuove connessioni mentre i flussi esistenti continuano. Un health check che riutilizza una connessione aperta continua a passare; gli utenti che ne aprono di nuove ottengono timeout.

Nessuno dei due compare nel monitoraggio dei processi. Il demone è attivo, il listener è in ascolto, la regola è presente.

Perché gli health check passano

Un ping, un probe TCP connect e il simulatore di percorso di un firewall creano ciascuno un nuovo flusso o valutano la policy da capo, quindi ciascuno riceve la decisione corrente e corretta. La lettura verde è vera, ma sull'oggetto sbagliato. La domanda da porre al firewall non è cosa farebbe con un nuovo pacchetto, ma cosa sta facendo con i flussi che già tiene.

TERMINAL
# the live flows from one source, with their state and NAT binding
conntrack -L -s <source>

# how full the table is
sysctl net.netfilter.nf_conntrack_count net.netfilter.nf_conntrack_max

# the kernel's own report of a full table
journalctl -k | grep -i 'nf_conntrack: table full'

Un flusso che precede l'ultima modifica di routing e mostra un'uscita o una traduzione che nessuna regola corrente produrrebbe è la voce da guardare.

Cosa monitorare

L'arrivo, non la vitalità. Righe al minuto che atterrano nel database del collector, messaggi al minuto sul ricevitore syslog, una posizione di replica che avanza. Una linea piatta è l'allarme, qualunque cosa dica lo stato del processo.

Contatori contro le attese. Il contatore di byte sulla regola che trasporta un flusso cresce più o meno al ritmo del flusso. Una regola che dovrebbe essere trafficata ed è quasi piatta significa che i pacchetti stanno corrispondendo a un'altra regola o non arrivano affatto.

Occupazione della tabella di stato. Allertate su nf_conntrack_count come frazione di nf_conntrack_max ben prima che si riempia, e sul messaggio di tabella piena del kernel, che altrimenti resta nel log senza che nessuno lo legga.

Controlli sintetici con la forma del traffico reale. Un probe che mantiene una connessione di lunga durata e vi spinge un record a intervalli, verificato all'altro capo, testa la cosa che si rompe. Un ping nuovo testa quella che non si rompe.

Dopo ogni modifica di routing o di NAT, elencate i flussi più vecchi della modifica e decidete di proposito se svuotarli.

La correzione è un bisturi

Cancellate lo stato per la sorgente interessata. Il pacchetto successivo crea una voce nuova con la decisione corrente e il flusso riprende.

TERMINAL
conntrack -D -s <source>

Funzionano anche un riavvio o uno svuotamento completo, e si portano giù ogni altra connessione attiva. Per una tabella piena, la correzione è alzare nf_conntrack_max insieme alla dimensione dell'hash, accorciare il timeout established dove non servono giorni, e trovare il client che sta creando i flussi.

Risposte dirette

Perché il firewall dice allow ma non passa traffico?+

Il simulatore di percorso calcola cosa otterrebbe un nuovo pacchetto. Un flusso esistente è legato alla decisione presa quando è stato creato, e il simulatore non legge la tabella di stato. Scaricate i flussi attivi per quella sorgente e confrontate la loro uscita e traduzione con ciò che produrrebbero le regole correnti.

Perché il ping funziona quando il flusso applicativo no?+

Il ping crea flussi di breve durata che scadono in secondi, quindi ognuno riceve una decisione fresca. Il flusso applicativo tiene una sola connessione di lunga durata e si tiene qualunque decisione avesse alla nascita.

Come trovo una connessione bloccata sull'interfaccia sbagliata?+

conntrack -L filtrato per sorgente su netfilter, la vista della tabella di stato su pf o Firepower. Cercate i flussi più vecchi dell'ultima modifica di rete la cui uscita o binding NAT nessuna regola corrente assegnerebbe loro.

Come lo correggo senza riavviare il firewall?+

Cancellate le voci di stato per quella sorgente con conntrack -D. Il pacchetto successivo viene valutato da capo. Tutto il resto nella tabella resta intatto.

Un flusso si è ammutolito mentre ogni controllo è verde?

Parlate con un ingegnere che legge la tabella di stato, non il simulatore.

Parla con un ingegnere (shell cta.talkToEngineer)

Siete arrivati alla fine.

Mettete la lettura al lavoro

Cosa fate girare?

Raccontateci il carico di lavoro, il traffico e i requisiti di ripristino. Partite dal configuratore di server, oppure discutete i dettagli con un ingegnere.

Scritto dagli ingegneri che costruiscono e gestiscono l'infrastruttura che descrive.
Parla con un ingegnere
XIn

5 min rimasti