Rate Limiting mit nginx

Dieser Artikel erklärt, wie Sie das nginx HttpLimitReqModule verwenden, um die Anzahl der Anfragen für eine bestimmte Sitzung zu begrenzen. Dies ist z.B. nützlich, wenn Ihre Website von einem Bot gehämmert wird, der mehrere Anfragen pro Sekunde stellt und damit die Serverlast erhöht. Mit dem ngx_http_limit_req_module können Sie ein Ratenlimit definieren, und wenn ein Besucher diese Rate überschreitet, erhält er einen Fehler 503.

1 Verwendung des HttpLimitReqModuls (ngx_http_limit_req_module)

Öffnen Sie Ihre nginx.conf.…..

nano /etc/nginx/nginx.conf

…. und definieren Sie einen Bereich, in dem die Sitzungszustände gespeichert werden – dieser muss in den http {} Container gehen:

http {
    [...]
    limit_req_zone  $binary_remote_addr  zone=one:10m   rate=1r/s;
    [...]
}

Dieser Bereich wird als einer bezeichnet und erhält 10 MB Speicherplatz. Anstelle der Variablen $remote_addr verwenden wir die Variable $binary_remote_addr, die die Größe des Zustands auf 64 Bytes reduziert. Es kann etwa 16.000 Zustände in einer 1-MB-Zone geben, so dass 10 MB etwa 160.000 Zustände zulassen, also sollte dies für Ihre Besucher ausreichend sein. Die Rate ist auf eine Anfrage pro Sekunde begrenzt. Bitte beachten Sie, dass Sie hier ganzzahlige Werte verwenden müssen. Wenn Sie also die Grenze auf eine halbe Anforderung pro Sekunde festlegen möchten, verwenden Sie 30r/m (30 Anforderungen pro Minute).

Um dieses Limit zu nutzen, verwenden wir die limit_req-Direktive. Sie können diese Direktive in http {}-, server {}- und location {}-Containern verwenden, aber meiner Meinung nach ist sie am nützlichsten in location {}-Containern, die Anfragen an Ihre App-Server weiterleiten (PHP-FPM, mongrel, etc.), da Sie sonst, wenn Sie eine einzelne Seite mit vielen Bildern, CSS- und JavaScript-Dateien laden, wahrscheinlich die angegebene Ratenbegrenzung mit einer einzelnen Seitenanfrage überschreiten würden.

Also lasst uns das in einen Container stellen ~ \.php$ {}:

[...]
        location ~ \.php$ {
                try_files $uri =404;
                fastcgi_split_path_info ^(.+\.php)(/.+)$;
                fastcgi_pass unix:/var/run/php5-fpm.sock;
                fastcgi_index index.php;
                include fastcgi_params;
                limit_req zone=one burst=5;
        }
[...]

limit_req zone=one burst=5; gibt an, dass diese Ratenbegrenzung zu dem von uns zuvor definierten Session-Speicherbereich gehört (wegen zone=one), was bedeutet, dass die Ratenbegrenzung 1r/s beträgt. Du kannst dir die Bedeutung von Burst wie eine Art Warteschlange vorstellen. Das bedeutet, dass, wenn Sie die Ratenbegrenzung überschreiten, die folgenden Anforderungen verzögert werden, und nur wenn Sie mehr Anforderungen in der Warteschlange haben, als im burst-Parameter angegeben, erhalten Sie einen 503-Fehler (z.B. so):

Es galt ein Nginx-Satzlimit.

).

Wenn Sie diese Warteschlange nicht verwenden möchten (d.h. einen 503 sofort liefern, wenn jemand das Ratenlimit überschreitet), müssen Sie die Option nodelay verwenden:

[...]
        location ~ \.php$ {
                try_files $uri =404;
                fastcgi_split_path_info ^(.+\.php)(/.+)$;
                fastcgi_pass unix:/var/run/php5-fpm.sock;
                fastcgi_index index.php;
                include fastcgi_params;
                limit_req zone=one burst=5 nodelay;
        }
[...]

Vergiss nicht, nginx neu zu laden, damit deine Änderungen wirksam werden:

service nginx reload

2 Links

Über den Autor

Falko Timme ist der Eigentümer von nginx WebhostingTimme Hosting (ultraschnelles nginx Webhosting). Er ist der leitende Maintainer von HowtoForge (seit 2005) und einer der wichtigsten Entwickler von ISPConfig (seit 2000). Er hat auch am O’Reilly-Buch „Linux System Administration“ mitgewirkt.

Das könnte Dich auch interessieren …