Wie würde eine Firewall eine TCP-Verbindung ohne RST oder FIN beenden? [geschlossen]


8

Die Situation ist wie folgt:

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

Aufgrund eines Keepalive würden Server und Client TCP-Verbindungen offen halten und der Client würde einen Verbindungspool für HTTP-Anforderungen verwenden.

Die Firewall hat die Regel, langjährige TCP-Verbindungen nach 1 Stunde zu "beenden". Das Problem ist, dass unser HTTP-Client nicht erkennt, dass die TCP-Verbindung zerstört wurde, und versucht hat, im Wesentlichen tote Verbindungen wiederzuverwenden, die auf unserer Seite so aussahen, als ob der Client nach einer gewissen Zeit "hängen geblieben" wäre. Eine Anfrage würde hängen bleiben, dann würde die nächste funktionieren, vermutlich weil eine neue Verbindung hergestellt wurde.

Hier stellt sich die Frage, mit welchem ​​Mechanismus die Firewall TCP-Verbindungen so beendet, dass unser HTTP-Client sie nicht erkennen konnte. Ich habe versucht, dieses Verhalten auf verschiedene Arten lokal zu reproduzieren:

  1. Beenden Sie TCP-Verbindungen auf unserem Vyos-Router. Wireshark auf der Clientseite hat TCP FIN-ACK erfasst. OK
  2. Wenn Sie die TCP-Verbindungsclientseite in TCPView unter Windows beenden, hat Wireshark TCP-RST auf der Clientseite erkannt. OK
  3. Das Blockieren des Ports nach dem Herstellen der Verbindung zur clientseitigen Firewall führte zu einer Ausnahme beim Zurücksetzen des Sockets. OK

Ich habe einen Wireshark-Dump auf der Serverseite und habe versucht herauszufinden, ob die Firewall eine FIN oder RST mit sendet, ip.dst==serverip && (tcp.flags.reset==1 || tcp.flags.fin==1)aber es wurde nichts angezeigt.

Darüber hinaus zeigt die Wireshark-Erfassung auf der Clientseite das Problem, wenn die HTTP-Anforderung ausgeht, gefolgt von einem Dutzend TCP-Neuübertragungen, die letztendlich nirgendwo hingehen.

Der HTTP-Client ist ein nativer Java- und / oder Jetty-HTTP-Client (beide ausprobiert). Beide konnten keine tote TCP-Verbindung erkennen. Ich möchte das Verhalten lokal reproduzieren, kann jedoch nicht herausfinden, auf welche zweifelhafte Weise die Firewall die Verbindungen beendet, und suche daher nach möglichen Antworten.


8
Legen Sie das Paket einfach in der Firewall ab, dh leiten Sie es nicht an das Ziel weiter und stellen Sie keine FIN, RST usw. ein
Steffen Ullrich

Sie sollten Ihre Frage so bearbeiten, dass sie das Firewall-Modell und die Konfiguration enthält (Kennwörter und öffentliche Adressen verschleiern).
Ron Maupin

"Die Firewall hat die Regel, langjährige TCP-Verbindungen nach 1 Stunde zu beenden." Das klingt nach einer ernsthaft bizarren Firewall-Regel.
Reirab

@ RonMaupin Ich würde schon, wenn ich es wüsste oder Zugang hätte
cen

Leider sind Fragen zu Netzwerken, über die Sie keine direkte Kontrolle haben, hier ausdrücklich nicht thematisch.
Ron Maupin

Antworten:


11

Sie erwähnen die Art der Firewall nicht, aber ich vermute, dass die Pakete am einfachsten verworfen werden.

Ich habe einen Wireshark-Dump auf der Serverseite und habe versucht herauszufinden, ob die Firewall eine FIN oder RST mit ip.dst == serverip && (tcp.flags.reset == 1 || tcp.flags.fin == 1) sendet, aber nichts aufgetaucht.

Welches würde dazu neigen, dies zu bestätigen.


Leider kenne ich keine Informationen über die Firewall, da es sich um ein internes Netzwerk handelt. Irgendwelche Vorschläge, wie ich dies lokal reproduzieren könnte (vorzugsweise clientseitig)?
cen

1
Wenn Sie einen Prüfstand erstellen möchten, können Sie eine Software-Firewall auf einem PC ausführen oder eine kostengünstige Hardware-Firewall kaufen. Das Blockieren der Verbindung scheint eine einfache Sache zu sein.
Ron Trunk

5

Höchstwahrscheinlich hat die Firewall das Paket nur verworfen, ohne ein RST-Paket zu senden, wahrscheinlich nachdem ein Sitzungszeitlimitwert erreicht wurde. Dies ist normalerweise ein konfigurierbares Verhalten.

Ich persönlich bevorzuge es, dieses RST-Paket genau deshalb senden zu lassen, weil es Clients dabei hilft, sich normal zu verhalten, aber ich habe Argumente dafür gehört, dass dies nicht auf nach außen gerichteten Firewalls erfolgen sollte, um potenziellen Angreifern keinerlei Feedback zu geben.

Ich habe gesehen, dass dies einige Probleme verursacht, weil Kunden mit solchen Szenarien normalerweise nicht sehr elegant umgehen. Im Wesentlichen wiederholen sie die ursprüngliche TCP-Sitzung (die jetzt tot ist) und versuchen niemals, eine neue wiederherzustellen. Schließlich wird ein clientseitiges Timeout ausgelöst und der Benutzer erhält eine böse Fehlermeldung. Wenn Sie HTTP Keepalive entsprechend für die App einrichten, kann dies behoben werden.


Das Senden eines FIN oder RST würde erfordern, dass die Firewall-Implementierung die Sequenznummern auf der Verbindung verfolgt (da diese Daten in das FIN / RST-Paket eingetragen werden müssen). Im Gegensatz dazu würde eine "Just Drop It" -Richtlinie bedeuten, dass die Firewall-Implementierung nur das 4-Tupel speichern und es beenden muss, wenn die 1-Stunden-Zeit abgelaufen ist.
bloß3ortal

Ich kann die Gründe für ein externes Netzwerk verstehen, aber für ein internes scheint dies geradezu böse zu sein.
cen

Es ist böse, dies staatsmäßig zu tun. Lassen Sie nur dann ganz fallen, wenn an diesem Port nichts auf diesen IP-Bereich warten soll.
Joshua

@ Joshua, ich stimmte vollkommen zu, dass es böse ist, gerade weil ich das Chaos beheben musste, das dies verursachte. Trotzdem passiert es mit ausreichend paranoiden SecOps-Teams ...
Jeremy Gibbons

4

@ Ron Trunk ist genau richtig, mit ziemlicher Sicherheit wird die offene Verbindung entweder aktiv (Verweigerungsregel eingefügt) oder passiv (aus bekannten Verbindungen entfernt und darf ohne Synchronisierung nicht neu erstellt werden) getrennt. In einem der Kommentare wurde vorgeschlagen, es selbst auszuprobieren. Hier ist ein Rezept für die Verwendung von Linux-Netzwerk-Namespaces. Es wird davon ausgegangen, dass die IP-Weiterleitung im Kernel Ihres Hosts aktiviert ist, Sie Root sind und wahrscheinlich auch andere Dinge.

# 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

Sie benötigen dann drei Fenster / Schalen / Bildschirme / Terminals. Führen Sie jeden der folgenden Befehle in einem eigenen Terminal aus:

  • Starten Sie den Server: ip netns exec three socat TCP-LISTEN:5001 STDIO
  • Starten Sie die Übertragung auf dem Client: ip netns exec one socat STDIO TCP:3.3.3.3:5001

Beachten Sie, dass nach dem Ausführen dieser Befehle alles, was Sie in ein Fenster eingeben, im anderen Fenster angezeigt wird und umgekehrt (nachdem Sie die Eingabetaste gedrückt haben). Wenn dies nicht der Fall ist, müssen Sie möglicherweise die IP-Weiterleitung aktivieren.

  • Instanziieren Sie die Verweigerungsregel: ip netns exec two iptables -I FORWARD -j DROP

Dann wird nichts, was Sie eingeben, durchgelassen.

Sie können eine weniger aktive Drop-Methode mit (nicht getesteten) Weiterleitungsregeln wie den folgenden simulieren:

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

Siehe /unix/127081/conntrack-tcp-timeout-for-state-stablished-not-working und https://www.kernel.org/doc/Documentation/networking/nf_conntrack-sysctl .txt für Informationen zum Anpassen der Zeitüberschreitungen - obwohl mir nicht klar ist, dass iptables nativ eine maximale Verbindungslebensdauer unterstützt; Ich glaube, alle Timeouts sind Leerlauf-Timeouts.

Aufräumen mit ip netns del one; ip netns del two; ip netns del three


Host- / Server- / VM-Konfigurationen sind hier nicht zum Thema.
Ron Maupin

@ Ron Maupin: Aber ist das Erstellen eines Netzwerkprüfstandes zum Testen einer Theorie der Netzwerktechnik nicht zum Thema?
Seth Robertson

Es gibt einige Dinge, wie die Konfiguration der Netzwerkgeräte (Router, Switches usw.) oder die Verwendung von Pacet Tracer oder GNS3, um etwas zu verspotten, die zum Thema gehören. Das Konfigurieren der Hosts / Server / VMS ist hier nicht zum Thema. Wie diese und ihre Betriebssysteme funktionieren, ist nicht Teil des Netzwerks. Das OP muss das Firewall-Modell und die Konfiguration enthalten, damit wir sehen können, ob wir helfen können.
Ron Maupin

1

Die Firewall kann ein ICMP-Paket senden, das angibt, dass das Ziel nicht erreichbar war. Für alles andere als TCP ist dies die einzig mögliche Fehleranzeige. Wenn Sie beispielsweise ein Paket an einen geschlossenen UDP-Port senden, wird die Meldung "Ziel nicht erreichbar" mit dem Ursachencode "Port nicht erreichbar" generiert.

Es ist auch möglich, "Port nicht erreichbare" Nachrichten als Antwort auf TCP-Pakete zu senden. Dadurch wird auch die Verbindung beendet. Jeder, der Paket-Dumps analysiert, wird jedoch feststellen, dass dies ungewöhnlich ist, da die TCP-Konvention darin besteht, geschlossene Ports mit einem RST anzuzeigen.

Es wird erwartet, dass der Absender alle empfangenen ICMP-Fehlerpakete der ursprünglichen Verbindung zuordnet und entsprechend behandelt, sodass ein von der Firewall generiertes Fehlerpaket auch zum Beenden einer TCP-Verbindung verwendet werden kann. Das ICMP-Paket enthält eine Kopie der Header des fehlerhaften Pakets, um diese Zuordnung zu ermöglichen.

Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.