Vulnerability Scanner als DDoS: Webserver gegen aggressive Bots absichern

Image Description
Christopher Zechendorf
02.04.2026
Share:

Ein einzelner Scanner legte eine TYPO3-Website lahm — nicht durch DDoS, sondern durch PHP-FPM-Worker-Erschöpfung. So haben wir den Server abgesichert.

Vulnerability Scanner als DDoS: Webserver gegen aggressive Bots absichern

Die Herausforderung

An einem Vormittag bemerkten wir über unser Monitoring eine erhöhte Antwortzeit bei VINUM.eu. Innerhalb weniger Minuten war die Website für reguläre Besucher nicht mehr erreichbar — Requests liefen in Timeouts. Die Ursache war kein klassischer DDoS-Angriff mit massenhaft verteiltem Traffic, sondern ein einzelner Vulnerability Scanner von der IP 185.177.72.50.

Der Scanner feuerte in nur 8 Minuten rund 964 Requests gegen die Website. Dabei probierte er systematisch typische Angriffsvektoren durch: .env-Dateien, WordPress-Endpunkte wie wp-json, wp-content und wp-admin, xmlrpc.php und diverse andere bekannte Pfade. Keiner dieser Pfade existierte auf der TYPO3-Installation — aber genau das war das Problem.

Warum das Rate Limit nicht griff

Auf dem Server war bereits ein Rate Limit von 5 Requests pro Sekunde konfiguriert. Im Durchschnitt lag der Scanner mit ca. 2 Requests pro Sekunde deutlich darunter. Allerdings öffnete er viele Verbindungen gleichzeitig, die parallel auf eine Antwort warteten. Jeder dieser Requests landete bei PHP-FPM, weil nginx die nicht existierenden Pfade an TYPO3 weiterreichte — und TYPO3 brauchte für jede 404-Antwort den vollen Rendering-Durchlauf.

Das Ergebnis: Alle 20 konfigurierten pm.max_children-Worker in PHP-FPM waren belegt. Legitime Requests von echten Besuchern konnten nicht mehr bedient werden und liefen in eine Queue, die sich über ca. 15 Minuten aufbaute.

Das Rate Limit schützt gegen Anfragen pro Sekunde — aber nicht gegen viele gleichzeitig offene Verbindungen, die jeweils einen Worker blockieren. Ein klassischer Fall, in dem Request Rate und Connection Concurrency zwei unterschiedliche Probleme sind.

Unsere Lösung

Die Absicherung besteht aus zwei Ebenen: nginx begrenzt die gleichzeitigen Verbindungen pro IP, und fail2ban sperrt Scanner anhand ihrer typischen Request-Muster komplett aus.

Nginx Connection Limiting

Zusätzlich zum bestehenden Rate Limit haben wir ein Connection Limit eingeführt. In der nginx.conf wird zunächst eine Shared-Memory-Zone definiert:

http {
    # Bestehend: Rate Limit
    limit_req_zone $remote_addr zone=per_ip_rate:10m rate=5r/s;

    # Neu: Connection Limit
    limit_conn_zone $remote_addr zone=per_ip:10m;
}

In den PHP-Locations für das Frontend wird das Limit dann aktiviert:

location ~ \.php$ {
    # Connection Limit: max. 10 gleichzeitige Verbindungen pro IP
    limit_conn per_ip 10;

    # Rate Limit: Burst von 15 auf 8 reduziert
    limit_req zone=per_ip_rate burst=8 nodelay;

    fastcgi_pass unix:/run/php/php-fpm.sock;
    # ... weitere fastcgi-Parameter
}

Für das TYPO3-Backend (/typo3/) erlauben wir etwas mehr gleichzeitige Verbindungen, da Redakteure im Backend naturgemäss mehr parallele Requests erzeugen (AJAX-Calls, Modul-Loads etc.):

location /typo3/ {
    limit_conn per_ip 15;
    limit_req zone=per_ip_rate burst=8 nodelay;

    # ... Backend-spezifische Konfiguration
}

Mit limit_conn per_ip 10 kann eine einzelne IP maximal 10 Verbindungen gleichzeitig offen halten. Der Scanner, der dutzende parallele Connections aufbaute, wird damit auf 10 begrenzt — die restlichen Verbindungen erhalten sofort einen 503 Service Temporarily Unavailable. Die PHP-FPM-Worker bleiben für legitime Besucher verfügbar.

fail2ban Scanner-Jail

Das Connection Limit begrenzt den Schaden, aber ein Vulnerability Scanner hat auf der Website grundsätzlich nichts verloren. Mit einem fail2ban-Jail erkennen wir typische Scanner-Muster und sperren die IP komplett per Firewall.

Der Filter (/etc/fail2ban/filter.d/nginx-scanner.conf):

[Definition]
failregex = ^<HOST> .* "(GET|POST|HEAD) /\.env.*"
            ^<HOST> .* "(GET|POST|HEAD) /wp-(admin|content|includes|json|login).*"
            ^<HOST> .* "(GET|POST|HEAD) /xmlrpc\.php.*"
            ^<HOST> .* "(GET|POST|HEAD) /administrator/.*"
            ^<HOST> .* "(GET|POST|HEAD) /config\.(php|yml|json|bak).*"
            ^<HOST> .* "(GET|POST|HEAD) /\.git/.*"

ignoreregex =

Das zugehörige Jail (/etc/fail2ban/jail.d/nginx-scanner.conf):

[nginx-scanner]
enabled  = true
port     = http,https
filter   = nginx-scanner
logpath  = /var/log/nginx/access.log
maxretry = 3
findtime = 600
bantime  = 86400
action   = iptables-multiport[name=scanner, port="http,https", protocol=tcp]

Mit maxretry = 3 und findtime = 600 wird eine IP gesperrt, sobald sie innerhalb von 10 Minuten 3 dieser typischen Scanner-Requests absetzt. Die Sperre (bantime = 86400) gilt für 24 Stunden. Damit wäre der Scanner aus unserem Vorfall bereits nach seinen ersten drei Probing-Versuchen geblockt worden — weit bevor er die PHP-FPM-Worker hätte erschöpfen können.

Das Ergebnis

Die Kombination aus Connection Limiting und fail2ban bietet einen zweischichtigen Schutz:

  1. Sofortwirkung durch Connection Limit: Selbst wenn ein Scanner noch nicht von fail2ban erkannt wurde, kann er maximal 10 gleichzeitige Verbindungen aufbauen. Die restlichen PHP-FPM-Worker bleiben für regulären Traffic verfügbar.

  2. Nachhaltige Sperre durch fail2ban: Scanner werden anhand ihrer typischen Muster erkannt und per Firewall komplett ausgesperrt — ohne dass ein einziger PHP-FPM-Worker belastet wird.

  3. Kein Einfluss auf reguläre Besucher: 10 gleichzeitige Verbindungen pro IP sind für normales Browsing mehr als ausreichend. Auch der reduzierte Burst-Wert von 8 schränkt reguläre Nutzer nicht ein.

Diese Massnahmen sind nicht TYPO3-spezifisch. Jede PHP-Anwendung, die hinter nginx und PHP-FPM läuft — ob WordPress, Symfony oder Laravel — profitiert von dieser Absicherung. Entscheidend ist, dass Rate Limiting allein nicht ausreicht: Wer nur Requests pro Sekunde begrenzt, übersieht das Problem gleichzeitig offener Verbindungen, die Worker blockieren.


Steht Ihre Website regelmässig unter Beschuss durch Scanner oder Bots? Wir analysieren Ihre Server-Konfiguration und implementieren passende Schutzmassnahmen. Nehmen Sie über unser Kontaktformular unverbindlich Kontakt mit uns auf.

Interesse geweckt? Top-Stories direkt in Ihre Mailbox:

Share:

Über den Autor

Christopher Zechendorf

Christopher Zechendorf

Christopher Zechendorf leitet die ext.dev GmbH und bringt über 25 Jahre Erfahrung in Webentwicklung, CMS-Systemen und Infrastruktur mit.

Ähnliche Beiträge