Rate limiting no Nginx para APIs
Rate limiting limita quantas requisições um IP pode fazer em determinado período — proteção essencial contra brute force em endpoints de login, DDoS de baixo volume e scraping abusivo. No Nginx, configure em menos de 10 linhas com limit_req_zone e tenha proteção imediata para todas as rotas.
Configuração básica de rate limiting
limit_req_zone define a zona de rate limiting; limit_req aplica em rotas específicas:
# /etc/nginx/nginx.conf — bloco http (antes dos includes)
http {
# Zona global: 10 req/s por IP, memória de 10MB (suporta ~160k IPs)
limit_req_zone $binary_remote_addr zone=api_limit:10m rate=10r/s;
# Zona específica para login: 5 req/min por IP
limit_req_zone $binary_remote_addr zone=login_limit:10m rate=5r/m;
# Zona para endpoints públicos: 30 req/s por IP
limit_req_zone $binary_remote_addr zone=public_limit:10m rate=30r/s;
# Retornar 429 (Too Many Requests) em vez de 503
limit_req_status 429;
}Aplicar rate limiting por rota
Diferentes endpoints têm diferentes tolerâncias. Configure por rota:
# /etc/nginx/sites-available/minha-api
server {
listen 443 ssl;
server_name api.seudominio.com.br;
# Endpoint de login: muito restritivo
location /auth/login {
limit_req zone=login_limit burst=3 nodelay;
proxy_pass http://app:3000;
}
# API geral: moderado com burst
location /api/ {
limit_req zone=api_limit burst=20 nodelay;
proxy_pass http://app:3000;
}
# Webhook: sem rate limit (origem conhecida)
location /webhooks/ {
allow 192.0.2.0/24; # IPs do serviço de webhook
deny all;
proxy_pass http://app:3000;
}
# Assets estáticos: sem rate limit
location /static/ {
root /var/www;
expires 1y;
}
}Whitelist de IPs para rate limiting
Exclua do rate limiting IPs internos e serviços conhecidos:
# /etc/nginx/nginx.conf
http {
# Mapa para whitelist de IPs
geo $limit {
default 1; # aplicar rate limit
127.0.0.1 0; # localhost — sem limite
10.0.0.0/8 0; # rede interna — sem limite
203.0.113.10 0; # IP fixo do escritório — sem limite
}
# Usar mapa na zona: IPs na whitelist têm chave vazia (sem limite)
map $limit $limit_key {
0 "";
1 $binary_remote_addr;
}
limit_req_zone $limit_key zone=api_limit:10m rate=10r/s;
}
# No server block, funciona normalmente:
# limit_req zone=api_limit burst=20;
# IPs da whitelist (limit_key="") não são contadosRespostas customizadas para rate limit excedido
Retorne JSON para APIs em vez da página de erro padrão do Nginx:
# /etc/nginx/sites-available/minha-api
server {
# Resposta JSON para 429
error_page 429 @rate_limit_exceeded;
location @rate_limit_exceeded {
add_header Content-Type application/json always;
add_header Retry-After 60 always;
return 429 '{"error":"rate_limit_exceeded","message":"Muitas requisições. Tente novamente em 60 segundos.","retry_after":60}';
}
# Logar requisições bloqueadas por rate limit
location /api/ {
limit_req zone=api_limit burst=20 nodelay;
limit_req_log_level warn; # warn (padrão) ou error
proxy_pass http://app:3000;
}
}Monitorar requisições bloqueadas
Verifique quantas requisições estão sendo bloqueadas:
# Ver logs de rate limit em tempo real
tail -f /var/log/nginx/error.log | grep "limiting requests"
# Contar bloqueios por período
grep "limiting requests" /var/log/nginx/error.log | \
grep "$(date +%Y/%m/%d)" | wc -l
# IPs mais bloqueados
grep "limiting requests" /var/log/nginx/error.log | \
grep -oE '[0-9]+\.[0-9]+\.[0-9]+\.[0-9]+' | \
sort | uniq -c | sort -rn | head -10
# Verificar configuração atual
nginx -T | grep limit_req$ runstack deploy --plan starter
Não quer configurar manualmente?
Não quer configurar manualmente? Implante o VPS em menos de 3 minutos com a Runstack. Infraestrutura da OPEN DATACENTER, com servidores no Brasil.