Ограничение частоты запросов по API-KEY с использованием Nginx

· 1 минута на чтение

Хотим добавить ограничение частоты запросов для какого-то ресурса. Пример запроса:

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/

Related Articles

Ограничение частоты запросов по API_KEY с использованием OpenResty и Docker

Предыдущий вариант ограничения был статичен, для внесения изменений в список API-KEY  требовался перезапуск Nginx. Нужно решение с динамическими ключами.  OpenResty

· 5 минуты на чтение