Белый список IP для limit_req в NGINX

zexis
На сайте с 09.08.2005
Offline
388
5384

В NGINX есть уникальная возможность для ограничения количества запросов с одного IP за период времени.

С помощью нее можно эффективно снизить нагрузку от быстрых ботов при ддос атаке.

Реализуется она с помощью команд limit_req в файле конфигурации NGINX.

Пример.

limit_req_zone $binary_remote_addr zone=one:10m rate=1r/s;

limit_req zone=one burst=5 nodelay;

В этом примере скорость кликов с одного IP будет не чаще 1 клика в секунду. Но будут разрешатся кратковременные всплески интенсивности длиной до 5 кликов.

Важный момент здесь в том что limit_req_zone ставится в блок http.

А limit_req ставится только в локейшен проксирующий на бэкенд.

Что бы не было ограничений на запросы к статике, так как картинок на одной странице сайта может быть очень много и их количество не нужно ограничивать.

Как это реализовано внутри NGINX.

1. В системе создается массив счетчиков целого типа для каждого поступающего на сервер IP.

2. Каждую секунду значение каждого из счетчиков уменьшается на величину rate. (Например на 1 каждую секунду).

3. Если значение какого то счетчика становится меньше 0, он удаляется.

4. При каждом запросе с IP адреса (попавшего в локейшн с параметром limit_req) значение счетчика для него увеличивается на 1. Если это первый клик с этого IP то счетчик для него создается новый со значением 1.

5. Если при очередном клике счетчик этого IP превысит значение burst. То значит этот IP превысил скорость и ему отдается ошибка 503. При этом проксирование запроса на бэкенд не происходит.

6. Корректный ответ IP сможет получить лишь при снижении его счетчика ниже величины burst.

Таким образом можно удобно ограничивать скорость запросов с одного IP, но разрешать кратковременные всплески активности до величины burst.

Но есть боты которые работают слишком быстро, и их скорость не нужно ограничивать.

Например, боты sape.ru.

Вопрос.

Как можно сделать белый список подсетей, для которых не будет действовать ограничение limit_req?

Мои эксперименты в этом не дали успехов.

Пытался делать отдельные локейшены в nginx в которые бы попадали боты с определенных IP , но локейшн в nginx определяется URL страницы а не IP клиента.

Кто нибудь смог сделать белые списки для параметра limit_req?

DV
На сайте с 01.05.2010
Offline
644
#1

http://serverfault.com/questions/450077/nginx-limit-req-zone-ip-exceptions

Проверять надо.

Единственное, там надо все IP в конфиг сувать. Поддерживались бы таблицы, как в IPFW…

VDS хостинг ( http://clck.ru/0u97l ) Нет нерешаемых задач ( https://searchengines.guru/ru/forum/806725 ) | Перенос сайтов на Drupal 7 с любых CMS. ( https://searchengines.guru/ru/forum/531842/page6#comment_10504844 )
A
На сайте с 19.07.2010
Offline
130
#2

Для списков белых/серых/черных я использую http://nginx.org/ru/docs/http/ngx_http_geo_module.html

Для каждой подсети/ip присваивается какая-то цифра определяющая степень плохости.

Файлы подсетей формируются сторонним софтом или руками и просто инклудятся в конфиг nginx-а

Потом в нужном месте конфига ставлю:

if ($geo = '8'){ bla-bla.... }

if ($geo = '666'){ return 444; } ;)

Маленький хинт: не ставьте limit_req на отдачу статики(.js, .css) и картинок их отдавайте без ограничений, т.к. будут клиниться обычные браузеры. Лучше поставьте более жесткие ограничения на хтмл.

.............
Andreyka
На сайте с 19.02.2005
Offline
822
#3

Разумеется можно (и нужно).

Только работать надо не с IP а с user-agent, потому что IP могут сменить, а вот user-agent у сапобота стабильный.

Как разгребусь с насущными проблемами - выложу статью как это делать.

Не стоит плодить сущности без необходимости
A
На сайте с 19.07.2010
Offline
130
#4
Andreyka:
Только работать надо не с IP а с user-agent, потому что IP могут сменить, а вот user-agent у сапобота стабильный.

плохой совет. юзер-агент легко подделывается, да и сапа вряд-ли гарантирует неизменность юзер-агента.

сапа, линкфид и другие биржи сами сообщают актуальные ip своих ботов.

достаточно к этим ip добавить маску /24

zexis
На сайте с 09.08.2005
Offline
388
#5
DenisVS:
http://serverfault.com/questions/450077/nginx-limit-req-zone-ip-exceptions
Проверять надо.
Единственное, там надо все IP в конфиг сувать. Поддерживались бы таблицы, как в IPFW…

спасибо, проверил.

Пример работает как надо.

geo $limited_ip {

default 1;

127.0.0.1 0;

99.99.99.99 0;

}

map $limited_ip $limited_ip_key {

0 '';

1 $binary_remote_addr;

}

limit_req_zone $limited_ip_key zone=one:10m rate=5r/s;;

---------- Добавлено 19.04.2013 в 16:34 ----------

admak:
Для списков белых/серых/черных я использую http://nginx.org/ru/docs/http/ngx_http_geo_module.html
Для каждой подсети/ip присваивается какая-то цифра определяющая степень плохости.
Файлы подсетей формируются сторонним софтом или руками и просто инклудятся в конфиг nginx-а

Потом в нужном месте конфига ставлю:
if ($geo = '8'){ bla-bla.... }
if ($geo = '666'){ return 444; } ;)

такую конструкцию для белого списка

if ($geo = '8'){ bla-bla.... }

использовать не получится, так как

limit_req нельзя ставить в блок if

У меня в NGINX на это выдается ошибка

[emerg]: "limit_req" directive is not allowed here in /usr/local/nginx/conf/nginx.conf

Andreyka
На сайте с 19.02.2005
Offline
822
#6

По этому нужно делать internal location и редиректить на него

A
На сайте с 19.07.2010
Offline
130
#7

или сделайте внутренний редирект через error_page, как-то так:


error_page 555 = @nolimit
....
if ($geo = '8'){ return 555; } # можно return 555; дергать откуда угодно
....

location @nolimit {
// обращение к бекенду

}

Авторизуйтесь или зарегистрируйтесь, чтобы оставить комментарий