Этот ответ идеально подходит для обхода ограничения скорости с помощью IP-адресов.
Если мне нужно обойти ограничение скорости с помощью секретного заголовка, как мне этого добиться?
Ссылка:
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 "";
}
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
Обычная причина этих вопросов заключается в том, что большинство этих директив нельзя использовать в контексте оператора if
, следовательно, как можно было бы условно указать разные пределы?
Ответ заключается в использовании промежуточных переменных - так же, как в связанном ответе, используйте установку ограничений с помощью переменных, где впоследствии значения этих переменных будут различаться в зависимости от карты
или оператор if
.
http {
map $http_x_secret_header $limit {
default $binary_remote_addr;
secretvalue "";
}
limit_conn_zone $limit zone=connlimit:10m;
…
Ссылка:
FWIIW, я также просмотрел другой «странный» ответ на вопрос, который вы ссылаетесь - он был написан в 2011 году, сегодня в 2017 году было только 3 положительных голоса. , по сравнению с 23 отзывами за цитируемый вами более свежий ответ от 2014 года. Возможно несколько удивительно, но более старый игнорируемый ответ на самом деле также работает без каких-либо проблем!
Вот мой взгляд на полную конфигурацию MVP, полностью протестированную:
server {
listen 7461;
error_page 429 = @slowdown;
if ($http_x_secret_header != secret_value) {
return 429;
}
location @slowdown {
#limit_...
return 200 "$uri: slowed down\n";
}
location / {
return 200 "$uri: very fast\n";
}
}
Вот тестирование, чтобы показать вам, что все это работает, включая тот факт, что возвращается правильный код 200 OK
:
%curl -H "X-Secret-Header: secret_value" localhost:7461/important/path/
/important/path/: very fast
%curl -H "X-Secret-Header: wrong_value" localhost:7461/important/path/
/important/path/: slowed down
%curl -v localhost:7461/important/path/ | & fgrep -e HTTP/ -e /important
> GET /important/path/ HTTP/1.1
< HTTP/1.1 200 OK
/important/path/: slowed down
%
Итак, да, перенаправление error_page
действительно работает!
Позвольте мне объяснить причину странного error_page
answer - в nginx вы можете выполнять как внешние перенаправления (видимые для клиента), так и внутренние перенаправления (выполняемые внутри, без любые промежуточные ответы клиенту).
Это внутреннее отличие от внешнего - очень мощная концепция, без которой многие крутые трюки не были бы возможно, поскольку язык конфигурации достаточно прост, чтобы ограничить количество директив, доступных из состояния if
мент, а также не разрешать вложенные операторы if
.
Таким образом, вместо этого, с внутренними перенаправлениями, $ uri
можно изменить внутренне, в результате чего ваш запрос будет перескакивать несколько независимых местоположений (представьте каждое местоположение
как состояние в DFA (детерминированном конечном автомате)), пока не будет достигнут желаемый результат (в качестве крайнего примера, взгляните на http: //mdoc.su/, как показано на nginx.conf 2016 ).
Подводя итог , в приведенном выше примере:
мы перепрофилируем 429
error_page
, чтобы действовать как внутреннее
перенаправление на внутреннее
местоположение
, а затем обрабатывать такое внутреннее
местоположение
в самом таким же образом, как было бы обработано не внутреннее местоположение, за исключением добавления некоторых дополнительных переменных или директив;
мы также используем параметр =
для error_page [121 70], чтобы указать nginx не отправлять код
429
обратно клиенту, а вместо этого позволить дальнейшей обработке определять, каким должен быть окончательный код состояния.