Хотим добавить ограничение частоты запросов для какого-то ресурса. Пример запроса:
http://test.one/somefile_105_907.png
Используем nginx. Примеры на базе CentOS 7.
Добавляем в nginx реверсивный прокси. Теперь все запросы будем принимать на другой адрес, ограничивать частоту посещения и перенаправлять на старый адрес. Новый адрес:
http://test.two/somefile_105_907.png
В начало блока http добавляем маппинг параметров для API-ключей, подключаем в него внешний файл с самими ключами, создаем правило ограничения доступа:
#/etc/nginx/nginx.conf:
http {
map $http_api_key $limit {
include /etc/nginx/conf.d/apikeys.map;
default $binary_remote_addr;
}
limit_req_zone $limit zone=apikey:10m rate=12r/m;
# Тут остальная часть прежнего конфига...
}
Добавляем сам файл с ключами:
#/etc/nginx/conf.d/apikeys.map:
111 '';
222 '';
Модифицируем блок конфигурации дефолтного сервера nginx (блок server / location):
#/etc/nginx/conf.d/default.conf:
server {
listen 80;
server_name test.two;
location / {
limit_req zone=apikey nodelay;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_pass http://test.one/;
}
}
Внимание! default.conf взят для минимизации примера, в реальных условиях используйте свои конфиги.
Описание работы:
- Запрос поступает на http://test.two/somefile_105_907.png
- Анализируется HTTP-Header «API-KEY». Берется его значение в переменную $http_api_key
- $http_api_key сверяется со списком из файла apikeys.map
- Если соответствие найдено, то переменной $limit устанавливается пустое значение (запрос не будет участвовать в анализе частоты обращений)
- Если нет соответствия, то переменной $limit устанавливается значение, равное IP адресу запроса. Такой запрос будет обрабатываться по правилам, указанным в limit_req_zone. Частота запросов будет ограничена (1 раз / 5 секунд) (rate=12r/m);
- Если фильтрация не требуется - то запрос передается на http://test.one/somefile_105_907.png, ответ возвращается обратно.
Примеры запросов с помощью утилиты CURL:
# Такие запросы будут проходить без ограничений:
curl "http://test.two/somefile_105_907.png" -H "Api-Key: 111"
curl "http://test.two/somefile_105_907.png" -H "Api-Key: 222"
# А такие будут фильтроваться по правилам:
curl "http://test.two/somefile_105_907.png" -H "Api-Key: 121"
curl "http://test.two/somefile_105_907.png"
Ссылки:
https://serverfault.com/questions/784852/nginx-conf-for-limit-req-based-on-http-header
http://nginx.org/ru/docs/http/ngx_http_limit_req_module.html
http://nginx.org/ru/docs/http/ngx_http_map_module.html
https://habr.com/ru/company/southbridge/blog/329876/