Eine DDoS-Attacke erkennst du an Metriken, die plötzlich und ohne Anlass aus dem Normalbereich springen: Requests pro Sekunde, halboffene TCP-Verbindungen, eingehende Bandbreite oder volle Conntrack-Tabellen. Typisch ist, dass viele Quellen dieselben Pfade aufrufen, kaum Referer mitschicken und nichts kaufen. Prüfen lässt sich das mit nginx-Logs, ss, iftop und den Analytics deines CDN.
Der erste Hinweis ist selten eine Warnmeldung. Meistens ruft jemand an und sagt, der Shop lade nicht. Dann schaust du aufs Monitoring, siehst eine CPU bei 100 Prozent und fragst dich, ob gerade ein Plugin-Update schiefgegangen ist oder jemand deinen Server flutet. Genau diese Unterscheidung ist der Kern, wenn du eine DDoS-Attacke erkennen willst.
Woran du eine DDoS-Attacke erkennst
Ein Angriff verändert mehrere Messwerte gleichzeitig und ohne erkennbaren Auslöser. Ein Defekt verändert meist nur einen. Die folgende Tabelle ist eine Arbeitsgrundlage, keine Norm: Die Normalwerte musst du für deinen eigenen Server kennen.
| Messwert | Wo du ihn siehst | Auffällig, wenn … |
|---|---|---|
| Requests pro Sekunde | nginx-Log, CDN-Analytics | ein Vielfaches des üblichen Tageshochs |
| Eingehende Bandbreite | iftop, Hoster-Graph | Leitung nahe Vollauslastung, ausgehend kaum mehr |
| Halboffene TCP-Verbindungen | ss -tan state syn-recv | Hunderte oder Tausende statt einstelliger Werte |
| Conntrack-Einträge | /proc/sys/net/netfilter/nf_conntrack_count | nahe nf_conntrack_max |
| Fehlerquote | nginx-Log (Status 499, 502, 503, 504) | sprunghaft steigend |
| Conversion | Shop- oder Analytics-Backend | Besucher hoch, Bestellungen bei null |
Das letzte Kriterium wird gern unterschätzt. Echte Besucher kaufen, melden sich an, scrollen. Ein Botnetz tut das nicht.
Der Server ist langsam: die ersten drei Befehle
Bevor du irgendetwas abschaltest, verschaffst du dir in zwei Minuten einen Überblick. Die Befehle laufen auf jedem aktuellen Debian oder Ubuntu, iftop musst du eventuell nachinstallieren.
ss -s
ss -tan state syn-recv | wc -l
cat /proc/sys/net/netfilter/nf_conntrack_count /proc/sys/net/netfilter/nf_conntrack_max
ss -s liefert eine Zusammenfassung. Die Ausgabe sieht etwa so aus:
Total: 41873
TCP: 41290 (estab 912, closed 214, orphaned 7, timewait 201)
Transport Total IP IPv6
RAW 0 0 0
UDP 14 9 5
TCP 41076 41060 16
INET 41090 41069 21
FRAG 0 0 0
Wenn die TCP-Summe weit über den etablierten Verbindungen liegt, hängen viele Verbindungen in Zwischenzuständen. Der zweite Befehl zählt die halboffenen. Auf einem normal laufenden Webserver liegt der Wert meist im niedrigen zweistelligen Bereich oder darunter. Tausende deuten auf einen SYN-Flood. Ob SYN-Cookies aktiv sind, zeigt sysctl net.ipv4.tcp_syncookies (1 = an).
Für die Bandbreite startest du iftop -i eth0 -nNP. -n und -N schalten Namens- und Portauflösung ab, -P zeigt die Ports. Siehst du massenhaft eingehenden UDP-Verkehr von Quellport 53 oder 123, obwohl dein Server selbst keine DNS- oder NTP-Anfragen stellt, ist das ein Reflexionsangriff. Wie der funktioniert, erklärt der Artikel zu DNS Amplification.
Im Kernel-Log (dmesg -T | tail -50) lohnt die Suche nach nf_conntrack: table full, dropping packet. Die Meldung heißt: Der Server wirft bereits Pakete weg, egal von wem.
Angriff in nginx-Logs analysieren
Auf Anwendungsebene, also bei HTTP-Floods, ist das Access-Log die beste Quelle. Die folgenden Einzeiler gehen vom Standardformat combined aus. Bei großen Logs nimmst du nur die letzten Zeilen mit tail -n 100000.
Requests pro Minute, um Beginn und Verlauf zu sehen:
awk '{print $4}' /var/log/nginx/access.log | cut -d: -f2-3 | sort | uniq -c | tail -30
Die häufigsten Quell-IPs:
awk '{print $1}' /var/log/nginx/access.log | sort | uniq -c | sort -rn | head -20
Die meistaufgerufenen Pfade und die User-Agents:
awk '{print $7}' /var/log/nginx/access.log | sort | uniq -c | sort -rn | head -20
awk -F'"' '{print $6}' /var/log/nginx/access.log | sort | uniq -c | sort -rn | head -20
Typische Muster eines HTTP-Floods:
- ein einziger teurer Pfad (Suche, Login, Warenkorb) macht den Großteil aus
- Query-Strings mit Zufallswerten wie
/?a8f3k2, die den Cache umgehen - wenige User-Agents in exakt gleicher Schreibweise über Tausende IPs
- leerer Referer bei fast allen Requests
- viele Status 499: Der Client bricht ab, bevor die Antwort kommt
Verteilt sich die Last dagegen auf viele Seiten, mit Referer von einer Nachrichtenseite oder einem Social-Media-Post, hast du wahrscheinlich echten Besuch. Diese Abgrenzung behandelt der Artikel DDoS oder Traffic-Spitze ausführlich.
Hinter einem CDN steht im Log zunächst nur dessen Adresse. Mit set_real_ip_from für die Proxy-Bereiche und real_ip_header CF-Connecting-IP; holst du die echte IP zurück. Prüfe das, bevor du IPs sperrst. Sonst sperrst du deinen eigenen Proxy.
DDoS-Anzeichen in Cloudflare-Analytics
Liegt die Domain hinter Cloudflare, zeigt das Dashboard unter Security die Events und unter Analytics den Verkehr nach Land, ASN, Pfad und User-Agent. Zwei Ansichten helfen besonders:
- Aufschlüsselung nach ASN. Echte Besucher kommen über Telekom, Vodafone, O2 und Kabelnetze. Ein Flood kommt oft gebündelt aus Rechenzentrumsnetzen.
- Verhältnis von Cache-Hits zu Origin-Requests. Steigen nur die Origin-Requests, zielt jemand gezielt auf ungecachte Inhalte.
Wenn Cloudflare selbst schon einen Angriff mitigiert hat, taucht er dort als DDoS-Ereignis auf. Was du in den Einstellungen anpassen kannst, steht im Artikel zum DDoS-Schutz mit Cloudflare.
Die Angriffsart einordnen
Für die Abwehr ist entscheidend, auf welcher Ebene der Angriff läuft. Grob gilt:
| Symptom | Wahrscheinliche Ebene | Wer filtern muss |
|---|---|---|
| Leitung voll, Server-CPU niedrig | Netzwerk (volumetrisch) | Hoster oder Upstream |
| Viele SYN-RECV, Conntrack voll | Protokoll | Kernel, Firewall, Hoster |
| CPU und PHP-Worker voll, Leitung frei | Anwendung (HTTP) | Webserver, WAF, CDN |
| DNS-Auflösung langsam, Website selbst ok | DNS | DNS-Anbieter |
Bei volumetrischen Angriffen kannst du auf deinem Server nichts tun, weil die Pakete schon die Leitung davor verstopfen. Da hilft nur der Provider. Mehr zu den Varianten findest du bei den DDoS-Arten.
Checkliste: Daten sichern, solange der Angriff läuft
Was du jetzt sammelst, brauchst du später für den Hoster, die Versicherung und eine mögliche Anzeige.
- Beginn mit Uhrzeit und Zeitzone notieren
- Access- und Error-Logs kopieren, bevor die Logrotation sie überschreibt
- Ausgabe von
ss -sundiftopals Screenshot oder Textdatei sichern - CDN-Analytics des Zeitraums exportieren
- Erpresser-Mails mit vollständigem Header aufheben
- Ticketnummern von Hoster und DNS-Anbieter festhalten
Wenn die Lage klar ist, geht es mit den Sofortmaßnahmen bei einer DDoS-Attacke weiter.
Was die Domain mit der Erkennung zu tun hat
Ein Teil der Angriffe richtet sich gar nicht gegen den Webserver, sondern gegen die Nameserver. Dann ist der Server gesund, aber niemand findet ihn. Deshalb gehört die DNS-Seite ins Monitoring: Ein externer Check mit dig +short example.de A @ns1.dein-anbieter.de alle paar Minuten zeigt früh, ob die Auflösung hakt.
Wie viel Kontrolle du dort hast, hängt vom Registrar ab. Bei betadomain verwaltest du die Nameserver deiner Domain selbst, kannst DNSSEC aktivieren und per Domain-API automatisiert umstellen, wenn du im Ernstfall auf einen anderen DNS-Anbieter ausweichen musst. Wer seine Projektdomain dort noch nicht hat, kann den Namen bei einem Registrar mit DNSSEC prüfen und dann in Ruhe das Monitoring für Server und Nameserver aufsetzen.
Domain gefunden? Prüfen und registrieren kannst du sie direkt bei Domain registrieren – Jahrespreis ab 2,99 €.
Häufige Fragen
Kann ich eine DDoS-Attacke von außen erkennen, ohne Serverzugang?
Nur indirekt. Du siehst Timeouts, Fehler 502 oder 503 und langsame DNS-Antworten. Ob dahinter ein Angriff, ein Hardwaredefekt oder ein Deployment-Fehler steckt, zeigen erst Server-Metriken oder die Analytics deines CDN. Ohne Zugang fragst du beim Hoster nach, ob er Auffälligkeiten im Netz sieht.
Ab wie vielen Requests pro Sekunde ist es ein DDoS?
Eine feste Grenze gibt es nicht. Für einen kleinen Shop können 300 Requests pro Sekunde schon zu viel sein, für eine Nachrichtenseite ist das ein normaler Dienstagabend. Maßstab ist dein eigener Normalwert. Liegt die Last beim Zehnfachen und passt zu keinem Ereignis, solltest du genauer hinsehen.
Warum zeigt mein nginx-Log nur Cloudflare-IPs?
Weil der Proxy die Verbindung zu deinem Server aufbaut. Mit dem Modul ngx_http_realip_module, den Direktiven set_real_ip_from für die Cloudflare-Bereiche und real_ip_header CF-Connecting-IP steht wieder die echte Besucher-IP im Log. Ohne das ist jede IP-Auswertung wertlos.
Was bedeutet „nf_conntrack: table full, dropping packet“?
Der Kernel verfolgt jede Verbindung in einer Tabelle mit fester Größe. Ist sie voll, verwirft er neue Pakete, auch von echten Besuchern. Die Meldung taucht bei SYN- und UDP-Floods häufig auf, kann aber auch bei einem schlecht dimensionierten Server unter normaler Last kommen.