Как ограничить скорость соединений (запросов) в NGINX
В нашей последней статье из серии «Управление трафиком NGINX» мы обсуждали, как ограничить количество соединений в NGINX. В этом руководстве мы рассмотрим, как ограничить частоту запросов в NGINX.
Ограничение скорости – это метод управления трафиком, используемый для ограничения количества HTTP запросов, которые клиент может сделать за определенный период времени. Ограничения скорости рассчитываются в запросах в секунду (или RPS).
Примером запроса является запрос GET для страницы входа в приложение, запрос POST в форме входа или POST . на конечной точке API.
Существует множество причин ограничить частоту запросов к вашим веб-приложениям или службам API, одна из которых — безопасность: защита от неправомерных быстрых запросов.
Ограничение скорости соединений в NGINX
Начните с определения параметров ограничения скорости с помощью директивы limit_req_zone
. Обязательными параметрами являются ключ для идентификации клиентов, зона общей памяти, в которой будет храниться состояние ключа и частота доступа к URL-адресу с ограниченным запросом, а также скорость.
Директива limit_req_zone
действительна в контексте HTTP.
limit_req_zone $binary_remote_addr zone=limitreqsbyaddr:20m rate=10r/s;
Кроме того, установите код состояния ответа, который возвращается в отклоненные запросы, используя директиву limit_req_status
, которая действительна в контексте HTTP, сервера и местоположения.
limit_req_status 429;
Теперь вы можете использовать директиву limint_conn
, чтобы включить ограничение скорости запросов в контексте HTTP, сервера и местоположения. Он принимает зону памяти в качестве параметра и другие дополнительные параметры.
limit_req zone=limitreqsbyaddr;
В следующем примере конфигурации показано ограничение частоты запросов к API веб-приложения. Размер общей памяти составляет 20 МБ, а ограничение скорости запросов — 10 запросов в секунду.
upstream api_service {
server 127.0.0.1:9051;
server 10.1.1.77:9052;
}
limit_req_zone $binary_remote_addr zone=limitreqsbyaddr:20m rate=10r/s;
limit_req_status 429;
server {
listen 80;
server_name testapp.linux-console.net;
root /var/www/html/testapp.linux-console.net/build;
index index.html;
#include snippets/error_pages.conf;
proxy_read_timeout 600;
proxy_connect_timeout 600;
proxy_send_timeout 600;
location / {
try_files $uri $uri/ /index.html =404 =403 =500;
}
location /api {
limit_req zone=limitreqsbyaddr;
proxy_pass http://api_service;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header Host $host;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
}
}
Сохраните файл конфигурации и закройте его.
Затем проверьте правильность синтаксиса конфигурации NGINX с помощью следующей команды:
sudo nginx -t
После этого перезагрузите сервис NGINX и примените последние изменения:
sudo systemctl reload nginx
Как только предел скорости 10 запросов в секунду превышается одним клиентом, обращающимся к /api/
, NGINX возвращает сообщение «429 Слишком много запросов». ошибка клиенту.
Он также регистрирует инцидент в журнале ошибок.
2022/04/29 00:30:38 [error] 3145846#0: *131039 limiting requests, excess: 0.990 by zone "limitreqsbyaddr", client: 192.168.1.10, server: testapp.linux-console.net, request: "GET /api/v1/app/meta-data HTTP/1.1", host: "testapp.linux-console.net", referrer: "https://testapp.linux-console.net/"
Иногда, в зависимости от характера вашего приложения или API, клиенту необходимо сделать много запросов одновременно, а затем на некоторое время снизить скорость, прежде чем делать больше. NGINX также может буферизовать любые лишние запросы в очереди и оперативно их обрабатывать.
Вы можете включить это поведение при ограничении скорости, используя параметр burst
с директивой limit_req
. Чтобы включить организацию очереди без задержки, добавьте параметр nodelay
.
limit_req zone=limitreqsbyaddr burst=20 nodelay;
Существует проблема с ограничением скорости на основе IP-адреса клиента, особенно для пользователей, получающих доступ к вашему приложению из той же сети и работающих за NAT. В этом случае все их запросы будут исходить с одного и того же IP-адреса. В таком сценарии вы можете использовать другие переменные для идентификации клиентов, например файл cookie сеанса.
Для получения дополнительной информации об ограничении скорости запросов ознакомьтесь с этим ограничением скорости NGINX на веб-сайте NGINX. Далее мы рассмотрим, как ограничить использование полосы пропускания в NGINX.