Wie kann man die Rate in Nginx begrenzen, aber bestimmte IP-Adressen ein- / ausschließen?
27
Ich kann limit_reqalle Anfragen an meinen Server mit einer Ratenbeschränkung versehen.
Ich möchte jedoch die Ratenbeschränkung für bestimmte IP-Adressen (z. B. Whitelist) aufheben und für bestimmte andere (z. B. bestimmte IP-Adressen, die nur 1 r / s betragen sollen) eine andere Ratenbeschränkung verwenden.
Ich habe versucht, Bedingungen zu verwenden (z. B. if ( $remote_addr = "1.2.3.4" ) {}), aber das scheint nur mit Umschreiberegeln zu funktionieren, nicht für Ratenbegrenzungsregeln.
Es ist wirklich besser, die Verwendung der "if" -Direktive zu vermeiden. Wenn der Schlüssel in limit_req_zone (und limit_conn_zone) leer ist, werden die Grenzwerte nicht angewendet. Sie können dies in Verbindung mit den Karten- und Geomodulen verwenden, um eine Whitelist mit IPs zu erstellen, bei denen die Gasgrenzwerte nicht angewendet werden.
In diesem Beispiel wird gezeigt, wie Sie ein Limit sowohl für gleichzeitige Anforderungen als auch für die Anforderungsrate von einer einzelnen IP konfigurieren.
http {
geo $whitelist {
default 0;
# CIDR in the list below are not limited
1.2.3.0/24 1;
9.10.11.12/32 1;
127.0.0.1/32 1;
}
map $whitelist $limit {
0 $binary_remote_addr;
1 "";
}
# The directives below limit concurrent connections from a
# non-whitelisted IP address to five
limit_conn_zone $limit zone=connlimit:10m;
limit_conn connlimit 5;
limit_conn_log_level warn; # logging level when threshold exceeded
limit_conn_status 503; # the error code to return
# The code below limits the number requests from a non-whitelisted IP
# to one every two seconds with up to 3 requests per IP delayed
# until the average time between responses reaches the threshold.
# Further requests over and above this limit will result
# in an immediate 503 error.
limit_req_zone $limit zone=one:10m rate=30r/m;
limit_req zone=one burst=3;
limit_req_log_level warn;
limit_req_status 503;
Die Zonenanweisungen müssen auf der http-Ebene platziert werden, die anderen Anweisungen können jedoch weiter unten platziert werden, z. B. auf dem Server oder auf der Standortebene, um deren Umfang einzuschränken oder die Grenzen weiter anzupassen.
Was ist der Unterschied zwischen diesen beiden Modulen?
mente
1
Gemäß
Können Sie erklären, warum Sie das Mapping in zwei Schritten durchführen, geogefolgt von map, anstatt es nur geozum $limitdirekten Einstellen zu verwenden ?
Marcus Downing
2
Es scheint, dass geoes keiner Variablen zugeordnet werden kann. Wenn Sie also $binary_remote_addreinen Zuordnungswert angeben, wird dies in die Literalzeichenfolge übersetzt "$binary_remote_addr", nicht in den Wert der Variablen.
ColinM
1
Ich möchte hinzufügen, dass, wenn die fragliche IP bereits in der Zone ist, Sie nginx neu starten müssen ; ein nachladen reicht nicht aus.
Halfgaar
5
Sie können problemlos benannte Speicherorte verwenden, z. B. "@Location" in einem if () - Block.
Geben Sie "location @slowdown {}" mit den gleichen Informationen wie "location / {}" ein, z. B. "proxy_pass", wenn Sie "nginx" als Reverse-Proxy verwenden.
Ich bin nicht sicher, ob ich den 410 Teil verstehe? Wird dem Client tatsächlich ein http 410-Statuscode angezeigt?
Svrist
1
Wow, das funktioniert tatsächlich! Sehr geschickter error_pageTrick, +1! @svrist, unter serverfault.com/a/870170/110020 finden Sie eine vollständige Erklärung, wie und warum so etwas funktionieren würde.
geo
gefolgt vonmap
, anstatt es nurgeo
zum$limit
direkten Einstellen zu verwenden ?geo
es keiner Variablen zugeordnet werden kann. Wenn Sie also$binary_remote_addr
einen Zuordnungswert angeben, wird dies in die Literalzeichenfolge übersetzt"$binary_remote_addr"
, nicht in den Wert der Variablen.Sie können problemlos benannte Speicherorte verwenden, z. B. "@Location" in einem if () - Block.
Siehe: http://wiki.nginx.org/IfIsEvil
So etwas sollte funktionieren:
Geben Sie "location @slowdown {}" mit den gleichen Informationen wie "location / {}" ein, z. B. "proxy_pass", wenn Sie "nginx" als Reverse-Proxy verwenden.
quelle
error_page
Trick, +1! @svrist, unter serverfault.com/a/870170/110020 finden Sie eine vollständige Erklärung, wie und warum so etwas funktionieren würde.