NGINX. ЛИМИТ ЧАСТОТЫ ЗАПРОСОВ.
Немного об ограничении частоты запросов к определённому адресу на сервере с Nginx и настройке исключений для такого ограничения.
Настраиваем лимиты.
Простое ограничение на частоту запросов выглядит так:
limit_req_zone $binary_remote_addr zone=one:10m rate=30r/m; server { # ... location /login.php { limit_req zone=one; # ... } }
Здесь мы используя limit_req_zone обозначаем:
- Ключ $binary_remote_addr — это бинарное представление IP адреса. Оно занимает меньше места чем строковое, что бывает критично.
- Зону one — заданного размера часть памяти, в которой будет храниться информация о состоянии IP и его обращениях к серверу.
- Rate лимит — лимит на количество обращений за определённый отрезок времени.
Обозначенную зону далее мы просто применяем на нужный location. В примере, была создана зона one, которая ограничивает частоту обращений к /login.php 30 запросами в минуту с одного IP.
Белый список IP.
Исключить применение лимитов для определённых IP адресов можно с помощью директив map и geo. Пример создания такого белого списка ниже:
geo $limit { default 1; 10.0.0.0/8 0; 192.168.0.0/24 0; 1.2.3.4/29 0; } map $limit $limit_key { 0 ""; 1 $binary_remote_addr; } limit_req_zone $limit_key zone=one:10m rate=5r/s; server { location / { limit_req zone=one burst=10 nodelay; # ... } }
В данном примере, с помощью geo мы задаём список, в котором для нужных нам подсетей мы передаём 0, а для всех остальных 1. Затем, с помощью map мы задаём ключ $limit_key относительно значения $limit.
Для подсетей из белого списка $limit имеет значение 0, а значит в $limit_key будет передана пустая строка. Для остальных IP $limit имеет значение 1, а значит в $limit_key будет передано значение $binary_remote_addr.
Затем нам остаётся просто обозначить зону one, и применить её для нужного location. Если всё будет сделано верно, то IP, не входящие в белый список, будут попадать под заданные ограничения.
Несколько зон для location.
Кроме того, для IP из такого списка мы можем так же задать отдельные ограничения. При этом, для одного location просто будут использоваться две разных зоны:
limit_req_zone $limit_key zone=def:10m rate=10r/s; limit_req_zone $binary_remote_addr zone=one:10m rate=30r/s; server { # ... location / { limit_req zone=def burst=10 nodelay; limit_req zone=one burst=20 nodelay; # ... } }
В данном примере, для location актуальны две зоны. IP попавшие в зону def, имеют ограничение на 10 запросов в секунду, в то время как IP из зоны one имеют расширенный лимит в 30 запросов в секунду.
В примерах так же используется параметры burst и nodelay. Nginx позволяет указать, какое количество запросов клиент может выполнить сверх обозначенного зоной лимита. Запросы превышающие лимит, встают в очередь, размер этой очереди и задаётся параметром burst. Для того что бы сократить время обработки очереди, вместе с параметром burst можно использовать параметр nodelay.