Conntrack-Erschöpfung erkennen und eine Limitänderung prüfen

Conntrack-Erschöpfung erkennen und eine Limitänderung prüfen

Conntrack-Erschöpfung erkennen und eine Limitänderung prüfen

Wenn neue Verbindungen sporadisch in einen Timeout laufen, bestehende Sitzungen aber weiterhin Daten übertragen und sowohl Anwendungsprozesse als auch lauschende Ports unauffällig sind, sollte die Verbindungstabelle von Linux geprüft werden. Zustandsbehaftete Firewalls, Adressübersetzung und einige Containernetzwerke sind auf conntrack angewiesen. Lassen sich keine neuen Einträge anlegen, kann neuer Datenverkehr verworfen werden, bevor er die Anwendung erreicht. Dieser Beitrag zeigt am Beispiel von Debian 12, wie sich Belege sammeln, Ursachen eingrenzen, die Kapazität anpassen und Änderungen zurücknehmen lassen — ohne Firewallregeln zu ändern oder bestehende Verbindungen zu löschen.

1. Zuerst den betroffenen Netzwerk-Namespace bestimmen

Dedicated Server von CloudDDR bieten AMD EPYC 7543P sowie 128 GB oder 256 GB ECC-Arbeitsspeicher. Die Speicherkapazität bestimmt jedoch nicht unmittelbar das conntrack-Limit. Zu prüfen sind der Systemkernel, der Netzwerk-Namespace und der Datenverkehr der Anwendung. Nach der Zahlung finden Sie die Zugangsdaten im Verwaltungsportal und können sich per SSH verbinden; bei mehreren Adressen verwenden Sie die erste.

Führen Sie die Befehle in dem Netzwerk-Namespace aus, der den Datenverkehr tatsächlich verarbeitet. Ergebnisse auf dem Host sagen nichts über den Zustand eines Gastsystems aus. Durchläuft Containerverkehr die Adressübersetzung auf dem Host, muss auch der Host geprüft werden. Halten Sie zunächst Kernelversion, aktuellen Netzwerk-Namespace, Anzahl der Einträge und deren Obergrenze fest:

uname -r
readlink /proc/self/ns/net
sudo sysctl net.netfilter.nf_conntrack_count
sudo sysctl net.netfilter.nf_conntrack_max
sudo sysctl net.netfilter.nf_conntrack_buckets

Fehlt ein Schlüssel, wird der entsprechende Parameter im aktuellen Namespace nicht bereitgestellt. Daraus lässt sich nicht unmittelbar auf eine erschöpfte Tabelle schließen. Prüfen Sie zunächst, ob die betreffenden Module geladen sind und ob der Anwendungsverkehr die Verbindungsverfolgung nutzt. Aktivieren Sie während einer Störung keine neuen Funktionen, nur um die Ausgabe zu vervollständigen.

Führen Sie conntrack -F nicht aus. Das Leeren der Tabelle löscht die Verfolgungszustände, kann bestehende Sitzungen und Zuordnungen der Adressübersetzung beeinträchtigen und beseitigt zugleich die für die Diagnose benötigten Daten.

2. Mit Zählerdifferenzen eine belastbare Beweiskette aufbauen

Die Installation der Userspace-Werkzeuge verändert keine bestehenden Regeln, sollte aber dem geltenden Änderungsverfahren folgen. Die folgenden Schritte lesen den aktuellen Zustand aus und zeigen anhand zweier zeitlich versetzter Stichproben, ob die Zähler weiter steigen:

sudo apt-get install conntrack
umask 077
sudo conntrack -S > /tmp/conntrack-before.txt
sudo journalctl -k --since "-10 min" --no-pager \
  | grep -Ei 'nf_conntrack|table full'
sleep 30
sudo conntrack -S > /tmp/conntrack-after.txt
diff -u /tmp/conntrack-before.txt /tmp/conntrack-after.txt

conntrack -S gibt üblicherweise kumulierte Zähler je CPU aus. Vergleichen Sie jeweils die Zeilen derselben CPU und achten Sie auf den Zuwachs bei insert_failed, drop und early_drop, statt die seit dem Systemstart aufgelaufenen Werte der aktuellen Störung zuzuschreiben. Bedeutung und Ausgabefelder der Zähler können sich je nach Kernel unterscheiden. Nicht jeder fehlgeschlagene Einfügeversuch ist auf mangelnde Kapazität zurückzuführen.

Erfassen Sie gleichzeitig die Anzahl der Anwendungs-Timeouts, die Tabellenbelegung und die Kernelmeldungen. Erst wenn die Belegung nahe am Limit liegt, die Fehlerzähler steigen und zeitgleich Anwendungsfehler auftreten, ergibt sich eine weitgehend vollständige Beweiskette. Auch ohne passende Protokollmeldungen ist ein Problem nicht ausgeschlossen, da die Ausgabe von Meldungen einer Ratenbegrenzung unterliegen kann. Kurze Spitzen zwischen den Messungen können unentdeckt bleiben. Verkürzen Sie bei Bedarf das Beobachtungsintervall, exportieren Sie aber nicht in einer Schleife die gesamte Tabelle.

3. Verbindungsanzahl und Rate neuer Verbindungen unterscheiden

Anhand einer Stichprobe klären, warum sich Einträge ansammeln

Die Anzahl der Einträge entspricht nicht der Zahl der aktuellen Anfragen. Eine TCP-Verbindung kann mehrere Anfragen transportieren, und auch UDP belegt Einträge in der Verbindungstabelle. Nach Ende der Kommunikation können Einträge bis zum Ablauf des jeweiligen Timeouts bestehen bleiben. Deshalb muss zwischen dauerhaft stabilen Verbindungen, einem sprunghaften Anstieg kurzlebiger Verbindungen und auffälligen Verkehrsquellen unterschieden werden.

Eine einmalige, begrenzte Stichprobe vermeidet es, unter hoher Last wiederholt die vollständige Verbindungstabelle auszugeben:

sudo timeout 5s conntrack -L -o extended 2>/tmp/conntrack-sample.err \
  | head -n 200 > /tmp/conntrack-sample.txt

Dieser Befehl erfasst nur eine begrenzte Ausgabe, kann vorzeitig enden und einen Exit-Status ungleich null liefern. Die Stichprobe ist keine vollständige Statistik. Die Datei enthält Adressinformationen; beschränken Sie die Leserechte und anonymisieren Sie Anhänge für Supporttickets bei Bedarf. Die Ausgabe enthält Tupel für die ursprüngliche Richtung und die Antwortrichtung. Vermischen Sie bei der Analyse der Quellen nicht die Adressen beider Gruppen.

Prüfen Sie Protokoll, TCP-Zustand, verbleibenden Timeout und Quelle in der ursprünglichen Richtung. Bei vielen kurzlebigen Verbindungen sollten Sie den Verbindungspool der Anwendung und die Wiederholungsprotokolle einbeziehen. Erzeugen wenige Quellen fortlaufend neue Flows, gleichen Sie dies mit den Zugriffsprotokollen ab. Sammeln sich UDP-Einträge über längere Zeit an, prüfen Sie den tatsächlichen Kommunikationszyklus. Ein einzelner Zustandsname reicht nicht aus, um einen Angriff festzustellen. Auffälliger Datenverkehr sollte auch nicht einfach als Kapazitätsproblem dargestellt werden.

Sinkt die Rate neuer Verbindungen nicht, verschiebt eine größere Tabelle lediglich den Zeitpunkt, an dem das Limit erneut erreicht wird. Das Beheben unbegrenzter Wiederholungsversuche, die Wiederherstellung der Verbindungswiederverwendung oder der Umgang mit auffälligen Quellen müssen häufig unabhängig von der Kapazitätsanpassung auf ihren Erfolg geprüft werden.

4. Nach der Speicherprüfung nur einen Parameter ändern

Das Limit ist weder vorab reservierter Speicher noch eine Durchsatzzusage

Eine Erhöhung von nf_conntrack_max legt nicht sofort sämtliche Einträge an. Eine sich weiter füllende Tabelle verbraucht jedoch Kernelspeicher. Beobachten Sie Speicher und Slab mit free -h, /proc/meminfo und sudo slabtop -o. Die Größe der Objekte im Slab-Cache deckt nicht alle Kosten ab, etwa zusätzliche Felder und den Verwaltungsaufwand der Speicherzuweisung. Eine feste Formel nach dem Muster „so viele Bytes pro Verbindung“ ist daher nicht geeignet.

nf_conntrack_buckets bezeichnet die Anzahl der Hash-Buckets, nicht die Verbindungskapazität. Wird nur das Limit erhöht, können die Ketten in den Buckets länger und die Suchkosten höher werden. Beobachten Sie deshalb zugleich CPU-Auslastung und Anwendungslatenz. Ob sich die Bucket-Anzahl im laufenden Betrieb ändern lässt, hängt von Kernel und Namespace ab; bei dieser Änderung wird sie nicht mit angepasst.

Das folgende Beispiel zeigt ausschließlich eine temporäre Änderung auf den Zielwert 262144. Stellen Sie vor der Ausführung sicher, dass dieser Wert über dem aktuellen liegt, das Speicherbudget ihn zulässt und eine weitere Administrationssitzung verfügbar ist. Er ist keine allgemeine Empfehlung für alle Maschinen. Die Befehle werden in einer Shell mit administrativen Rechten ausgeführt:

sudo -i
OLD=$(sysctl -n net.netfilter.nf_conntrack_max)
test "$OLD" -lt 262144 || exit 1
umask 077
printf '%s\n' "$OLD" > /run/conntrack-max.before
sysctl -w net.netfilter.nf_conntrack_max=262144
sysctl -n net.netfilter.nf_conntrack_max

Wiederholen Sie nach dem Sichern des ursprünglichen Werts dieselben Anwendungstests und Zählermessungen. Verkürzen Sie nicht gleichzeitig den Timeout für TCP established: Langlebige Verbindungen können trotz Inaktivität weiterhin von der Anwendung genutzt werden. Eine globale Verkürzung des Timeouts würde eine neue Ursache für Verbindungsabbrüche schaffen.

5. Prüfung, Rollback und dauerhafte Konfiguration getrennt durchführen

Die Prüfung muss mindestens den ursprünglich betroffenen Datenverkehr sowie langlebige Verbindungen abdecken, die nach einer Leerlaufphase wieder kommunizieren. Prüfen Sie die Erfolgsquote neuer Verbindungen, den Zuwachs der Fehlerzähler, die Entwicklung der Tabellenbelegung, die Speicherreserve, die CPU-Auslastung und die Anwendungslatenz. Ein höheres Limit allein belegt keine Lösung des Problems.

Nehmen Speicherdruck, CPU-Auslastung oder Latenz zu, setzen Sie den gespeicherten Wert wieder:

sudo sysctl -w \
  net.netfilter.nf_conntrack_max="$(sudo cat /run/conntrack-max.before)"

Das Senken des Limits entfernt vorhandene Einträge nicht sofort. Liegt die Belegung weiterhin über der wiederhergestellten Obergrenze, kann das Anlegen neuer Einträge weiter behindert sein. Warten Sie, bis Einträge regulär auslaufen, und kümmern Sie sich um die Verkehrsquellen. Leeren Sie die Tabelle nicht, um die Wiederherstellung zu beschleunigen.

Nach erfolgreicher Prüfung der temporären Änderung kontrollieren Sie zunächst, ob /etc/sysctl.conf und /etc/sysctl.d/ bereits eine Einstellung desselben Namens enthalten. So vermeiden Sie, dass mehrere Dateien einander überschreiben. Schreiben Sie den geprüften Wert in eine eigene, versionierte Konfigurationsdatei, beispielsweise:

net.netfilter.nf_conntrack_max = 262144

Laden Sie nur diese Datei und prüfen Sie den tatsächlich gesetzten Wert erneut. Laden Sie während der Störung nicht pauschal unbeteiligte Parameter neu. Bei einem späteren kontrollierten Neustart sollte zudem der endgültige Wert nach dem Laden der Module geprüft werden: Ein Eintrag in einer Datei garantiert nicht, dass er beim Systemstart wirksam wird.

Die abschließende Dokumentation sollte Verkehrsquellen, Zählerstände vor und nach der Änderung, Anwendungstests, Speicherbeobachtungen, den ursprünglichen Wert und die Schritte zur Wiederherstellung enthalten. Das Kapazitätsmanagement für conntrack ist abgeschlossen, wenn die Belege die Störung erklären und das Ergebnis der Anpassung reproduzierbar ist — nicht, wenn die Obergrenze lediglich eine größere Zahl zeigt.

Häufig gestellte Fragen

Beweist eine fast volle Conntrack-Tabelle die Ursache des Paketverlusts?

Nein. Der Zuwachs bei insert_failed, drop oder early_drop muss mit Kernelmeldungen und Anwendungsfehlern im selben Zeitraum abgeglichen werden. Hohe Belegung allein zeigt nur Kapazitätsdruck.

Müssen TCP-Zeitlimits mit nf_conntrack_max geändert werden?

Nein. Zunächst bleiben die Protokollzeitlimits unverändert; nur das durch das Speicherbudget gedeckte Tabellenlimit wird geprüft. Ein kürzeres globales TCP-established-Zeitlimit kann ruhende Dauerverbindungen stören.

Dedizierter Server mit AMD EPYC 7543P ab $447/Monat.

Dedicated-Server-Konfiguration: Arbeitsspeicher wählen

AMD EPYC 7543P mit 128 GB oder 256 GB DDR4-3200 ECC.