In che modo un firewall ucciderebbe una connessione TCP senza RST o FIN? [chiuso]


8

La situazione è così:

http client ----> corporate firewall ----> http server

A causa di un keepalive, server e client manterrebbero aperte le connessioni TCP e il client userebbe un pool di connessioni per le richieste HTTP.

Il firewall ha una regola per "uccidere" connessioni TCP di vecchia data dopo 1 ora. Il problema è che il nostro client HTTP non ha rilevato che la connessione TCP è stata distrutta e ha tentato di riutilizzare le connessioni essenzialmente morte che dalla nostra parte sembravano "bloccate" dopo un certo periodo di tempo. Una richiesta verrebbe bloccata, quindi la successiva funzionerebbe, presumibilmente perché è stata stabilita una nuova connessione.

La domanda qui è qual è il meccanismo con cui il firewall sta uccidendo le connessioni TCP in modo tale che il nostro client HTTP non sia stato in grado di rilevarle. Ho provato a riprodurre questo comportamento localmente in alcuni modi:

  1. Uccidi le connessioni TCP sul nostro router vyos, Wireshark sul lato client ha catturato TCP FIN-ACK. ok
  2. Kill TCP connessione lato client in TCPView su Windows, Wireshark ha rilevato TCP RST sul lato client. ok
  3. La porta di blocco dopo aver stabilito la connessione al firewall lato client, ha comportato un'eccezione di reimpostazione socket. ok

Ho un dump di Wireshark sul lato server e ho provato a scoprire se il firewall invia un FIN o RST con ip.dst==serverip && (tcp.flags.reset==1 || tcp.flags.fin==1)ma non viene visualizzato nulla.

Inoltre, l'acquisizione di Wireshark sul lato client mostra il problema quando la richiesta HTTP viene interrotta, seguita da una dozzina di ritrasmissioni TCP, che alla fine non vanno da nessuna parte.

Il client HTTP è un client Java nativo e / o Jetty HTTP (provato entrambi), entrambi non sono riusciti a rilevare una connessione TCP morta. Mi piacerebbe riprodurre il comportamento localmente ma non sono in grado di capire in che modo oscuro il firewall sta uccidendo le connessioni, quindi alla ricerca di possibili risposte.


8
Rilascia semplicemente il pacchetto nel firewall, ovvero non inoltrarlo a destinazione e non impostare FIN, RST ecc.
Steffen Ullrich,

È necessario modificare la domanda per includere il modello e la configurazione del firewall (offuscare eventuali password e indirizzi pubblici).
Ron Maupin

"Il firewall ha una regola per" uccidere "connessioni TCP di lunga durata dopo 1 ora." Sembra una regola del firewall davvero bizzarra.
reirab

@RonMaupin Lo avrei già fatto se lo avessi saputo o avessi avuto accesso
cen

Sfortunatamente, le domande sulle reti sulle quali non hai alcun controllo diretto sono esplicitamente fuori tema qui.
Ron Maupin

Risposte:


11

Non menzionate il tipo di firewall, ma sospetto che la maggior parte semplicemente lasci cadere i pacchetti.

Ho un dump Wireshark sul lato server e ho provato a scoprire se il firewall invia un FIN o RST con ip.dst == serverip && (tcp.flags.reset == 1 || tcp.flags.fin == 1) ma niente si presentò.

Il che tenderebbe a confermarlo.


Sfortunatamente non conosco alcuna informazione sul firewall poiché è una rete interna. Qualche suggerimento su come potrei riprodurlo localmente (preferibilmente lato client)?
cen

1
Se il tuo obiettivo è creare un banco di prova, potresti eseguire un firewall software su un PC o acquistare un firewall hardware economico. Bloccare la connessione sembrerebbe essere una cosa semplice da fare.
Ron Trunk,

5

Molto probabilmente il firewall ha appena lasciato cadere il pacchetto senza inviare un pacchetto RST, probabilmente dopo aver colpito un valore di timeout della sessione di qualche tipo. Questo è in genere un comportamento configurabile.

Personalmente preferisco che quel pacchetto RST sia inviato proprio perché aiuta i clienti a comportarsi normalmente, ma ho sentito degli argomenti secondo cui ciò non dovrebbe essere fatto sui firewall rivolti verso l'esterno per evitare di fornire alcun tipo di feedback ai potenziali aggressori.

Ho visto questa causa parecchi problemi perché i clienti in genere non gestiscono questo tipo di scenario in modo molto elegante. In sostanza, continuano a riprovare attraverso la sessione TCP originale (che ora è morta) e non provano mai a ristabilirne una nuova. Alla fine si attiva un timeout sul lato client e l'utente riceve un brutto messaggio di errore. L'impostazione di keepalive HTTP in modo appropriato per l'app può aiutare a risolvere questo problema.


L'invio di un FIN o RST richiederebbe che l'implementazione del firewall tenga traccia dei numeri di sequenza sulla connessione (poiché deve inserire tali dati nel pacchetto FIN / RST). Al contrario, una politica "basta rilasciarlo" significherebbe che l'implementazione del firewall deve solo archiviare la 4-tupla e ucciderla quando scade il tempo di 1 ora.
mere3ortal,

Riesco a capire il ragionamento per la rete esterna, ma per quella interna, questo sembra decisamente malvagio.
cen

È malvagio farlo con dignità. Abbandona del tutto solo se nulla deve essere in ascolto su quella porta per quell'intervallo IP.
Joshua,

@ Giosuè, sono completamente d'accordo sul fatto che sia malvagio, proprio perché ho dovuto risolvere il disordine che questo ha causato. Tuttavia, succede con squadre SecOps sufficientemente paranoiche ...
Jeremy Gibbons,

4

@Ron Trunk è esattamente corretto, quasi certamente la connessione aperta viene interrotta o attivamente (nega la regola inserita) o passivamente (rimossa da connessioni conosciute e non può essere ricreata senza un syn). Uno dei commenti ha suggerito di provarlo tu stesso. Ecco una ricetta per farlo usando gli spazi dei nomi della rete linux. Presuppone che l'IP Forwarding sia abilitato nel kernel del tuo host, tu sei root e probabilmente altre cose.

# Create network namespacs
ip netns add one; ip netns add two; ip netns add three
# Create interfaces between namespaces
ip link add dev i12 type veth peer name i21
ip link add dev i32 type veth peer name i23
# Bring interfaces up and assign them to respective namespaces
ip link set dev i12 netns one up
ip link set dev i21 netns two up
ip link set dev i32 netns three up
ip link set dev i23 netns two up
# Assign IP addresses
ip netns exec one ip addr add 1.1.1.1/24 dev i12
ip netns exec two ip addr add 1.1.1.2/24 dev i21
ip netns exec three ip addr add 3.3.3.3/24 dev i32
ip netns exec two ip addr add 3.3.3.2/24 dev i23
# Add routes when necessary
ip netns exec one ip route add default via 1.1.1.2
ip netns exec three ip route add default via 3.3.3.2

Sono quindi necessari tre finestre / shell / schermi / terminali. Esegui ciascun comando di seguito in un terminale distinto:

  • Inizia l'ascolto sul server: ip netns exec three socat TCP-LISTEN:5001 STDIO
  • Inizia a trasmettere sul client: ip netns exec one socat STDIO TCP:3.3.3.3:5001

Si noti che dopo aver eseguito questi comandi, tutto ciò che si digita in una finestra si rifletterà nell'altra e viceversa (dopo aver premuto Invio). Se ciò non è vero, potrebbe essere necessario abilitare l'inoltro IP.

  • Crea un'istanza della regola di rifiuto: ip netns exec two iptables -I FORWARD -j DROP

Quindi non sarà permesso nulla attraverso la digitazione.

Puoi simulare un metodo di rilascio meno attivo con regole di inoltro (non testate) come:

ip netns exec two iptables -A FORWARD -m state --state RELATED,ESTABLISHED -j ACCEPT
ip netns exec two iptables -A FORWARD -m tcp -p tcp -dport 5001 --tcp-flags ALL SYN -j ACCEPT
ip netns exec two iptables -A FORWARD -j DROP

Vedi /unix/127081/conntrack-tcp-timeout-for-state-stablished-not-working e https://www.kernel.org/doc/Documentation/networking/nf_conntrack-sysctl .txt per informazioni su come regolare i timeout - sebbene non mi sia chiaro che iptables supporti nativamente una durata massima della connessione; Credo che tutti i timeout siano timeout inattivi.

Pulisci con ip netns del one; ip netns del two; ip netns del three


Le configurazioni host / server / VM sono fuori tema qui.
Ron Maupin

@Ron Maupin: Ma sta creando un banco di prova di rete per testare una teoria dell'ingegneria di rete fuori tema?
Seth Robertson,

Ci sono alcune cose, come la configurazione dei dispositivi di rete (router, switch, ecc.) O l'utilizzo di qualcosa come Pacet Tracer o GNS3 per deridere qualcosa, sono in tema. La configurazione di host / server / VMS è fuori tema qui. Come funzionano questi e i loro sistemi operativi non fanno parte della rete. L'OP deve includere il modello e la configurazione del firewall in modo da poter vedere se possiamo aiutare.
Ron Maupin

1

Il firewall può inviare un pacchetto ICMP che indica che la destinazione era irraggiungibile. Per tutto tranne TCP, questa è l'unica possibile indicazione di errore, ad esempio l'invio di un pacchetto a una porta UDP chiusa genererà un messaggio "destinazione non raggiungibile" con il codice motivo impostato su "porta non raggiungibile".

È anche possibile inviare messaggi "port non raggiungibili" come risposta ai pacchetti TCP, anche questo interrompe la connessione, ma chiunque analizzi i dump dei pacchetti noterà che ciò è insolito, poiché la convenzione TCP deve indicare porte chiuse con un RST.

Il mittente dovrebbe mappare eventuali pacchetti di errore ICMP ricevuti sulla connessione di origine e gestirli in modo appropriato, pertanto è possibile utilizzare un pacchetto di errori generato dal firewall per terminare una connessione TCP. Il pacchetto ICMP contiene una copia delle intestazioni del pacchetto offensivo per consentire questa mappatura.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.