Neue Verbindungen scheitern: Ist die Conntrack-Tabelle voll?
Die Anwendungsprozesse laufen normal und bestehende langlebige Verbindungen übertragen weiterhin Daten, doch neue Anfragen laufen sporadisch in einen Timeout. Das muss nicht an der Listen-Queue der Anwendung liegen. Übernimmt ein Dedicated Server die Aufgaben einer zustandsbehafteten Firewall oder die Netzwerkadressübersetzung (NAT), kann auch die Verbindungstabelle von Linux zum Engpass werden. Entscheidend ist, den Zeitpunkt der Fehler mit der Tabellenbelegung und den Kernel-Zählern abzugleichen, statt allein wegen vieler Verbindungen das Limit anzuheben.
Dieser Artikel verwendet Debian 13 als Beispiel. Alle Prüfungen erfolgen im Netzwerk-Namespace des Hosts. Bei CloudUDP sind die Zugangsdaten nach der Zahlung in der Konsole abrufbar; der Zugriff auf Linux erfolgt über SSH. Sind mehrere Adressen vorhanden, verwenden Sie die erste für die Verbindung. Die folgenden Schritte ändern keine Netzwerkregeln und löschen keine bestehenden Verbindungszustände.
1. Prüfen, ob der betroffene Verkehr die Verbindungsverfolgung durchläuft
Die Verbindungsverfolgung (conntrack) erfasst Protokoll, Adressen, Zustand und Timeout von Datenströmen. Diese Informationen dienen zustandsbasierten Regeln und NAT. Eine Anwendungsverbindung entspricht nicht einem Anwendungsthread. Einträge können zudem noch eine Weile erhalten bleiben, nachdem die Anwendung die Verbindung geschlossen hat. Viele kurzlebige Verbindungen in schneller Folge, ungewöhnliche Scan-Aktivitäten oder weitergeleiteter Verkehr können die Belegung erhöhen.
Installieren Sie zunächst das Prüfwerkzeug und lesen Sie die Konfiguration aus:
sudo apt-get update
sudo apt-get install conntrack
sysctl net.netfilter.nf_conntrack_count
sysctl net.netfilter.nf_conntrack_max
sudo conntrack -S
sudo nft list ruleset
ct state oder NAT in den Regeln sind Hinweise darauf, dass die Tracking-Kapazität relevant ist. Fehlen solche Regeln, beweist das jedoch nicht, dass keine Verbindungsverfolgung stattfindet. Wird beim Auslesen ein Parameter als nicht vorhanden gemeldet, prüfen Sie zuerst die Module und den tatsächlichen Verkehrsweg. Laden Sie keine Module auf Verdacht, nur um eine „vollständige Ausgabe“ zu erhalten.
Ergebnisse aus einem Container ersetzen nicht die Ergebnisse des Hosts. Weitergeleiteter Verkehr auf dem Host und Verkehr innerhalb eines Containers können unterschiedliche Namespaces durchlaufen. Dokumentieren Sie deshalb, wo die Befehle ausgeführt wurden. Andernfalls kann eine niedrige Belegung im Container fälschlich zur Erklärung von Paketverlusten auf dem Host herangezogen werden.
Verwenden Sie
conntrack -Fnicht als routinemäßige Wiederherstellungsmaßnahme. Das Leeren der Tabelle entfernt bestehende Zustände, kann Sitzungen unterbrechen, die auf zustandsbasierten Regeln oder NAT beruhen, und vernichtet zugleich Befunde, die für die Diagnose erhalten bleiben sollten.
2. Belegung und Fehlerzuwachs im selben Zeitraum erfassen
nf_conntrack_count gibt die aktuelle Anzahl der Einträge an, nf_conntrack_max die Kapazitätsgrenze. Eine Belegung nahe am Limit bedeutet weniger Reserve, beweist für sich genommen aber nicht, dass Anfragen deshalb scheitern. conntrack -S gibt Statistiken pro Prozessor aus. Summieren Sie jeden Zähler über alle Prozessoren und vergleichen Sie anschließend die Differenzen zwischen zwei Messungen. Eine einzelne Zeile ist nicht die Summe für den gesamten Server.
umask 077
out=$(mktemp -d /var/tmp/ct-check.XXXXXX)
for sample in 1 2; do
{
date -Is
sysctl net.netfilter.nf_conntrack_count
sysctl net.netfilter.nf_conntrack_max
sudo conntrack -S
} > "$out/sample-$sample.txt"
if [ "$sample" -eq 1 ]; then
sleep 10
fi
done
sudo journalctl -k --since "-10 min" --no-pager \
> "$out/kernel.txt"
printf '%s\n' "$out"
Das Messintervall dient hier nur als Beispiel. Die Messungen müssen den Zeitraum abdecken, in dem die Anwendungsfehler auftreten. Achten Sie insbesondere darauf, ob insert_failed, drop und early_drop fortlaufend steigen und ob der Kernel eine volle Verbindungstabelle meldet. Die verfügbaren Felder können je nach Kernel-Version variieren. Ein fehlendes Feld ist kein Beleg dafür, dass das System fehlerfrei arbeitet.
Speichern Sie gleichzeitig die Anzahl fehlgeschlagener neuer Verbindungen der Anwendung, das Anfragevolumen und die ursprünglichen Fehlermeldungen. Nach einem Neustart hat sich die Bezugsbasis der kumulierten Zähler geändert; Werte vor und nach dem Neustart dürfen daher nicht direkt voneinander abgezogen werden. Dass Fehlerzähler bei geringer Last nicht weiter steigen, bestätigt außerdem noch nicht, dass die Kapazität auch für Spitzenlast ausreicht.
3. Ermitteln, warum sich Einträge ansammeln
Unterscheiden Sie zunächst zwischen einem normalen Anstieg gleichzeitiger Verbindungen und einer ungewöhnlich hohen Rate neu angelegter Verbindungen. Vergleichen Sie eingehende Anfragen, aktiv von der Anwendung aufgebaute ausgehende Verbindungen, weitergeleiteten Verkehr und die Wiederverwendung von Verbindungen. Selbst kurzlebige Verbindungen können sich bei hoher Erstellungsrate ansammeln. Bei langlebigen Verbindungen ist dagegen vor allem die tatsächliche Anzahl gleichzeitig bestehender Verbindungen maßgeblich.
Nicht mit einem vollständigen Tabellendump beginnen
Auf einem stark ausgelasteten Host verursacht bereits das vollständige Auflisten der Einträge zusätzlichen Diagnoseaufwand. Außerdem enthält die Ausgabe Kommunikationsadressen. Lesen Sie zuerst die zusammengefassten Zähler aus. Falls weitere Details tatsächlich nötig sind, begrenzen Sie Protokoll und Ausgabeumfang:
sudo timeout 5s conntrack -L -p tcp -o extended 2>/dev/null \
| head -n 100
Diese Ausgabe ist lediglich eine verzerrte Stichprobe, keine Statistik zur Verteilung der Zustände. Ein Timeout oder das vorzeitige Schließen der Pipe kann außerdem dazu führen, dass der Befehl mit einem Rückgabecode ungleich null endet. Daraus lässt sich keine beschädigte Tabelle ableiten. Speichern Sie Adressdaten nur in einem Verzeichnis mit eingeschränkten Zugriffsrechten und entfernen Sie vor dem Einreichen eines Support-Tickets Informationen zu nicht betroffenen Anwendungen.
Prüfen Sie parallel die lauschenden Prozesse, Anwendungsfehler und Antworten vorgelagerter Dienste. Sind noch Kapazitätsreserven vorhanden und steigen die relevanten Zähler nicht, untersuchen Sie blockierte Anwendungen, Routing oder andere Stellen mit Paketverlusten. Weitere Anpassungen an conntrack sind dann nicht der richtige nächste Schritt.
Verkürzen Sie nicht als erste Maßnahme die Timeouts aller Protokolle. Timeouts bestimmen, wie lange der Zustand inaktiver Verbindungen erhalten bleibt. Zu kurze Werte können langlebige Verbindungen beeinträchtigen. Probleme wie nicht wiederverwendete Verbindungen im Connection-Pool oder unkontrollierte Wiederholungsversuche nach Fehlern müssen auf der aufrufenden Seite behoben werden.
4. Rücknehmbare Änderungen innerhalb des Speicherbudgets vornehmen
Ein höheres Limit erlaubt lediglich mehr Tabelleneinträge; es beseitigt nicht die Ursache ungewöhnlichen Verkehrs. Die Einträge beanspruchen Kernel-Speicher. Der tatsächliche Bedarf hängt unter anderem von Protokollerweiterungen und der Kernel-Konfiguration ab. Ein fester Wert von „so vielen Bytes pro Eintrag“ erlaubt deshalb keine exakte Budgetberechnung.
Erfassen Sie vor der Änderung free -h und /proc/meminfo und prüfen Sie mit sudo slabtop -o die Kernel-Objekt-Caches. Slab ist der Cache-Mechanismus des Kernels zur Verwaltung von Objekten. Auch die dort angezeigten Statistiken zu Conntrack-Objekten bilden nicht den gesamten zugehörigen Speicherbedarf ab.
Deuten die Befunde auf zu wenig Kapazität hin und ist ausreichend Speicherreserve vorhanden, lässt sich die Annahme mit einer kleinen Anpassung prüfen. Das folgende Beispiel erhöht das bisherige Limit um ein Viertel. Dieser Schritt dient nur dem Versuch und ist keine pauschale Konfigurationsempfehlung:
old=$(sysctl -n net.netfilter.nf_conntrack_max) || exit 1
case "$old" in
''|*[!0-9]*) exit 1 ;;
esac
new=$((old + old / 4))
printf 'old=%s new=%s\n' "$old" "$new"
sudo sysctl -w net.netfilter.nf_conntrack_max="$new"
Lassen Sie diese Sitzung geöffnet und bewahren Sie den ursprünglichen Wert auf. Wiederholen Sie die Messungen bei vergleichbarem Anfragevolumen. Verbessert sich die Fehlersituation nicht, erhöhen Sie den Parameter nicht immer weiter. Stellen Sie den ursprünglichen Wert wieder her und prüfen Sie andere Befunde:
sudo sysctl -w net.netfilter.nf_conntrack_max="$old"
Kontrollieren Sie vor dem Zurücksetzen die aktuelle Belegung. Liegt sie bereits über dem ursprünglichen Limit, reduzieren Sie zuerst den Druck durch neue Verbindungen. Andernfalls kann das Zurücksetzen erneut einen Kapazitätsengpass auslösen. Ändern Sie nicht gleichzeitig Hash-Buckets, Protokoll-Timeouts und Firewall-Regeln, damit die Wirkung einer einzelnen Änderung überprüfbar bleibt.
5. Anhand der Anwendungsergebnisse über die dauerhafte Konfiguration entscheiden
Für die erfolgreiche Prüfung müssen drei Arten von Nachweisen zusammenkommen: Bei vergleichbarem Anfragevolumen hat sich die Erfolgsquote neuer Verbindungen erholt, die relevanten Fehlerzähler steigen nicht mehr fortlaufend, und es entsteht kein neuer Druck auf Speicher und Kernel-Objekt-Caches. Eine niedrigere prozentuale Tabellenbelegung allein bedeutet noch nicht, dass das Problem behoben ist.
Ist die Wirkung bestätigt, tragen Sie den geprüften Zahlenwert in /etc/sysctl.d/90-conntrack-capacity.conf ein. Prüfen Sie zuvor, ob andere Konfigurationsdateien denselben Parameter definieren, damit die Ladereihenfolge den Wert nicht überschreibt. Laden Sie nur diese Datei, ohne dabei weitere ungeprüfte Einstellungen des gesamten Servers anzuwenden:
sudo sysctl -p /etc/sysctl.d/90-conntrack-capacity.conf
sysctl net.netfilter.nf_conntrack_max
Die Datei muss eine Zeile nach dem Muster net.netfilter.nf_conntrack_max = geprüfte Ganzzahl enthalten. Ersetzen Sie den erklärenden Platzhalter durch die tatsächliche Zahl. Prüfen Sie nach dem nächsten vom Betrieb geplanten Neustart erneut den wirksamen Wert und mögliche Ladefehler. Starten Sie einen Produktionsserver nicht sofort neu, nur um den Parameter zu überprüfen.
Bewahren Sie abschließend den ursprünglichen und den neuen Wert, den Messzeitraum, das Anfragevolumen, die Zählerdifferenzen und die Bedingungen für ein Zurücksetzen auf. Das Ziel der Conntrack-Kapazitätsplanung ist nicht eine größere Zahl. Es geht darum, Verbindungsfehler erklären zu können, die Wirksamkeit der Änderung nachzuweisen und bei veränderter Last dieselben Befunde erneut zu prüfen.
Häufig gestellte Fragen
Beweist eine fast volle Conntrack-Tabelle bereits einen Engpass?
Nein. Änderungen von insert_failed, drop und early_drop müssen mit Kernelmeldungen und fehlgeschlagenen neuen Verbindungen im gleichen Zeitraum abgeglichen werden. Hohe Belegung ist ein Risikosignal; auch ein einzelner Zähler beweist die Ursache nicht.
Sollte die Conntrack-Tabelle zur schnellen Wiederherstellung geleert werden?
Nicht als Standardmaßnahme. Das Leeren entfernt Zustände bestehender Verbindungen und kann Sitzungen mit zustandsabhängigen Regeln oder NAT unterbrechen. Zuerst Zähler und Meldungen sichern, dann auffällige Verbindungsquellen behandeln oder die Kapazität mit Speicherbudget anpassen.
Dedizierter EPYC 7543P Server ab $454/Monat