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:

    nginx
    # /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;
    }
    Dica
    $binary_remote_addr usa o IP em formato binário (4 bytes) em vez de string — consome ~3x menos memória. 10m de memória suporta aproximadamente 160.000 IPs simultâneos.

    Aplicar rate limiting por rota

    Diferentes endpoints têm diferentes tolerâncias. Configure por rota:

    nginx
    # /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;
        }
    }
    Dica
    burst=20 permite uma rajada de até 20 requisições acima do limite antes de começar a rejeitar. nodelay processa o burst imediatamente em vez de enfileirar — melhor para APIs onde latência importa.

    Whitelist de IPs para rate limiting

    Exclua do rate limiting IPs internos e serviços conhecidos:

    nginx
    # /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 contados

    Respostas customizadas para rate limit excedido

    Retorne JSON para APIs em vez da página de erro padrão do Nginx:

    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:

    bash
    # 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.

    Perguntas frequentes