Alle Systeme betriebsbereit 6 Offshore-Regionen No-KYC-Bezahlvorgang
Hands-on Praxisleitfaden

DDoS-Angriff auf Ihrem VPS: das Runbook für die erste Stunde

Die ersten zehn Minuten entscheiden, wie die nächsten drei Stunden verlaufen, und die meisten Menschen verbringen sie mit Raten — Dienste neu starten, wahllos Adressen sperren, ein Dashboard lesen, das nur sagt, dass die Seite down ist. Das ist die Abfolge, die wir auf der Flotte tatsächlich fahren: bestätigen, dass der Angriff echt ist, seine Form messen, die Last abwerfen, die sich von innerhalb der Box abwerfen lässt, und genau den Punkt erkennen, an dem nichts mehr zählt, was Sie auf dem Server eintippen, sondern nur noch das 1.5 Tbps Upstream-Scrubbing davor. Geschrieben für einen einzelnen VPS ab $8.00/Monat, nicht für ein NOC.

Aktualisiert 2026-09-06 · 15 Min. Lesezeit · Flottenbetrieb
Auf dieser Seite
  1. Zuerst: Stellen Sie sicher, dass es wirklich ein Angriff ist
  2. Die Fünf-Minuten-Triage
  3. Was Sie nicht von innerhalb der Box aus reparieren können
  4. Layer 7: die Flut, die aussieht wie Traffic
  5. Vier Kontrollen, geordnet nach Wirkung pro Minute
  6. Kämpfen Sie nicht von der Maschine aus, die Ihre Daten hält
  7. Der Tag, an dem Sie der Reflektor sind, nicht das Ziel
  8. Danach: das Post-Mortem und die Grundausstattung
  9. Schritt für Schritt
SP·01

Zuerst: Stellen Sie sicher, dass es wirklich ein Angriff ist

Der teuerste Fehler mitten in einem Ausfall ist, das Falsche zu behandeln. „Die Seite ist langsam“ ist ein Symptom, das eine echte Flut genauso auslöst wie ein Deploy, das eine Query ohne Index ausgeliefert hat, ein Cron-Job, der jede Stunde zur selben Minute anfängt, die Datenbank leerzuräumen, ein Crawler, der Ihre facettierte Suche entdeckt hat, ein Link, der es auf die Startseite von irgendwo Großem geschafft hat, und eine vollgelaufene Festplatte. Von einem Browser aus sehen alle diese Fälle identisch aus, und die richtigen Reaktionen schließen sich gegenseitig aus: Sie wollen keine echten Kunden ausbremsen, nur weil eine Migration einen Index vergessen hat.

Drei Fragen trennen sie in unter einer Minute. Ist das Verkehrsaufkommen wirklich abnormal, oder ist der Traffic normal und nur der Server langsam? Eine Flut zeigt sich als sprunghafte Veränderung bei Paketen oder Anfragen pro Sekunde; ein missglücktes Deploy zeigt sich als normales Anfragevolumen bei eingebrochener Antwortzeit. Hat sich in der letzten Stunde auf Ihrer Seite etwas geändert? Prüfen Sie das Deploy-Log vor der Firewall — selbstverschuldete Vorfälle übertreffen Angriffe auf kleiner Infrastruktur bei Weitem. Verteilt sich die Last über die ganze Seite, oder konzentriert sie sich auf einen einzigen Pfad? Echte Fluten sind meist wahllos oder zielen auf die Startseite; ein teurer Endpunkt, der von hundert Clients bombardiert wird, ist eher Missbrauch als ein DDoS-Angriff, und die Lösung dafür ist deutlich billiger.

Beantworten Sie das, dann geht es weiter. Der Rest dieses Guides geht davon aus, dass die Antwort lautete: Das Volumen ist abnormal, auf Ihrer Seite hat sich nichts geändert, und die Box geht unter.

SP·02

Die Fünf-Minuten-Triage

Es gibt nur zwei Fehlerarten, die zählen, und sie verlangen entgegengesetzte Reaktionen. Entweder die Leitung ist voll — Pakete kommen schneller an, als Ihr Uplink oder Ihr Kernel sie verarbeiten kann, und Ihr Server verliert Traffic, bevor auch nur eine Ihrer Anwendungen ihn zu Gesicht bekommt —, oder die Leitung ist in Ordnung und die Anwendung ist erschöpft, weil wohlgeformte Anfragen schneller eintreffen, als sie beantwortet werden können. Beides zu verwechseln verschwendet die Stunde: nginx-Tuning bringt gegen eine gesättigte Leitung nichts, und mehr Bandbreite zu kaufen bringt gegen eine Anfragenflut nichts.

Unterscheiden Sie beide, indem Sie zwei Zahlen vergleichen. Sehen Sie sich die Interface-Counter und die CPU-Aufteilung gleichzeitig an. Wenn die rx-Bytes nahe an Ihrer Portgeschwindigkeit kleben, wenn die Zähler für dropped oder overrun steigen und die Zeit eher in Soft-Interrupts geht als in Ihre Anwendung, liegt die Flut auf Layer 3 oder 4 und ist ein Kapazitätsproblem. Ist die Bandbreite unauffällig, aber der Worker-Pool gesättigt, stauen sich die Verbindungen, und das Access-Log ist voller plausibel aussehender Anfragen, dann ist es Layer 7 und ein Filterproblem.

Klassifizieren Sie den Layer-3/4-Fall dann noch einen Schritt genauer, denn die Subtypen verhalten sich unterschiedlich. Eine SYN-Flut zeigt sich als Zehntausende halboffener Sockets in SYN-RECV; der Kernel kommt damit gut zurecht, sobald Syncookies aktiviert sind. Eine UDP- oder Amplification-Flut zeigt sich als riesiges eingehendes Volumen auf Ports, auf denen Sie gar nicht lauschen — DNS-, NTP-, Memcached-, CLDAP-Reflexionen —, und nichts, was Sie ausführen, hilft dagegen, weil der Schaden schon angerichtet ist, sobald die Pakete Ihre NIC erreichen. Eine Fragmentierungs- oder Rohpaket-Flut zeigt sich als hohe Paketrate bei moderater Bandbreite, was die CPU statt die Leitung aushungert. Notieren Sie sich, welche davon Sie haben, bevor Sie eine Konfigurationsdatei anfassen.

SP·03

Was Sie nicht von innerhalb der Box aus reparieren können

Das ist der Teil, den die meisten Artikel auslassen, und der Teil, der darüber entscheidet, ob Ihre Stunde produktiv ist. Eine Firewall-Regel auf dem Ziel rettet keinen gesättigten Uplink. Ihr iptables-DROP läuft auf der Maschine am Ende der Leitung — das Paket hat den Transit-Link bereits durchquert, die Bandbreite, für die Sie bezahlen, bereits verbraucht, und bereits das Paket eines echten Nutzers verdrängt. Es lokal zu verwerfen schützt Ihre Anwendung davor, Zyklen zu verschwenden, was etwas wert ist, und schützt Ihre Bandbreite vor überhaupt nichts.

Die ehrliche Obergrenze für einen einzelnen Server ist ungefähr die kleinere von zwei Zahlen: die Portgeschwindigkeit, mit der er verbunden ist, und die Pakete pro Sekunde, die seine CPU klassifizieren kann. Ein 1-Gbps-Port ist bei 1 Gbps voll, ganz gleich, wie elegant Ihr Regelwerk ist, und eine moderate Flut kleiner Pakete kann ein paar Kerne mit der Interrupt-Verarbeitung auslasten, lange bevor die Bandbreitenzahl alarmierend aussieht. Jenseits dieses Punkts hilft nur noch ein Gerät weiter stromaufwärts, das mehr Kapazität hat als der Angriff und den Traffic verwirft, bevor er überhaupt Ihre Leitung erreicht. Genau das ist Scrubbing, und deshalb steht jede Maschine unserer Flotte hinter 1.5 Tbps durchgehend aktiver Mitigation statt hinter einer größeren Firewall.

Ebenso wichtig ist die Konsequenz daraus: Haben Sie keinen Upstream-Schutz, besteht die Antwort Ihres Providers auf einen großen volumetrischen Angriff darin, Ihre Adresse per Null-Route stillzulegen, weil die Alternative wäre, jeden anderen Kunden auf dieser Leitung zu beeinträchtigen. Das ist keine Böswilligkeit, das ist Arithmetik — und es bedeutet, dass der Angreifer gewinnt, indem er Sie teuer macht, statt etwas kaputtzumachen. Im Voraus zu wissen, ob Mitigation in Ihrem Plan enthalten ist oder ein kostenpflichtiges Extra, das Sie nie aktiviert haben, ist eine Fünf-Minuten-Prüfung, die sich heute lohnt und nicht erst während des Vorfalls. Unsere ist bei jedem Plan inklusive, und das ist die einzige Regelung, die um 3 Uhr morgens hilft.

SP·04

Layer 7: die Flut, die aussieht wie Traffic

Eine Layer-7-Flut ist schwieriger, weil jede einzelne Anfrage legitim ist. Eine gut gebaute HTTP-Flut vervollständigt den TCP-Handshake, handelt TLS aus, schickt ein gültiges GET / mit einem plausiblen User-Agent und liest die Antwort. Kein einziges Paket darin ist fehlerhaft. Was Sie umbringt, ist die Arithmetik: Eine Anfrage kostet den Angreifer fast nichts zu senden und kostet Sie eine Datenbankabfrage, ein Template-Rendering und hundert Millisekunden eines Workers, der jetzt niemand anderen mehr bedient.

Die Anzeichen stehen in Ihrem eigenen Access-Log, und sie sind meist offensichtlich, sobald Sie gezielt danach suchen, statt nur draufzuschauen. Cache-Busting-Query-Strings — Tausende Anfragen an /?1234567, jede eine einzigartige URL, die jeden Cache aushebelt, den Sie besitzen — sind mit Abstand die häufigste Signatur. Eine User-Agent-Verteilung ohne Long Tail: echter Traffic ist eine unordentliche Mischung aus Hunderten Browser-Builds, und eine Flut besteht oft aus drei Zeichenketten, die eine Million Mal wiederholt werden, oder einer, die kein echter Mensch benutzt. Ein Referrer-Feld, das überall identisch ist. Anfragen, die Ihre statischen Assets komplett auslassen — ein echter Browser lädt nach dem HTML noch das CSS, die Schriften und die Bilder nach; ein Flut-Client fragt das HTML ab und verschwindet. Und eine Quellverteilung, die zu flach ist: Ein Botnet, verteilt über zehntausend Adressen aus Privathaushalten, von denen jede zwei Anfragen pro Sekunde sendet, sieht wie Popularität aus, bis Ihnen auffällt, dass die Rate pro Adresse verdächtig gleichmäßig ist.

Dann gibt es noch die Variante, die fast gar keinen Traffic braucht: den langsamen Angriff. Ein paar Hundert Verbindungen, die sich öffnen, alle zwanzig Sekunden einen Header senden und nie fertig werden, belegen jeden Worker, den Sie haben, während Ihr Bandbreiten-Graph flach bleibt. Die Lösung ist kein Rate Limit — die Anfragerate ist winzig —, sondern aggressive Header- und Body-Timeouts, weshalb sie weiter unten im ersten Konfigurationsblock auftauchen und nicht als nachträglicher Einfall.

SP·05

Vier Kontrollen, geordnet nach Wirkung pro Minute

Tun Sie unter Druck zuerst das, was am meisten bewirkt. Die folgende Reihenfolge ist nicht willkürlich; sie ist grob absteigend danach sortiert, wie viel Last jede Maßnahme pro Minute Ihrer Aufmerksamkeit abwirft.

  • Liefern Sie etwas Billiges aus. Ein Micro-Cache von dreißig Sekunden vor Ihrer Anwendung verwandelt tausend identische Anfragen pro Sekunde in einen Zugriff auf den Origin und 999 Lesevorgänge aus dem Speicher. Das ist der mit Abstand größte Hebel gegen fast jede HTTP-Flut, es kostet einen einzigen Block mit einer Direktive, und für anonymen Traffic ist es fast immer sicher. Fügen Sie proxy_cache_lock hinzu, damit ein Cache-Miss keine Thundering Herd auf das Backend loslässt.
  • Nebenläufigkeit begrenzen und Timeouts verkürzen. limit_conn pro Adresse plus knappe Header-, Body- und Keepalive-Timeouts tötet langsame Angriffe direkt ab und verhindert, dass ein einzelner Client Ihren Worker-Pool blockiert. Das ist die Kontrolle, die echte Nutzer am wenigsten kostet.
  • Rate begrenzen, mit Burst. limit_req mit einem sinnvollen Burst ist präzise, aber langsamer zu justieren, und es ist die Maßnahme, die False Positives erzeugt, wenn Sie sie aus Panik statt aus Ihrer eigenen Baseline heraus einstellen. Sie müssen Ihre normale Anfragerate pro Sekunde und Client kennen, bevor Sie eine Zahl festlegen können — weshalb das Post-Mortem am Ende dieses Guides wichtiger ist, als es klingt.
  • Blockieren, eng begrenzt und zurückhaltend. Bestimmte Netze zu verwerfen funktioniert, wenn die Quellen konzentriert sind, und bringt nichts, wenn nicht. Es altert außerdem schlecht: Jede Blockade, die Sie während eines Vorfalls hinzufügen, ist womöglich ein Kunde, den Sie in drei Monaten stillschweigend abweisen. Verwenden Sie ein Set mit Timeout, damit die Regeln von selbst auslaufen.

Beachten Sie, was nicht auf der Liste steht: einzelne IP-Adressen von Hand sperren, den Webserver wiederholt neu starten, und die Firewall deaktivieren, um zu sehen, „ob das hilft“. Ersteres ist gegen eine verteilte Quelle zu langsam, um etwas zu bewirken, Zweiteres wirft jede warme Verbindung weg, die Sie hatten, und Drittens ist der Weg, wie aus einem Vorfall eine Kompromittierung wird.

SP·06

Kämpfen Sie nicht von der Maschine aus, die Ihre Daten hält

Jede Kontrolle von oben ist mehr wert, wenn sie woanders läuft als auf der Box, die Ihre Datenbank hält. Ist Ihr Edge ein separater Knoten, endet die Flut auf einer Maschine, deren einzige Aufgabe es ist, Fluten zu beenden: Sie cacht, drosselt und verwirft, mit der echten Client-Adresse in der Hand, und der Origin sieht immer nur den kleinen, gefilterten Rest über einen privaten Tunnel. Fällt der Edge aus, ersetzen Sie ihn in 15 min und verlieren nichts, weil nichts darauf liegt. Fällt der Origin aus, haben Sie einen Ausfall und eine Wiederherstellung.

Diese Trennung schließt außerdem den Bypass, der die meiste Mitigation zur Dekoration macht. Hat der Origin noch einen öffentlichen Listener, kann ein Angreifer, der seine Adresse findet — über Passive-DNS, einen Certificate-Transparency-Eintrag, einen MX-Eintrag oder eine Link-Vorschau —, an jeder Kontrolle vorbeizielen, die Sie konfiguriert haben, und die Anwendung direkt treffen. Das kommt so häufig vor, dass man es bis zum Beweis des Gegenteils als Normalzustand jeder „geschützten“ Seite behandeln sollte. Die Version zu bauen, die hält, ist ein eigener Guide: ein Offshore-Reverse-Proxy ganz ohne öffentlichen Listener auf dem Origin.

Eine Warnung zur Mitte eines Vorfalls: Das ist Architektur, keine Erste Hilfe. Einen Edge aufzusetzen, DNS umzuziehen und einen Tunnel unter laufendem Angriff neu aufzubauen, ist ein Zwei-Stunden-Job, der unter Druck schlecht gemacht wird, und allein die DNS-Änderung greift erst nach Ablauf Ihrer TTL. Wenn Sie es haben, nutzen Sie es. Wenn nicht, kommen Sie mit den Kontrollen, die Sie haben, durch die Stunde, und bauen Sie es in der ruhigen Woche danach auf — genau dann, wenn es niemand tut.

SP·07

Der Tag, an dem Sie der Reflektor sind, nicht das Ziel

Es gibt eine zweite Version dieses Vorfalls, bei der Ihr Server nicht das Opfer ist und niemand es Ihnen sagt. Ein offener Resolver, ein exponierter NTP-Daemon, ein unauthentifiziertes Memcached auf einer öffentlichen Schnittstelle, ein SSDP- oder CLDAP-Responder in einem Container — jeder davon beantwortet eine kleine gefälschte Anfrage mit einer viel größeren Antwort, gerichtet an jemand anderen. Von Ihrer Seite aus sind die Symptome umgekehrt: Die ausgehende Bandbreite ist hoch, die eingehende gering, Ihre Anwendung läuft einwandfrei, und das erste echte Signal ist eine Abuse-Meldung oder ein gesperrter Port.

Die Prüfung dauert eine Minute und gehört ins selbe Runbook, denn es ist derselbe Befehl, den Sie schon während der Triage ausgeführt haben. ss -tulpn sollte nichts auflisten, was an eine öffentliche Adresse gebunden ist, die Sie nicht absichtlich dorthin gelegt haben, und UDP-Dienste verdienen besonderes Misstrauen, weil sie diejenigen sind, die verstärken. Ein rekursiver Resolver muss an localhost oder an eine Tunnel-Adresse gebunden sein; Memcached und Redis dürfen niemals aus dem Internet erreichbar sein; und jeder Container, der einen Port mit -p 0.0.0.0: veröffentlicht, hat gerade ein Loch in die Firewall gerissen, die Sie konfiguriert haben, weil Docker seine eigenen Regeln vor Ihre schreibt. Genau das Letzte überrascht die Leute jedes einzelne Mal.

Dasselbe Muster deckt auch ausgehende Fluten von einer bereits kompromittierten Maschine ab, was der andere Grund ist, aus dem ein Provider eine Adresse plötzlich per Null-Route stilllegt. Ist Ihr ausgehender Graph hoch und Ihre Anwendung untätig, hören Sie auf, Konfigurationen zu lesen, und fangen Sie an, Prozesse zu prüfen — das ist ein Einbruch, kein Kapazitätsproblem, und die richtige Reaktion ist, die Box aus einem bekanntermaßen sauberen Backup neu aufzubauen, statt sie zu filtern.

SP·08

Danach: das Post-Mortem und die Grundausstattung

Angriffe hören auf. Meist wird dem Angreifer langweilig, manchmal macht die Mitigation es sinnlos, gelegentlich war es ein befristetes Booter-Abo, das schlicht ausgelaufen ist. Die Versuchung in diesem Moment ist, alles genau so zu lassen, wie es ist, und ins Bett zu gehen — und genau so wird aus einem vorübergehenden Rate Limit neun Monate später ein dauerhaftes, vergessenes, stilles 429 für ein ganzes Land. Nehmen Sie sich zwanzig Minuten, um die Sache abzuschließen, solange sie noch frisch ist.

Drei Artefakte lohnt es sich zu erstellen. Eine Baseline: Ihre normale Anfragerate pro Sekunde, Ihre normale Rate pro Client, Ihre normale Bandbreite bei Spitzenlast. Ohne diese Zahlen ist jedes Limit, das Sie beim nächsten Vorfall setzen, eine Schätzung, und die Hälfte davon wird in die Richtung falsch liegen, die Kunden schadet. Eine Rollback-Liste: alles, was Sie geändert haben, mit Datum und Grund, damit die Notfallkonfiguration nicht stillschweigend zur dauerhaften wird. Ein Runbook, das vier Befehle lang ist und irgendwo liegt, wo Sie es erreichen, wenn die Seite down ist — nicht auf dem Server, und nicht nur im eigenen Kopf.

Schließen Sie dann die beiden strukturellen Lücken, denn genau hier sitzt diese Schicht im Stack. Mitigation absorbiert das Volumen, ein Edge hält die Flut von Ihren Daten fern, und die Box dahinter muss trotzdem richtig gehärtet sein und wiederherstellbare Off-Site-Backups haben, denn der nächste Vorfall nach diesem ist vielleicht gar keine Flut. Ein Server, der einen DDoS übersteht und einen Monat später seine Festplatte verliert, war nie widerstandsfähig — er hatte zweimal Glück.

SP·09

Schritt für Schritt

  1. 01

    Den Angriff bestätigen, bevor Sie etwas ändern

    Verschaffen Sie sich ein ehrliches Bild der Maschine, bevor Sie eine Konfigurationsdatei anfassen. Sie suchen nach einer sprunghaften Veränderung bei Paketen oder Anfragen und danach, wohin die Zeit fließt — eine Anwendung, der Soft-Interrupts die CPU rauben, ist ein ganz anderer Vorfall als eine Anwendung, die auf eine Datenbank wartet.

    # is the box alive, and where is the time going?
    uptime                     # load average against your core count
    vmstat 1 5                 # 'in' and 'cs' high, 'id' near zero = packet work
    mpstat -P ALL 1 3          # %soft pinned on one core = interrupt saturation
    
    # is the pipe full, or just busy?
    ip -s link show eth0       # rx bytes, and the errors/dropped counters
    ethtool eth0 | grep -i speed
    
    # requests per second from your own log, minute by minute
    tail -n 20000 /var/log/nginx/access.log \
      | awk -F'[][]' '{print $2}' | cut -d: -f2-4 | uniq -c | tail -5

    Bevor Sie es als Angriff einstufen, prüfen Sie Ihr eigenes Deploy-Log und Ihre Cron-Tabelle. Selbstverschuldete Ausfälle sind auf einem einzelnen VPS häufiger als Fluten, und von außen sehen sie gleich aus.

  2. 02

    Die Form des Traffics in sechzig Sekunden messen

    Jetzt klassifizieren Sie sie. Drei Fragen: wie viele verschiedene Quellen, welches Protokoll und welcher Zustand, und — falls es HTTP ist — welche Pfade und welche Agents. Die Antworten entscheiden, zu welcher Kontrolle Sie greifen, und sie zu sammeln dauert etwa eine Minute.

    # top source addresses on the wire right now
    timeout 20 tcpdump -nn -i eth0 -c 20000 2>/dev/null \
      | awk '{print $3}' | rev | cut -d. -f2- | rev \
      | sort | uniq -c | sort -rn | head -20
    
    # TCP state census: a wall of SYN-RECV is a SYN flood
    ss -tan | awk '{print $1}' | sort | uniq -c | sort -rn
    
    # layer 7: talkers, paths, agents over the last 50k requests
    L=/var/log/nginx/access.log
    tail -n 50000 $L | awk '{print $1}' | sort | uniq -c | sort -rn | head -20
    tail -n 50000 $L | awk '{print $7}' | sort | uniq -c | sort -rn | head -20
    tail -n 50000 $L | cut -d'"' -f6   | sort | uniq -c | sort -rn | head -10

    Lesen Sie das Ergebnis anhand der Anzeichen: einzigartige Query-Strings auf einem Pfad, eine User-Agent-Liste ohne Long Tail, keine Anfragen nach Ihren statischen Assets, oder eine Rate pro Adresse, die seltsam gleichmäßig ist. Ist die Bandbreite hoch auf Ports, auf denen Sie nicht lauschen, hören Sie hier auf — das ist eine volumetrische Flut, und Schritt sechs ist der einzige Schritt, der zählt.

  3. 03

    Etwas Billiges ausliefern und die Verbindungen begrenzen

    Zuerst das mit der größten Wirkung. Ein Dreißig-Sekunden-Micro-Cache verdichtet eine Flut identischer anonymer Anfragen zu einem einzigen Zugriff auf den Origin, und knappe Timeouts töten langsame Angriffe ab, die ein Rate Limit nicht sieht. Packen Sie beides in den http-Block, und laden Sie dann neu, statt neu zu starten, damit Ihre warmen Verbindungen erhalten bleiben.

    # /etc/nginx/nginx.conf — http block
    limit_conn_zone $binary_remote_addr zone=perip:10m;
    limit_req_zone  $binary_remote_addr zone=flood:20m rate=10r/s;
    
    client_header_timeout 10s;
    client_body_timeout   10s;
    send_timeout          10s;
    keepalive_timeout     20s;
    reset_timedout_connection on;
    
    proxy_cache_path /var/cache/nginx levels=1:2 keys_zone=hot:64m
                     max_size=2g inactive=10m use_temp_path=off;
    # the server block — cap concurrency, serve the cached copy
    limit_conn perip 20;
    
    location / {
        proxy_cache hot;
        proxy_cache_valid 200 301 302 30s;
        proxy_cache_lock on;
        proxy_cache_use_stale error timeout updating
                              http_500 http_502 http_503 http_504;
        add_header X-Cache $upstream_cache_status;
        proxy_pass http://127.0.0.1:8080;
    }
    nginx -t && systemctl reload nginx
    curl -sI https://example.com/ | grep -i x-cache   # want: HIT on the second call
  4. 04

    Die Rate des echten Clients begrenzen, nicht die des eigenen Proxys

    Sitzt irgendetwas vor nginx, kommt jede Anfrage von einer einzigen Adresse, und ein Limit pro Adresse drosselt den Proxy statt den Angreifer — oder bannt ihn komplett und legt die Seite lahm, während Sie sie eigentlich verteidigen. Vertrauen Sie dem Forwarded-Header nur von der Proxy-Adresse, niemals aus dem Internet, und wenden Sie dann das Limit an.

    # /etc/nginx/conf.d/realip.conf — the tunnel or edge address only
    set_real_ip_from 10.66.0.1;
    real_ip_header   X-Forwarded-For;
    real_ip_recursive off;
    # burst absorbs bursty humans; nodelay keeps the page fast for them
    location / {
        limit_req zone=flood burst=20 nodelay;
        limit_req_status 429;
    }
    
    # the expensive paths get a much tighter bucket of their own
    location ~ ^/(search|login|register|api/) {
        limit_req zone=flood burst=5;
        limit_req_status 429;
    }

    Beobachten Sie dann, was Sie gerade getan haben: tail -f /var/log/nginx/error.log | grep limiting. Sehen die limitierten Adressen wie Ihre Kunden aus, ist die Rate zu niedrig — erhöhen Sie sie. Ein Limit, das echte Nutzer blockiert, ist ein Ausfall, den Sie sich selbst eingebrockt haben.

  5. 05

    Eng begrenzt blockieren und jeder Blockade ein Ablaufdatum geben

    Nur sinnvoll, wenn Schritt zwei konzentrierte Quellen gezeigt hat. Verwenden Sie ein Set, keine tausend Regeln — ein ipset-Lookup läuft in konstanter Zeit, eine lange iptables-Chain wird für jedes Paket durchlaufen und wird selbst zur eigenen Denial-of-Service. Geben Sie jedem Eintrag ein Timeout, damit aus dem Notfall von heute nicht die stille Sperrliste von nächstem Jahr wird.

    ipset create flood hash:net timeout 3600 -exist
    iptables -I INPUT -m set --match-set flood src -j DROP
    
    # feed it from the census: /24s you actually verified, not guesses
    for n in 203.0.113.0/24 198.51.100.0/24; do ipset add flood $n -exist; done
    
    # SYN flood: let the kernel do the part it is good at
    sysctl -w net.ipv4.tcp_syncookies=1
    sysctl -w net.ipv4.tcp_max_syn_backlog=8192
    sysctl -w net.core.somaxconn=8192
    
    ipset list flood | head -20      # keep a copy of this for the post-mortem

    Widerstehen Sie der Versuchung, per Geoblocking ein ganzes Land zu sperren, außer Sie können die Kunden benennen, die Sie damit aussperren. Und niemals ufw disable, um eine Theorie zu testen: Eine ungeschützte Box unter aktivem Angriff ist der Weg, wie aus einem Bandbreiten-Vorfall ein Einbruch wird.

  6. 06

    Auf die Ebene eskalieren, die es tatsächlich abfangen kann

    Sagen die Interface-Counter, dass die Leitung gesättigt ist, oder steigen die Drops, während Ihre CPU im Leerlauf ist, haben Sie die Obergrenze dessen erreicht, was sich auf dem Server tun lässt. Bestätigen Sie diesen Befund, und eskalieren Sie, statt weiter zu justieren.

    # drops in the stack itself — second column is 'dropped'
    awk '{print strtonum("0x" $2)}' /proc/net/softnet_stat | paste -sd+ | bc
    
    # interface-level loss against link speed
    ip -s link show eth0 | sed -n '3,6p'

    Mit Upstream-Scrubbing im Einsatz gibt es meist nichts mehr zu tun: Die Erkennung läuft durchgehend, und die Flut wird im Netzwerk verworfen, bevor sie Ihren Port erreicht — auf unserer Flotte sind das 1.5 Tbps Kapazität, die vor jedem Plan liegen, sodass der Vorfall im Nachhinein oft nur noch als Graph sichtbar ist. Ist der Angriff eine wohlgeformte HTTP-Flut statt einer volumetrischen, ist das der Fall für ein L7-Schild, denn Anfragenfluten sind auf Paketebene nicht von echten Nutzern zu unterscheiden und müssen weiter oben beurteilt werden. Haben Sie überhaupt keine Mitigation, sind Ihre realistischen Optionen, hinter einen Edge zu ziehen, der das hat, oder zu warten — und Ersteres zu planen, bevor der nächste Angriff kommt.

  7. 07

    Den Kreis schließen: verifizieren, zurückbauen, dann aufschreiben

    Verifizieren Sie von außerhalb der Maschine, nicht aus einer Shell auf ihr. Machen Sie dann die Notfallmaßnahmen gezielt rückgängig, behalten Sie die, die schon immer eine gute Idee waren, und halten Sie die Zahlen fest, damit der nächste Vorfall von einer Baseline aus startet statt von einer Schätzung.

    # from somewhere else entirely: is the site healthy for a normal user?
    curl -s -o /dev/null -w 'code=%{http_code} ttfb=%{time_starttransfer}s\n' \
         https://example.com/
    
    # did you leave a limit that is biting real people?
    grep -c 'limiting requests' /var/log/nginx/error.log
    
    # what is still blocked, and when does it expire?
    ipset list flood | head -30

    Behalten Sie den Cache, die Timeouts und die Syncookies — das sind dauerhafte Verbesserungen. Setzen Sie die aggressiven Rate Limits auf Ihre gemessene Baseline plus Puffer zurück, und lassen Sie die ipset-Einträge auslaufen. Schreiben Sie dann die vier Befehle aus den Schritten eins und zwei in ein Runbook, das nicht auf diesem Server liegt, direkt neben Ihrer normalen Anfragerate pro Sekunde und Ihrer normalen Spitzenbandbreite. Der nächste Angriff wird allein deshalb ein kürzerer Vorfall, weil diese beiden Zahlen existieren.

SP·10 — FAQ

Schnelle Antworten

Wie unterscheide ich einen echten DDoS von einer Traffic-Spitze?

Achten Sie auf die Form, nicht auf die Größe. Organische Spitzen haben Struktur: Sie kommen aus vielen Netzwerken, die User-Agents sind ein unordentlicher Long Tail, Clients laden nach dem HTML noch Ihr CSS und Ihre Bilder nach, und der Referrer verweist meist auf etwas Echtes. Eine Flut ist flach und repetitiv — dieselbe Handvoll Agents, keine Anfragen nach statischen Assets, gleichmäßige Raten pro Client, und oft einzigartige Query-Strings, die gezielt Caching aushebeln. Zwei Dinge lassen sich außerdem schnell ausschließen: Prüfen Sie Ihr Deploy-Log und Ihre Cron-Tabelle, bevor Sie irgendjemandem die Schuld geben, denn eine vor einer Stunde ausgelieferte langsame Query erzeugt dieselben Symptome und braucht die entgegengesetzte Lösung.

Können iptables oder fail2ban einen DDoS stoppen?

Sie helfen gegen kleine, konzentrierte Angriffe und bringen nichts gegen volumetrische. Beide laufen auf der Maschine am Ende der Leitung, sodass das Paket Ihre Bandbreite schon verbraucht hat, wenn eine Regel greift — Sie sparen CPU-Zyklen, keine Leitungskapazität. fail2ban ist außerdem von Natur aus reaktiv: Es liest ein Log im Nachhinein, was bei einer Flut um Minuten zu spät ist, und es kann Ihren eigenen Reverse-Proxy bannen, wenn Sie die echte Client-Adresse nicht konfiguriert haben. Nutzen Sie beide als Hygiene gegen Brute Force und Scanner; nutzen Sie Upstream-Scrubbing gegen Volumen.

Hilft es, die IP-Adresse meines Servers zu ändern?

Kurz und selten, und es kostet Sie jeden DNS-Cache der Welt. Zielt der Angreifer auf einen Hostnamen, steht die neue Adresse innerhalb von Minuten im DNS, und die Flut folgt ihr; der Umzug bringt nur dann etwas, wenn das Ziel die nackte Adresse ist und der Angreifer keine einfache Möglichkeit hat, sie neu aufzulösen. Die Version, die wirklich funktioniert, ist struktureller Natur statt kosmetisch: Stellen Sie einen austauschbaren Edge davor, halten Sie den Origin aus dem öffentlichen Internet unerreichbar, und dann ist die angegriffene Adresse eine, die Sie in 15 min verwerfen können, ohne Ihre Daten anzufassen.

Fügt DDoS-Mitigation Latenz hinzu oder bricht sie etwas?

Layer-3/4-Scrubbing ist durchgehend aktiv und praktisch unsichtbar — Pakete laufen durch einen Filterpfad, statt nur während eines Ereignisses umgeleitet zu werden, es gibt also keinen Failover-Moment und keine messbare Einbuße beim normalen Traffic. Filterung auf Anwendungsebene ist anders, weil zu beurteilen, ob eine Anfrage von einem Menschen stammt, manchmal bedeutet, sie herauszufordern, und jede solche Challenge trifft eine kleine Zahl ungewöhnlicher Clients. Die beiden Fehlerarten, die eine Planung wert sind, sind zwischengespeicherte Antworten, die an eingeloggte Nutzer ausgeliefert werden — das ist ein Cache-Key-Problem, kein Mitigations-Problem — und API-Clients, die eine Challenge nicht beantworten können, weshalb Sie Ihre API-Pfade gezielt ausnehmen, statt es erst hinterher zu entdecken.

Könnte mein Server derjenige sein, der jemand anderen angreift?

Das kommt häufiger vor, als man denkt, und die Symptome sind umgekehrt: hohe ausgehende Bandbreite, normale eingehende, eine Anwendung, die sich unauffällig anfühlt, und eine Abuse-Meldung als erstes echtes Signal. Die üblichen Ursachen sind ein offener DNS-Resolver, ein exponierter NTP- oder Memcached-Dienst, oder ein Container, der einen Port auf 0.0.0.0 veröffentlicht und dabei seine eigene Firewall-Regel vor Ihre geschrieben hat. Führen Sie ss -tulpn aus und stellen Sie sicher, dass nichts Unbeabsichtigtes an eine öffentliche Adresse gebunden ist. Ist der ausgehende Traffic hoch und kein legitimer Dienst erklärt das, behandeln Sie es als Kompromittierung und bauen Sie aus einem bekanntermaßen sauberen Backup neu auf, statt zu versuchen, sich herauszufiltern.

L3/4-Schutz ist inklusive — brauche ich trotzdem ein L7-Schild?

Das hängt vollständig davon ab, was Sie betreiben. Eine statische Seite, ein Game-Server oder alles, bei dem die Last aus Paketen statt aus gerenderten Seiten besteht, ist mit Scrubbing auf Netzwerkebene allein gut abgedeckt. Eine dynamische Anwendung mit teuren Endpunkten — Suche, Login, Checkout, eine API, die die Datenbank anfasst — kann von ein paar Tausend völlig gültigen Anfragen pro Sekunde lahmgelegt werden, gegen die kein Paketfilter je etwas einzuwenden hätte, und genau dafür ist ein Schild auf Anwendungsebene da. Der billige erste Schritt ist aber nicht das Add-on: Es sind der Micro-Cache und die Rate Limits pro Pfad aus den Schritten drei und vier, die den größten Teil des arithmetischen Vorteils kostenlos wegnehmen.

In die Praxis umsetzen

VPS in 15 min online, dedizierter Server übergeben in 2–12 h. Laden Sie ab $30.00 in Krypto auf — ohne angehängte Identität.

Einen VPS bereitstellen