Eine Nginx-Website gegen einen Angriff auf Anwendungsebene (L7) schützen

Veröffentlicht am 21/08/2026 Aktualisiert am 06/10/2026 48 Aufrufe
Sécurité VPS Linux Nginx DDoS

Nicht alle Angriffe gleichen sich. Ein volumetrischer Angriff will die Netzwerkanbindung sättigen: ein Stau auf der Autobahn. Darum kümmert sich der Schutz von By-Hoster vorgelagert, ohne Ihr Zutun.

Ein Angriff auf Anwendungsebene, Schicht 7 genannt, ist etwas anderes. Der Datenverkehr bleibt bescheiden, doch jede Anfrage ist teuer: eine Suche, eine Anmeldeseite, ein Warenkorb. Für das Netzwerk sehen sie aus wie normale Besucher. Erst auf Ihrem Webserver wird die Natur des Verkehrs sichtbar, und genau dort muss man handeln.

Wie finde ich heraus, was meinen Server tatsächlich trifft?

Ändern Sie nichts, solange Sie nicht wissen, was ankommt. Eine aufs Geratewohl gesetzte Regel blockiert meist Ihre echten Besucher, ohne den Angreifer zu stören.

Die aktivsten IP-Adressen:

awk '{print $1}' /var/log/nginx/access.log | sort | uniq -c | sort -rn | head -20

Die am häufigsten angefragten URLs:

awk -F'"' '{print $2}' /var/log/nginx/access.log | sort | uniq -c | sort -rn | head -20

Der jüngste Verkehr, um die Intensität einzuschätzen:

tail -n 100000 /var/log/nginx/access.log | awk '{print $4}' | uniq -c | tail -20

Sie suchen ein Muster: eine Handvoll sehr gesprächiger Adressen, eine einzelne dauerhaft aufgerufene URL, überall derselbe User-Agent. Dieses Muster bestimmt die Regel, nicht umgekehrt.

Prüfen Sie auch, was tatsächlich ausgelastet ist:

uptime
systemctl status php8.3-fpm --no-pager

Oft knickt nicht Nginx ein, sondern PHP oder die dahinterliegende Datenbank.

Wie drossle ich Anfragen pro Adresse in Nginx?

Nginx kann Anfragen je Adresse zählen und diejenigen bremsen, die eine Schwelle überschreiten. Die Zonen werden im http-Block deklariert (/etc/nginx/nginx.conf):

http {
    limit_req_zone  $binary_remote_addr zone=req_pro_ip:10m rate=10r/s;
    limit_conn_zone $binary_remote_addr zone=conn_pro_ip:10m;
}

Angewendet wird im Server-Block:

server {
    limit_req  zone=req_pro_ip burst=20 nodelay;
    limit_conn conn_pro_ip 20;
}

Was das konkret bedeutet:

Einstellung Wirkung
rate=10r/s 10 Anfragen pro Sekunde und Adresse im Normalbetrieb
burst=20 duldet eine Spitze von 20 Anfragen über der Rate
nodelay bedient die Spitze sofort, statt sie zu strecken
limit_conn 20 höchstens 20 gleichzeitige Verbindungen je Adresse

Eine Zone von 10m merkt sich rund 160 000 Adressen, das reicht reichlich.

burst ohne nodelay stellt Anfragen in eine Warteschlange: die Seite wird langsam, statt abzuweisen. Mit nodelay kommt ein normaler Besucher, der eine Seite mit zwanzig Ressourcen lädt, ungebremst durch, während ein hartnäckiger Bot einen 503 erhält.

Schützen Sie wirklich teure URLs strenger als die gesamte Website:

location = /wp-login.php {
    limit_req zone=req_pro_ip burst=3 nodelay;
}

Wie teste ich die Nginx-Konfiguration, bevor ich sie anwende?

Mit nginx -t, das die Syntax prüft, ohne etwas anzuwenden, und danach mit einem Reload statt eines Neustarts.

nginx -t

Dieser Befehl prüft die Syntax, ohne etwas zu unterbrechen. Er muss syntax is ok und dann test is successful melden. Erst danach:

systemctl reload nginx

reload übernimmt die Konfiguration, ohne laufende Verbindungen zu kappen, anders als restart. Mitten im Angriff macht das einen Unterschied.

Beobachten Sie, was abgewiesen wird:

grep "limiting requests" /var/log/nginx/error.log | tail -20

Tauchen dort Ihre eigenen Adressen oder die Ihrer Kunden auf, ist das Limit zu niedrig. Erhöhen Sie es.

Wie erzeuge ich dieselbe Seite seltener neu?

Der beste Weg, einen Angriff abzufedern, ist oft, die Seite nicht bei jeder Anfrage neu zu berechnen. Eine 60 Sekunden lang zwischengespeicherte Seite kostet fast nichts, wie oft sie auch angefragt wird.

http {
    proxy_cache_path /var/cache/nginx levels=1:2 keys_zone=site:50m inactive=10m;
}
location / {
    proxy_cache site;
    proxy_cache_valid 200 60s;
    proxy_cache_use_stale error timeout updating;
}

proxy_cache_use_stale ist die rettende Zeile: antwortet das Backend nicht mehr, liefert Nginx weiter die letzte bekannte Fassung statt eines Fehlers.

Bei WordPress, PrestaShop oder Laravel erreicht ein Anwendungs-Cache dasselbe mit weniger Nebenwirkungen.

Wie sperre ich Wiederholungstäter mit fail2ban?

Drosseln bremst, Sperren stoppt. fail2ban liest die Protokolle und ergänzt eine Firewallregel gegen Adressen, die das Limit zu oft auslösen.

apt install fail2ban

In /etc/fail2ban/jail.local:

[nginx-limit-req]
enabled  = true
filter   = nginx-limit-req
logpath  = /var/log/nginx/error.log
maxretry = 10
findtime = 60
bantime  = 3600
systemctl restart fail2ban
fail2ban-client status nginx-limit-req

Laut gelesen besagt die Regel: eine Adresse, die innerhalb von 60 Sekunden zehnmal die Drosselung auslöst, wird eine Stunde lang blockiert.

Welche Einstellungen sollte ich bei einem Angriff auf Anwendungsebene meiden?

Diese Einstellungen kursieren häufig und schaden mehr, als sie nützen.

Vermeiden Warum
curl und wget über den User-Agent blockieren Ein Angreifer wechselt den Agent in einer Zeile. Sie zerlegen Ihre Überwachung, Ihre Zahlungs-Webhooks und Ihre Backup-Skripte.
client_max_body_size 1k Jeder Bildupload, jedes längere Formular, jedes CMS-Update schlägt fehl.
allow für ein Subnetz und dann deny all Sie schließen die Website für das gesamte Internet, Besucher inklusive. Heben Sie dieses Muster für Admin-URLs auf.
Reflexhaft ganze Länder sperren Viele Fehlalarme, und Angreifer mieten Maschinen überall.
Protokolle „für die Leistung“ abschalten Sie verlieren die einzige Möglichkeit zu verstehen, was gerade passiert.

Eine einfache Regel: jede Maßnahme, die breiter blockiert als das beobachtete Muster, bezahlen Sie mit verlorenen Kunden.

Wann sollte ich ein Ticket bei uns öffnen?

Wenn das Problem über das hinausgeht, was Sie auf der Maschine lösen können: gesättigte Leitung, langer Angriff oder Tausende Adressen.

Öffnen Sie ein Ticket, wenn:

  • die Maschine trotz dieser Einstellungen unerreichbar bleibt;
  • der Verkehr die Netzwerkanbindung sättigt, bevor er Nginx überhaupt erreicht;
  • der Angriff anhält und aus Tausenden verschiedenen Adressen kommt.

Hängen Sie die Log-Auszüge aus Schritt 1 und das betroffene Zeitfenster an. Erst das erlaubt uns, vorgelagert im Netzwerk zu handeln, wo Sie nicht eingreifen können.

War dieser Artikel hilfreich?