Wenn Linux conntrack nicht mehr Ihr Freund ist

Wenn Linux conntrack nicht mehr Ihr Freund ist

Die Verbindungsverfolgung („conntrack“) ist eine Kernfunktion des Linux-Kernel-Netzwerkstapels. Es ermöglicht dem Kernel, alle logischen Netzwerkverbindungen oder -flüsse zu verfolgen und dadurch alle Pakete zu identifizieren, aus denen jeder Fluss besteht, sodass sie nacheinander gemeinsam verarbeitet werden können.

Conntrack ist eine wichtige Kernel-Funktion, die in einigen grundlegenden Fällen verwendet wird:

  • NAT stützt sich auf Informationen von conntrack, sodass alle Pakete aus demselben Stream gleich behandelt werden können. Wenn beispielsweise ein Pod auf einen Kubernetes-Dienst zugreift, verwendet der Kube-Proxy-Load-Balancer NAT, um den Datenverkehr an einen bestimmten Pod innerhalb des Clusters weiterzuleiten. Conntrack zeichnet auf, dass für eine bestimmte Verbindung alle Pakete an den IP-Dienst an denselben Pod gesendet werden müssen und dass vom Backend-Pod zurückgegebene Pakete per NAT an den Pod zurückgesendet werden müssen, von dem die Anfrage kam.
  • Stateful Firewalls wie Calico verlassen sich auf Informationen von Connecttrack, um den „Antwort“-Verkehr auf die Whitelist zu setzen. Auf diese Weise können Sie eine Netzwerkrichtlinie schreiben, die besagt: „Erlaube meinem Pod, eine Verbindung zu einer beliebigen Remote-IP-Adresse herzustellen“, ohne eine Richtlinie schreiben zu müssen, die den Antwortverkehr explizit zulässt. (Ohne dies müssten Sie die viel weniger sichere Regel „Pakete von jeder IP an meinen Pod zulassen“ hinzufügen.)

Darüber hinaus verbessert Conntrack in der Regel die Systemleistung (durch Reduzierung des CPU-Verbrauchs und der Paketlatenz), da nur das erste Paket in einem Stream angezeigt wird
muss den gesamten Netzwerkstapel durchgehen, um zu bestimmen, was damit geschehen soll. Siehe den Beitrag „Vergleich der Kube-Proxy-Modi" um ein Beispiel dafür zu sehen, wie das funktioniert.

Allerdings hat conntrack seine Grenzen ...

Wo ist also alles schief gelaufen?

Die Conntrack-Tabelle hat eine konfigurierbare maximale Größe, und wenn sie voll ist, werden Verbindungen normalerweise abgelehnt oder gelöscht. In der Tabelle ist genügend freier Speicherplatz vorhanden, um den Datenverkehr der meisten Anwendungen zu bewältigen, und dies wird nie zu einem Problem werden. Es gibt jedoch einige Szenarios, in denen Sie die Verwendung der conntrack-Tabelle in Betracht ziehen sollten:

  • Der offensichtlichste Fall ist, wenn Ihr Server eine extrem große Anzahl gleichzeitig aktiver Verbindungen verarbeitet. Wenn Ihre Conntrack-Tabelle beispielsweise für 128 Einträge konfiguriert ist, Sie aber >128 gleichzeitige Verbindungen haben, werden Sie mit Sicherheit auf ein Problem stoßen!
  • Ein etwas weniger offensichtlicher Fall: Wenn Ihr Server sehr viele Verbindungen pro Sekunde verarbeitet. Auch wenn die Verbindungen nur von kurzer Dauer sind, werden sie von Linux noch einige Zeit lang überwacht (standardmäßig 120 Sekunden). Wenn Ihre Conntrack-Tabelle beispielsweise für 128 Einträge konfiguriert ist und Sie versuchen, 1100 Verbindungen pro Sekunde zu verarbeiten, überschreiten diese die Größe der Conntrack-Tabelle, selbst wenn die Verbindungen sehr kurzlebig sind (128/120 s = 1092 Verbindungen/s). ).

Es gibt mehrere Nischentypen von Apps, die in diese Kategorien fallen. Darüber hinaus könnte das Füllen der Conntrack-Tabelle Ihres Servers mit vielen halboffenen Verbindungen bei vielen böswilligen Akteuren als Teil eines Denial-of-Service-Angriffs (DOS) genutzt werden. In beiden Fällen kann conntrack zu einem limitierenden Engpass in Ihrem System werden. In manchen Fällen kann es ausreichen, die Parameter der Conntrack-Tabelle an Ihre Bedürfnisse anzupassen – durch Erhöhen der Größe oder Reduzieren der Conntrack-Timeouts (wenn Sie es jedoch falsch machen, werden Sie auf große Probleme stoßen). In anderen Fällen ist es erforderlich, Conntrack für aggressiven Verkehr zu umgehen.

Echtes Beispiel

Lassen Sie uns ein konkretes Beispiel geben: Ein großer SaaS-Anbieter, mit dem wir zusammengearbeitet haben, hatte eine Reihe von zwischengespeicherten Servern auf Hosts (keine virtuellen Maschinen), von denen jeder mehr als 50 Kurzzeitverbindungen pro Sekunde verarbeitete.

Sie experimentierten mit der Conntrack-Konfiguration, erhöhten die Tabellengröße und verkürzten die Tracking-Zeit, aber die Konfiguration war unzuverlässig, der RAM-Verbrauch stieg deutlich an, was ein Problem darstellte (in der Größenordnung von GBytes!), und die Verbindungen waren so kurz, dass Conntrack dies nicht tat seinen gewohnten Leistungsvorteil erzielen (geringerer CPU-Verbrauch oder weniger Paketlatenz).

Als Alternative wandten sie sich an Calico. Mit den Calico-Netzwerkrichtlinien können Sie Conntrack für bestimmte Arten von Datenverkehr nicht verwenden (mithilfe der Richtlinienoption „doNotTrack“). Dadurch erhielten sie das erforderliche Leistungsniveau sowie das zusätzliche Maß an Sicherheit, das Calico bietet.

Welchen Aufwand müssen Sie betreiben, um Conntrack zu umgehen?

  • Do-Not-Track-Netzwerkrichtlinien sollten im Allgemeinen symmetrisch sein. Im Fall des SaaS-Anbieters: Seine Anwendungen liefen innerhalb der geschützten Zone und daher konnte er mithilfe von Netzwerkrichtlinien den Datenverkehr von anderen spezifischen Anwendungen, denen der Zugriff auf Memcached gestattet war, auf die Whitelist setzen.
  • Die Do-Not-Track-Richtlinie berücksichtigt nicht die Richtung der Verbindung. Wenn also der Memcached-Server gehackt wird, können Sie theoretisch versuchen, eine Verbindung zu jedem der Memcached-Clients herzustellen, solange dieser den richtigen Quellport verwendet. Wenn Sie jedoch die Netzwerkrichtlinie für Ihre zwischengespeicherten Clients korrekt definiert haben, werden diese Verbindungsversuche weiterhin auf der Clientseite abgelehnt.
  • Die Do-Not-Track-Richtlinie wird auf jedes Paket angewendet, im Gegensatz zu normalen Richtlinien, die nur auf das erste Paket in einem Fluss angewendet werden. Dies kann den CPU-Verbrauch pro Paket erhöhen, da die Richtlinie für jedes Paket angewendet werden muss. Bei kurzlebigen Verbindungen wird dieser Aufwand jedoch durch die Reduzierung des Ressourcenverbrauchs für die Verbindungsverarbeitung ausgeglichen. Im Fall eines SaaS-Anbieters war beispielsweise die Anzahl der Pakete für jede Verbindung sehr gering, sodass der zusätzliche CPU-Verbrauch beim Anwenden von Richtlinien auf jedes Paket gerechtfertigt war.

Beginnen wir mit dem Testen

Wir haben den Test auf einem einzelnen Pod mit einem Memcached-Server und mehreren Memcached-Client-Pods ausgeführt, die auf Remote-Knoten ausgeführt wurden, sodass wir eine sehr große Anzahl von Verbindungen pro Sekunde ausführen konnten. Der Server mit dem zwischengespeicherten Server-Pod hatte 8 Kerne und 512 Einträge in der Conntrack-Tabelle (die standardmäßig konfigurierte Tabellengröße für den Host).
Wir haben den Leistungsunterschied gemessen zwischen: keine Netzwerkrichtlinie; mit regulärer Calico-Richtlinie; und die Do-Not-Track-Richtlinie von Calico.

Für den ersten Test haben wir die Anzahl der Verbindungen auf 4.000 pro Sekunde festgelegt, damit wir uns auf den Unterschied im CPU-Verbrauch konzentrieren können. Es gab keine signifikanten Unterschiede zwischen keiner Richtlinie und einer regulären Richtlinie, aber durch „Do-not-track“ erhöhte sich der CPU-Verbrauch um etwa 20 %:

Wenn Linux conntrack nicht mehr Ihr Freund ist

Im zweiten Test haben wir so viele Verbindungen gestartet, wie unsere Clients generieren konnten, und die maximale Anzahl von Verbindungen pro Sekunde gemessen, die unser zwischengespeicherter Server verarbeiten konnte. Wie erwartet erreichten sowohl die Fälle „keine Richtlinie“ als auch „reguläre Richtlinie“ das Conntrack-Limit von über 4,000 Verbindungen pro Sekunde (512 / 120 s = 4,369 Verbindungen/s). Mit einer Do-Not-Track-Richtlinie haben unsere Kunden problemlos 60,000 Verbindungen pro Sekunde gesendet. Wir sind sicher, dass wir diese Zahl durch die Aufnahme weiterer Kunden erhöhen könnten, aber wir sind der Meinung, dass diese Zahlen bereits ausreichen, um den Sinn dieses Artikels zu veranschaulichen!

Wenn Linux conntrack nicht mehr Ihr Freund ist

Abschluss

Conntrack ist eine wichtige Kernel-Funktion. Er macht seinen Job perfekt. Es wird häufig von wichtigen Systemkomponenten verwendet. In einigen spezifischen Szenarien übersteigt die durch Conntrack verursachte Überlastung jedoch die normalen Vorteile, die es bietet. In diesem Szenario können Calico-Netzwerkrichtlinien verwendet werden, um die Verwendung von Conntrack selektiv zu deaktivieren und gleichzeitig die Netzwerksicherheit zu erhöhen. Für den gesamten übrigen Verkehr bleibt conntrack weiterhin Ihr Freund!

Lesen Sie auch andere Artikel in unserem Blog:

Source: habr.com

Kommentar hinzufügen