Por Que a Limitação de Taxa é Importante

Todo servidor web público está sujeito a picos de tráfego, scrapers automatizados, tentativas de força bruta e ataques de negação de serviço distribuído (DDoS). Sem limitação de taxa, um único cliente abusivo pode esgotar a CPU, memória e descritores de arquivo do seu servidor, tornando o serviço indisponível para usuários legítimos.

A limitação de taxa integrada do Nginx fornece uma camada de defesa leve e de alto desempenho que opera no nível do proxy reverso — antes que as requisições cheguem à sua aplicação.

Pré-requisitos

  • Nginx 1.18+ instalado (ambos os módulos são compilados por padrão).
  • Acesso sudo ou root para editar arquivos de configuração do Nginx.
  • Familiaridade básica com a sintaxe de configuração do Nginx.
  • Uma ferramenta de teste como curl, Apache Bench (ab) ou wrk.

Solução Passo a Passo

1. Definir uma Zona de Limitação

http {
    limit_req_zone $binary_remote_addr zone=api:10m rate=10r/s;
    limit_req_zone $binary_remote_addr zone=login:10m rate=5r/m;
    limit_req_zone $binary_remote_addr zone=general:10m rate=30r/s;
}

2. Aplicar Limites a Localizações

server {
    listen 80;
    server_name exemplo.com;

    limit_req zone=general burst=50 nodelay;
    limit_req_status 429;

    location /api/auth/login {
        limit_req zone=login burst=3 nodelay;
        proxy_pass http://backend;
    }

    location /api/ {
        limit_req zone=api burst=20 nodelay;
        proxy_pass http://backend;
    }

    location /static/ {
        limit_req off;
        alias /var/www/static/;
    }
}

Entendendo burst e nodelay:

  • burst=N: Permite até N requisições extras acima do limite serem enfileiradas.
  • nodelay: Processa requisições de rajada imediatamente sem atraso.
  • delay=N: (Nginx 1.15.7+) Híbrido: as primeiras N requisições de rajada são processadas imediatamente, o restante é atrasado.

3. Configurar Limitação de Conexões

http {
    limit_conn_zone $binary_remote_addr zone=addr:10m;

    server {
        limit_conn addr 10;
        limit_conn_status 429;

        location /downloads/ {
            limit_conn addr 2;
            limit_rate 500k;
        }
    }
}

4. Excluir IPs Confiáveis

http {
    geo $limit_key {
        default         $binary_remote_addr;
        10.0.0.0/8      "";
        192.168.1.0/24  "";
        203.0.113.50    "";
    }

    limit_req_zone $limit_key zone=api:10m rate=10r/s;
}

5. Respostas de Erro Personalizadas

error_page 429 = @rate_limited;

location @rate_limited {
    default_type application/json;
    return 429 '{"error": "rate_limit_exceeded", "message": "Muitas requisições. Tente novamente em alguns segundos.", "retry_after": 1}';
}

6. Testar a Configuração

sudo nginx -t
sudo systemctl reload nginx
ab -n 100 -c 10 http://exemplo.com/api/data

Armadilhas e Casos Especiais

  • Cadeias de proxy reverso: Se Nginx está atrás de um balanceador de carga, use o módulo realip para extrair o IP real do cliente.
  • Endereços IPv6: $binary_remote_addr é 16 bytes para IPv6 (vs 4 para IPv4). Dimensione as zonas adequadamente.
  • Chaves API em vez de IPs: Para APIs autenticadas, use um header como chave.

Prevenção

  • Combine com um WAF: Use ModSecurity, Cloudflare ou AWS WAF para defesa em profundidade.
  • Use fail2ban: Bloqueie automaticamente IPs que excedam os limites persistentemente.
  • Monitore com métricas: Exporte métricas com o módulo stub_status e alerte sobre taxas elevadas de 429.

Resumo

  • A limitação de taxa do Nginx usa limit_req_zone/limit_req para taxas de requisição e limit_conn_zone/limit_conn para limites de conexão.
  • O algoritmo de balde furado suaviza picos de tráfego em vez de impor contagens rígidas por segundo.
  • Configure sempre burst e nodelay para cargas de produção.
  • Use limit_req_status 429 para retornar o código HTTP 429 padrão.

Artigos Relacionados