TCP SYN Cookies im Linux-Kernel halten die Handshake-Last gering, indem sie Zustandsinformationen kryptografisch in die Initial Sequence Number codieren und erst bei einem gültigen ACK eine Verbindung vollständig anlegen. So verhindere ich, dass SYN-Floods die Warteschlange halboffener Verbindungen verstopfen und legitime Clients blockieren.
Zentrale Punkte
- Funktionsweise: Cookie im ISN, Zustand erst nach ACK
- Linux-Steuerung: net.ipv4.tcp_syncookies mit Modi 0/1/2
- Nutzen: geringer Speicherbedarf bei Angriffslast
- Grenzen: hilft nicht gegen Bandbreiten- oder App-Angriffe
- Tuning: Backlog- und Retry-Werte sorgfältig setzen
Wie SYN-Floods den TCP-Handshake ausbremsen
Ein Angreifer überhäuft den Server mit SYN-Paketen und ignoriert die folgenden SYN/ACK-Antworten, wodurch halboffene Einträge die Syn-Queue belegen. Ich erlebe dann, dass neue, legitime Anfragen keinen Platz finden und Zeitüberschreitungen häufen. Genau hier setzen Syncookies an: Der Kernel speichert vorerst keinen Verbindungszustand und verlagert benötigte Daten in die Sequenznummer. Erst ein korrektes ACK beweist eine echte Gegenstelle, sodass der Aufbau regulär weiterläuft. LWN.net und die TUM-Unterlagen beschreiben dieses Prinzip als etablierten, effektiven Handshake-Schutz ohne hohen Speicherverbrauch. Diese Architektur hält den Server auch unter Flutverkehr aufnahmefähig, weil er teure Zustände erst sehr spät anlegt.
Technischer Ablauf: Cookie statt früher Zustandsanlage
Der Kernel antwortet auf ein SYN mit einem speziell codierten SYN/ACK, dessen ISN aus einem geheimen Schlüssel, TCP-Optionen und Zeitscheiben abgeleitet ist. Trifft ein ACK mit der passenden Nummer ein, rekonstruiere ich aus der ISN die Session-Parameter und öffne den Socket normal. Bleibt die Antwort aus, existiert auch kein belegter halboffener Zustand, was Speicher und CPU schont. Dieser Ansatz senkt die Anfälligkeit der Annahmephase drastisch, ohne den regulären Pfad dauerhaft zu verändern. Laut Ubuntu- und Red-Hat-Dokumenten arbeitet die Technik seit vielen Kernel-Generationen verlässlich und greift erst, wenn die Warteschlange zu kippen droht.
Aktivieren und prüfen: tcp_syncookies in der Praxis
Über den Sysctl-Schalter net.ipv4.tcp_syncookies steuere ich das Verhalten: 0 = aus, 1 = nur bei Überlast, 2 = dauerhaft. In produktiven Umgebungen setze ich meist den Modus 1, damit der Standard-Handshake intakt bleibt und Schutz erst bei Bedarf einsetzt. Den Status sehe ich auf der Shell schnell ein, Änderungen übernehme ich per sysctl oder dauerhaft in /etc/sysctl.d/. Ein passender Hintergrundartikel zu Socket-Verhalten und Angriffsmustern unterstützt beim Planen des Ganzen; Details vertiefe ich im Beitrag SYN-Flood-Schutz. Die folgenden Befehle nutze ich regelmäßig:
# Status anzeigen
sysctl net.ipv4.tcp_syncookies
# temporär aktivieren (bis Neustart)
sudo sysctl -w net.ipv4.tcp_syncookies=1
# dauerhaft setzen
echo "net.ipv4.tcp_syncookies = 1" | sudo tee /etc/sysctl.d/60-syncookies.conf
sudo sysctl --system
Grenzen: Was SYN Cookies nicht leisten
SYN Cookies adressieren vor allem die Syn-Queue und verhindern, dass halboffene Zustände Speicher binden. Gegen eine überlastete Leitung, überforderte Applikationslogik oder CPU-Sättigung wirken sie allerdings nicht. Bei volumetrischen Attacken brauche ich vorgelagerte Filter, QoS und gegebenenfalls Scrubbing. Auch Anwendungsebene-Angriffe wie HTTP-GET-Fluten erfordern zusätzliche Kontrollen, Limits und Caches. Ich ordne Syncookies daher immer in eine mehrstufige Verteidigung ein, die Netzwerk, Kernel und Dienstebene zusammenführt.
Tuning: Backlogs, Warteschlangen und Retries
Vor dem Ernstfall stimmen ich Backlogs und Retries ab, damit legitime Spitzen den Schutzmodus nicht unnötig auslösen. tcp_max_syn_backlog beeinflusst die Queue halboffener Verbindungen, somaxconn die maximale Länge der Annahmeschlange für accept()-Wartende. Mit tcp_synack_retries bestimme ich, wie oft der Kernel auf SYN/ACK ein Wiederholen versucht, bevor er aufgibt. Höhere Backlogs fangen kurze Lastspitzen, kosten aber Speicher; geringere Retries befreien Slots früher, bergen jedoch das Risiko, entfernte Clients zu hart zu treffen. Diese Kompromisse teste ich unter realistischer Last mit Werkzeugen wie hping3 oder tcp_syn_flooder in einem isolierten Netz.
# Kandidaten für Lastspitzen
sudo sysctl -w net.core.somaxconn=4096
sudo sysctl -w net.ipv4.tcp_max_syn_backlog=8192
sudo sysctl -w net.ipv4.tcp_synack_retries=3
Betriebsarten vergleichen: Auswirkungen und Einsatz
Für den Alltag wähle ich die Modi bewusst, denn sie beeinflussen Diagnose, Metriken und Verhalten unter Druck. Dauerhafte Cookies (2) vermeiden jede frühe Zustandsanlage, verändern jedoch Messwerte für Retries und können seltene Edge-Cases mit TCP-Optionen beeinflussen. Der adaptive Modus (1) lässt den Stack normal laufen und greift bei drohendem Overrun ein. Aus bleibt (0) höchstens in Laborsituationen oder geschlossenen Netzen sinnvoll. Die folgende Tabelle fasst das kompakt zusammen:
| Modus | Beschreibung | Vorteil | Potenzielle Nebenwirkung | Beispiel |
|---|---|---|---|---|
| 0 | Deaktiviert, keine Cookies | Klares Baseline-Verhalten | Angreifer füllt Syn-Queue | Isoliertes Testnetz |
| 1 | Adaptiv, nur bei Überlauf | Normales TCP bei Ruhe | Umschaltpunkt kalibrieren | Öffentliche Dienste |
| 2 | Erzwungen, immer aktiv | Frühe Entlastung | Analysewerte verschieben sich | Harte Angriffslage |
Messbare Effekte: Latenzen und Erfolgsquote
Unter Druck sinkt der Speicherbedarf pro Verbindungseintritt deutlich, weil kein halboffener Zustand entsteht. Dadurch halten SYN Cookies die Annahmerate hoch, und kurze Bursts verursachen weniger Abbrüche. Ich beobachte unter Flutverkehr schnellere Erholung, sobald die Quelle versiegt. Ubuntu- und Tenable-Richtlinien raten zum adaptiven Einsatz, damit normale Clients unverändert agieren. Für Regressionstests prüfe ich Retransmits, Drop-Raten und die Server-Latenz beim Übergang in den Cookie-Modus.
Zusätzliche Schutzschichten: Firewall und Limits
Syncookies löse ich mit Filterregeln und Rate Limits ab, damit die Last gar nicht erst in den TCP-Stack drückt. Auf Linux setze ich bevorzugt nftables-Regeln, um Offender anhand von Verbindungsraten zu drosseln oder früh zu verwerfen. Einen kompakten Überblick über moderne Paketfilter bietet der Leitfaden nftables vs. Netfilter. Ergänzend helfen SYNPROXY-Szenarien an Edge-Firewalls, die den Handshake terminieren und nur valide Verbindungen weitergeben. Für exponierte Ports definiere ich strikte Öffnungen, Logging-Schwellen und maximale Verbindungsversuche pro Quelladresse.
High-Performance-Ansätze: XDP und Co.
Wenn Volumenangriffe die PPS-Rate hochtreiben, verlagere ich Filterlogik per XDP an den Netzwerkrand der NIC. So verwerfe ich verdächtige SYNs noch vor dem Socket-Layer, was CPU-Last spart und die Annahmeschlange entlastet. Den Einstieg in diese Technik erleichtert eine Einführung zur XDP-Paketverarbeitung. In Zusammenspiel mit SYN Cookies entsteht ein zweistufiges System: erst grobe Selektion an der Karte, dann verlässliche Handshake-Prüfung im Kernel. Diese Kette reduziert die Angriffsfläche spürbar und hält Dienste zugänglich.
Diagnose: Metriken und Log-Hinweise richtig lesen
Bei auffälligen Timeouts prüfe ich netstat/ss-Statistiken, dmesg-Hinweise und Grafana-Panels mit Verbindungsraten. Ein steigender Anteil SYN-RECV, hohe Retransmits und Drops zeigen den Wechsel in den Schutzmodus an. Ich achte auf syn backlog overflow-Meldungen und korreliere sie mit CPU- und IRQ-Last. Packet-Captures mit tcpdump belegen die Sequenznummern-Logik und helfen, falsche Positive zu erkennen. Mit iptables/nftables-Countern messe ich zusätzlich die Treffersituation an Rate-Limit-Regeln.
Kompatibilität: TCP-Optionen und Edge-Cases
Moderne Kernel codieren Optionen wie MSS, SACK oder Timestamp so, dass Cookies sie rekonstruktionsfähig transportieren. Ältere oder exotische Stacks können Eigenheiten zeigen, daher prüfe ich kritische Pfade vor dem Rollout. Besonders bei Proxies, NAT und Anycast-Topologien beobachte ich das Verhalten gründlich. LWN.net diskutiert Design-Details, die erklären, warum heutige Implementierungen verlässlich agieren. In sehr speziellen Szenarien bleibt die erzwungene Betriebsart (2) ein Werkzeug, das ich nur gezielt einsetze.
Typische Fehlannahmen: Was ich oft korrigiere
Syncookies ersetzen keine DDoS-Abwehr an der Peripherie, sie schützen vor allem die Handshake-Phase. Eine hohe somaxconn-Zahl allein verhindert keine Überläufe, wenn SYN/ACK nie beantwortet wird. Ebenso trügt die Annahme, dass dauerhafte Cookies (2) immer die beste Wahl seien; Diagnosen und Sonderfälle leiden darunter. Ohne Monitoring fehlen mir Signale, um Umschaltpunkte und Limits zu justieren. Lasttests bleiben unverzichtbar, damit Konfiguration und Hardware zur realen Zugriffsdynamik passen.
Praxis-Check: Schritte zur belastbaren Annahme
Ich starte mit Modus 1 für tcp_syncookies und verifiziere den Eingriffspunkt unter Last. Danach erhöhe ich tcp_max_syn_backlog und somaxconn moderat, während ich tcp_synack_retries absenke und Erfolgsquoten messe. Firewall-Rate-Limits und Geo-/ASN-Filter sortieren Lärm vor dem Stack aus. XDP oder SmartNIC-Filter spare ich mir für hohe PPS-Lagen auf, damit ich Ressourcen zielgerichtet einsetze. Abschließend dokumentiere ich die Metriken, damit spätere Anpassungen auf Daten beruhen.
IPv6 und Dual-Stack: gleicher Schalter, gleiche Logik
In Dual-Stack-Umgebungen verhalten sich IPv4 und IPv6 im Kontext der Cookies konsistent. Der Schalter net.ipv4.tcp_syncookies steuert den Schutz global für TCP, also auch für v6-Sockets. Ich teste den Übergang in den Cookie-Modus deshalb auf beiden Protokollen – besonders, wenn Upstream-Geräte in IPv6 andere Filterpfade nutzen. Wichtig: SYN Cookies schützen ausschließlich TCP. UDP-Dienste oder QUIC erfordern eigene Rate-Limits und Edge-Policy, damit volumetrischer Verkehr nicht die CPU erschöpft.
Metriken im Kernel: belastbare Indikatoren
Für verlässliches Monitoring ziehe ich Kernel-Zähler heran, die Cookies explizit ausweisen. Neben ss -s und Zustandsverteilungen beobachte ich die Zähler für gesendete, angenommene und fehlgeschlagene Cookies. So erkenne ich, ob der Schutz greift, ob legitime Clients durchkommen und ob Fehlkonfigurationen vorliegen.
# Überblick
ss -s
ss -ant state syn-recv | wc -l
# Cookie-Zähler (Kernel: /proc/net/netstat)
grep -E 'Syncookies|ListenOverflows|ListenDrops' /proc/net/netstat
# Live-Ansicht
watch -n1 'grep -E "Syncookies(Sent|Recv|Failed)|Listen(Overflows|Drops)" /proc/net/netstat'
# Log-Hinweise (Beispielmeldung)
# dmesg zeigt u.a.:
# TCP: Possible SYN flooding on port 443. Sending cookies. Check SNMP counters.
Steigen ListenOverflows und ListenDrops parallel zu SyncookiesSent an, justiere ich Backlogs, Retries und Upstream-Filter. Bleiben SyncookiesRecv aus, deutet das auf reine Bot-Fluten hin; häufen sich dagegen SyncookiesFailed, prüfe ich NAT/Proxy-Pfade und mögliche Manipulationen unterwegs.
Proxies, Load-Balancer und Kubernetes
In Proxy- und LB-Ketten entscheidet die Platzierung des Cookie-Schutzes. Terminiert ein L4-/L7-Load-Balancer den TCP-Handshake, erreicht eine SYN-Flut die Backends gar nicht; Cookies aktiviere ich dann am Edge. Arbeitet der LB nur passiv (DSR, ECMP), müssen Backend-Knoten eigenständig schützen. In Kubernetes stimme ich sysctls auf den Worker-Nodes ab, insbesondere bei NodePort- oder HostNetwork-Workloads. Für Ingress-Controller mit eigener SYN-Abwehr (SYNPROXY, eBPF) reguliere ich die Policies so, dass sie sich nicht gegenseitig ausbremsen. Health-Checks des LBs berücksichtige ich in Tests, da kurze Probe-Fenster mit niedrigen Retries sonst fälschlich für Instabilität sorgen.
Grenzfälle im Detail: Optionen, Zeitscheiben, NAT
Cookies kodieren nur begrenzte Parameter. Moderne Linux-Implementierungen rekonstruieren MSS, SACK und Window Scaling in der Regel zuverlässig; Timestamps und seltene Optionen können jedoch je nach Kernelstand Einschränkungen haben. Ich halte daher die Betriebsart (1) bevorzugt, damit der Standardpfad dominiert und Cookies nur beim Überlauf greifen. Die Gültigkeit eines Cookies ist an Zeitscheiben gebunden – bei stark asymmetrischen Wegen oder Delay-Spitzen kann ein legitimes ACK knapp außerhalb des Fensters liegen. In WAN- und Satellitenszenarien messe ich deshalb Round-Trip-Varianz, bevor ich Retries absenke. NAT und Middleboxen, die Sequenznummern oder Optionen anfassen, sind weitere Kandidaten für Edge-Cases; mit gezielten Captures belege ich, wo Bits verloren gehen.
ACK-/RST-Floods und Varianten jenseits des SYN-Sturms
Nicht jede Transport-Attacke ist eine reine SYN-Flut. ACK- oder RST-Floods zielen auf CPU und Paketpfade, ohne den Handshake zu triggern – Cookies helfen hier kaum. Ich nutze dann frühe Filter (nftables/XDP) mit Zustandslogik oder minimaler ACK-Ratenbegrenzung. Gerade RST-Wellen gegen etablierte Verbindungen beende ich per Regelwerk, das unerwartete RSTs ohne passendes Fenster verwirft. Auch halb-offene Wiederholer (SYN mit Spoofing plus späte ACKs) decke ich über Rate-Limits pro Quellnetzraum ab.
Weiteres Tuning: Listen-/Accept-Queues und schnelle Fehler
Neben den klassischen Parametern nutze ich ergänzende Schalter, die das Verhalten im Grenzbereich prägen:
- Backlog vs. somaxconn: Der Wert in listen(backlog) pro Prozess wird durch net.core.somaxconn gedeckelt. Ich sorge dafür, dass Server-Software und Kernel harmonieren, sonst verpuffen Optimierungen.
- tcp_abort_on_overflow: Ob bei voller Accept-Queue stumm gedroppt oder aktiv mit RST geantwortet wird. In hochvolumigen APIs kann ein schneller Fehler dem Client schnelles Re-Try erlauben; bei TLS- oder Legacy-Clients bevorzuge ich meist das Default-Dropping.
- Port- und TIME-WAIT-Management: Cookies vermeiden keinen Ephemeral-Port-Engpass. Ich plane ip_local_port_range großzügig und setze TIME-WAIT-Optimierungen mit Bedacht, damit Reuse nicht zu Heisenbugs führt.
- SO_REUSEPORT: Mehrere Accept-Queues pro Port verteilen Last quer über Worker-Prozesse und verringern Overflows auf einzelnen CPUs.
Testmethoden: reproduzierbar und aussagekräftig
Ich simuliere Last szenariennah und messe den Umschaltpunkt in den Cookie-Modus, die Erfolgsquote legitimer Verbindungen sowie die Erholzeit nach der Lastspitze. Dabei kombiniere ich synthetische SYN-Fluten mit echten Applikationsabrufen.
# Flut generieren (Labor!)
sudo hping3 -S -p 443 --flood --rand-source <SERVER-IP>
# Netzwerkbedingungen variieren
sudo tc qdisc add dev eth0 root netem delay 80ms 30ms loss 1%
# Legitimen Traffic mischen
wrk -t8 -c512 -d60s https://<SERVER>/
# Beobachtung parallel
watch -n1 'ss -s; echo; grep -E "Syncookies|Listen(Overflows|Drops)" /proc/net/netstat'
Mit diesen Schritten erkenne ich, ob Retries zu aggressiv sinken, ob Upstream-Firewalls fälschlich Timestamps filtern oder ob die Accept-Queues einzelner Worker überproportional überlaufen. Ich dokumentiere die Kennzahlen (Annäherung an 100% Erfolgsquote legitimer Verbindungen, Cookie-Trefferquote, Latenzverhalten), um spätere Anpassungen datenbasiert vornehmen zu können.
Betrieb und Wartung: Stabilität über Laufzeit sichern
Im Dauerbetrieb plane ich Secret-Rotation (Kernel-seitig automatisch) und beobachte, ob Zeitscheibenwechsel sichtbare Effekte auf sehr lange RTT-Strecken haben. Ich halte Kernel und Treiber aktuell, damit Verbesserungen in der Cookie-Implementierung (bessere Optionencodierung, robuste Zeitschlitze) wirken. Für Audits notiere ich, wann der Schutzmodus griff, wie viele Verbindungen er durchließ und ob zusätzliche Filter zugeschaltet wurden. Bei Änderungen an MTU, Offloading oder NF-Stacks (z. B. neue nftables-Sets) wiederhole ich Kurztests, damit ich Fehlinteraktionen früh entdecke.
Kurzfassung für Eilige
SYN Cookies halten die Handshake-Last klein, indem sie Zustände erst nach einem bestätigten ACK anlegen und so die Syn-Queue vor Fluten schützen. Ich aktiviere Modus 1, tune Backlogs und Retries vorsichtig und messe die Effekte mit klaren Metriken. Zusätzliche Layer wie nftables-Rate-Limits, SYNPROXY und XDP bremsen Verkehr noch vor dem TCP-Stack. In Summe sichere ich so Web-, Mail-, VPN- und API-Dienste gegen SYN-Floods ab, ohne reguläre Clients zu benachteiligen. Wer diese Schritte stringent umsetzt, stärkt Verfügbarkeit und reduziert Ausfälle bei Angriffslast spürbar.


