Taxa do NGINX O Limiting interrompe as solicitações automatizadas, reduz os picos de carga e protege os pontos finais de início de sessão, API e formulários contra bots e ataques. Vou mostrar-te como definir limites e aplicá-los a Proteção contra bots aplica e, a partir daí, desenvolve um conceito de segurança robusto para sites com elevado tráfego.
Pontos centrais
Essencial estas são as ideias-chave:
- Limites de taxas impedem ataques maliciosos e protegem os recursos de backend.
- Burst/sem atraso detetam picos legítimos sem bloquear os utilizadores.
- zonas distinguir pessoas e bots com limites diferentes.
- Registo fornece dados para aperfeiçoar os limites de forma iterativa.
- Integração com WAF, proteção contra DDoS e monitorização, aumenta a eficácia.
Por que razão a limitação de taxa impede os ataques numa fase inicial
Os atacantes apostam em um alto Taxas de pedidos, para abusar de formulários de início de sessão, sobrecarregar APIs ou extrair conteúdos de forma automatizada. Por isso, limito as solicitações por chave – geralmente por IP – e decido se as devo restringir, atrasar ou responder com um código 429. Desta forma, mantenho o tráfego de bots afastado da CPU, da base de dados e da lógica da aplicação, permitindo o acesso aos utilizadores legítimos. Caminhos particularmente sensíveis, como /login, /auth, /xmlrpc.php ou pesquisas que consomem muitos recursos, beneficiam significativamente desta abordagem. A fonte deste procedimento é a Documentação do Nginx sobre o ngx_http_limit_req_module.
Funcionamento do módulo NGINX na prática
O módulo funciona de acordo com o Balde com fugasPrincípio: Para cada chave, o NGINX armazena os valores de contagem numa zona e compara-os com a taxa permitida. Chaves típicas são $binary_remote_addr para endereços IP, tokens para chaves de API ou valores derivados através de map. Se um cliente exceder de forma persistente a taxa e o buffer de picos, o NGINX rejeita o pedido antes de o enviar para o backend. Isto poupa tempo de processamento e reduz as latências para os visitantes reais. Defino a resposta como 429 Too Many Requests ou, opcionalmente, outra Código de estado um.
Configuração: explicada passo a passo
Começo por definir uma zona na secção HTTP, estabeleço uma taxa moderada e ativo-a de forma seletiva em percursos sensíveis. Para picos de curta duração, defino um «burst», opcionalmente com «nodelay», para evitar rejeições abruptas. Em seguida, testo no ambiente de teste e analiso os registos antes de ativar a funcionalidade no ambiente de produção. Desta forma, não corro o risco de bloquear inutilmente utilizadores reais. Um exemplo conciso ilustra o Sintaxe tangível:
# http {}
limit_req_zone $binary_remote_addr zone=req_limit_per_ip:10m rate=10r/s;
server {
location /api/ {
limit_req zone=req_limit_per_ip burst=20 nodelay;
limit_req_status 429;
}
location /login {
limit_req zone=req_limit_per_ip burst=5;
limit_req_status 429;
}
}
Proteção contra bots com zonas e lógica de user-agent
Os limites baseados em IP raramente são suficientes contra botnets distribuídas; por isso, separo o tráfego em zonas: As pessoas recebem valores mais generosos, enquanto os rastreadores genéricos recebem valores mais restritivos. Com o `map`, avalio os user-agents, identifico bots isentos, como o Googlebot, e atribuo-lhes limites próprios, rigorosamente controlados. Para os scrapers desconhecidos, estabeleço limites rigorosos em percursos dispendiosos. Se forem detetados padrões suspeitos, aumentei dinamicamente o rigor até que o Taxa está novamente dentro dos limites aceitáveis.
Ajustes finos: taxa, burst, nodelay e códigos de estado
A taxa regula o débito por segundo, o burst permite buffering de curta duração e o nodelay determina se prefiro o buffering ou a passagem imediata. Começo de forma moderada, por exemplo, 10r/s com burst 20 nas APIs, e vou ajustando após a análise dos registos. Para as rotas de início de sessão, defino, por exemplo, 1r/s com um pequeno burst, para travar os ataques de força bruta. Em caso de excedentes, devolvo um código de erro 429, porque os clientes, com isso, dar-se bem e a lógica de nova tentativa funciona corretamente. Em casos específicos, utilizo códigos alternativos, quando os clientes assim o solicitam.
Visão geral na tabela: diretivas e utilização
O seguinte Tabela resume as diretrizes fundamentais e indica em que situações estas se justificam.
| diretiva | Efeito | Exemplo | Utilização típica |
|---|---|---|---|
| limit_req_zone | Defina a chave, a zona e Taxa firmemente | limit_req_zone $binary_remote_addr zone=perip:10m rate=10r/s; | Base por IP, token ou agente do utilizador |
| limite_req | Ativa o limite em Localização/Servidor | limit_req zone=perip burst=20 nodelay; | Controlo preciso por caminho ou vHost |
| limit_req_status | Define o código HTTP em Excesso | limit_req_status 429; | Comportamento adequado do cliente e novas tentativas |
| mapa | Redireciona os pedidos para zonas em | map $http_user_agent $is_bot {…} | Distinção entre bot e utilizador com base no User-Agent |
Na prática: proteger de forma específica o ponto final de início de sessão
Limito o /login de forma muito rigorosa, porque os bots tentam adivinhar palavras-passe com elevada Frequência Experimentar. 1 r/s com burst 3 evita tentativas massivas, sem afetar demasiado os utilizadores reais. Além disso, registo as tentativas falhadas repetidas no log para bloquear temporariamente os endereços IP. Em combinação com a autenticação de dois fatores (2FA) e, opcionalmente, o Captcha, a pressão sobre a base de dados e a gestão de sessões diminui significativamente. Desta forma, mantenho o número de tentativas falhadas baixo e garanto que o Acesse pronto e estável.
Na prática: disponibilizar APIs de forma justa e controlada
As APIs requerem diretrizes claras Probabilidades, para que os clientes individuais não ocupem toda a largura de banda. Para rotas gerais, defino 10 r/s e um pico de 20; para pontos finais mais caros, aplico valores mais restritivos. Quando há tokens ou chaves de API disponíveis, imponho limites por token em vez de por IP. Isto garante a equidade entre os clientes e evita abusos. Para uma abordagem mais aprofundada, consulte a minha nota sobre Limitação de taxas da API, que enquadra o conceito de forma mais ampla.
Monitorização, registo e aperfeiçoamento iterativo
Registo 429 respostas, incluindo Chave (por exemplo, IP ou token) e o caminho, para identificar padrões. Picos em poucos caminhos indicam scraping ou ataques de força bruta; uma pressão distribuída aponta para redes de bots. Com estes dados, aplico limites apenas onde é necessário e minimizo os falsos positivos. Os painéis com taxas, taxa de erro e latência mostram-me o impacto de cada alteração. Assim, a Desempenho elevada, enquanto a proteção aumenta.
Integração num conceito de proteção holístico
Considero a limitação de taxa um primeiro passo importante camada, mas combino-o com regras WAF, reputação de IP e reforço de TLS. Contra ataques de grande volume, ajuda uma proteção DDoS a montante, que filtra o tráfego ao nível da rede antes de o NGINX ter de entrar em ação. Mido continuamente as métricas, defino alarmes para picos invulgares e reajo com atualizações das regras. Assim, a partir de vários elementos, cria-se uma rede de proteção robusta. Estas fornecem uma visão geral prática Estratégias contra ataques DDoS.
Padrões de configuração concretos para bots vs. pessoas
Separo os visitantes em categorias com o map e encaminho-os para as respetivas zonas. Os rastreadores conhecidos têm limites moderados, enquanto os agentes genéricos têm limites mais restritivos. Em relação a percursos como /search ou /report, sou mais rigoroso, uma vez que consomem muitos recursos da CPU. Em caso de infrações recorrentes, não aumentei os limites, mas sim bloqueio temporariamente o acesso ou transfiro a verificação para um módulo de deteção de bots. Desta forma, a Taxa de utilização indevida baixo, sem interferir com os motores de busca.
Exemplo: Duas zonas e mapeamento de User-Agent
O fragmento seguinte mostra a separação por Agente do utilizador e a atribuição de limites adequados. Combino isso com códigos de estado diferenciados e campos de registo para medir o impacto de forma precisa. Os bots com um agente genérico são encaminhados para a zona mais restritiva. As pessoas ou os rastreadores verificados utilizam a zona mais flexível. Esta abordagem proporciona resultados previsíveis Produções por turma:
map $http_user_agent $is_bot {
default 0;
"~*googlebot" 0;
"~*bingbot" 0;
"~*crawler|scraper|bot" 1;
}
limit_req_zone $binary_remote_addr zone=human:10m rate=10r/s;
limit_req_zone $binary_remote_addr zone=bot:10m rate=1r/s;
server {
location / {
if ($is_bot) {
limit_req zone=bot burst=5;
}
if ($is_bot = 0) {
limit_req zone=human burst=20 nodelay;
}
limit_req_status 429;
}
}
Gestão de erros: comunicar corretamente o erro 429
No que diz respeito aos limites, dou uma resposta clara Resposta indicando quando é aconselhável fazer uma nova tentativa. No caso das APIs, isso inclui o cabeçalho «Retry-After» válido, para que os clientes apliquem o mecanismo de «backoff». Os utilizadores humanos recebem uma breve explicação sem detalhes técnicos. Isto reduz o número de tickets e garante um comportamento compreensível. Uma abordagem clara UX torna os limites aceitáveis e evita a frustração.
Provedor de alojamento, rede e kernel: reforçar as bases
Um elevado volume de tráfego legítimo e as medidas de defesa exigem soluções fiáveis Recursos e predefinições adequadas ao nível da rede. Presto atenção às versões mais recentes do NGINX, à quantidade suficiente de RAM para as zonas e às funcionalidades de proteção contra ataques de transporte. Para combater os ataques SYN-Flood, é útil ativar Cookies TCP SYN no kernel, para que as ligações não fiquem bloqueadas. Em suma, isto alivia o NGINX de uma carga desnecessária. Assim, concentro os limites nas camadas HTTP e mantenho o Rendimento estável.
Em resumo: eis como utilizo eficazmente a limitação de taxa do NGINX
Limito os pedidos a chave, isolo os caminhos críticos e mantenho os bots afastados através de zonas restritas. As funcionalidades «Burst» e «nodelay» ajudam a permitir picos legítimos sem incentivar abusos. Através dos registos 429, calibro os valores de forma contínua e só aumento os limites quando é necessário. Em combinação com o WAF, a defesa contra DDoS, a monitorização e o reforço do kernel, surge um conceito de proteção robusto. Quem o implementar de forma consistente reduz significativamente o tráfego de bots e preserva Desempenho mesmo sob carga.
Elementos que frequentemente faltam na prática
Em muitas configurações, faltam alguns componentes essenciais que aumentam significativamente a eficácia da limitação de taxa:
- IP real do cliente por trás de proxies: Sem um tratamento correto do IP real, o NGINX limita frequentemente o IP do equilibrador de carga – os limites passam então a aplicar-se a todos os utilizadores agrupados a jusante.
- Testes a seco (Dry-Run): Os limites são ativados „às cegas“. É melhor registar previamente apenas quantas vezes um limite teria sido aplicado.
- Chaves de granularidade fina: Em vez de limitar apenas por IP, vale a pena estabelecer limites por token de API, sessão ou utilizador, para aumentar a equidade.
- Interação com o limit_conn: As ligações paralelas e as taxas de pedidos abrangem diferentes padrões de abuso.
- Exceções específicas: As verificações de estado, os webhooks ou os serviços internos requerem, muitas vezes, limites mais flexíveis ou nenhum limite.
Proxy reverso: analisar com segurança o IP real do cliente
Se o NGINX estiver atrás de um balanceador de carga, defino as diretivas Real-IP para que $binary_remote_addr reflita o cliente real. Só confio nas redes que me pertencem e ativo a avaliação recursiva:
http {
# Intervalos de IP de proxy de confiança (exemplo)
set_real_ip_from 10.0.0.0/8;
set_real_ip_from 192.168.0.0/16;
# Adicione, se necessário, intervalos públicos de LB/CDN
real_ip_header X-Forwarded-For;
real_ip_recursive on;
limit_req_zone $binary_remote_addr zone=perip:20m rate=10r/s;
}
Sem esta configuração, um limite acabaria por afetar indevidamente muitos utilizadores ao mesmo tempo. Após a configuração, verifico nos registos de acesso se o endereço IP do cliente esperado aparece.
Estratégia-chave: IP, utilizador, token e percurso
A chave escolhida determina a equidade e o impacto. Alguns modelos comprovados:
- Pro IP ($binary_remote_addr): Rápido de configurar, adequado para /login e pontos finais anónimos.
- Por token da API: Equidade entre clientes; protege contra o agrupamento NAT. Extraio tokens através do map.
- Por turma de escuteiros: Limitar separadamente os pontos finais mais dispendiosos, por exemplo, /search mais do que /status.
map $http_authorization $api_token {
default "";
"~*^Bearer\s+(.+)$" $1;
}
limit_req_zone $api_token zone=per_token:30m rate=5r/s;
server {
location /api/ {
# Apenas se aplica se houver um token
limit_req zone=per_token burst=10;
limit_req_status 429;
}
}
Importante: uma cardinalidade elevada das chaves consome memória na zona. Preveja uma margem de segurança e acompanhe a utilização da memória.
Armazenamento e dimensionamento das zonas
A zona armazena metadados por cada chave ativa. O consumo por entrada é de algumas dezenas de bytes, mais a sobrecarga. Daí deduzo que:
- Para um grande número de IPs/tokens simultâneos, opto por zonas maiores, por exemplo, 50–100 MB.
- Começo com uma configuração bastante generosa e analiso os registos do NGINX: a mensagem „shared memory zone is full“ indica que é necessário ajustar a configuração.
- As chaves não utilizadas caducam após um curto período de inatividade; os picos são mais importantes do que a média diária.
Utilizar o Burst e o nodelay com precisão
Sem nodelay o NGINX agrupa os excedentes dentro do buffer de picos e atrasado Pedidos. Com nodelay As solicitações em rajada permitidas são imediatamente aceites, enquanto as excedentes são rejeitadas. O meu procedimento:
- Percursos interativos (HTML): de preferência sem «nodelay», para gerar tempos de espera curtos em vez de erros 429 definitivos.
- APIs: frequentemente com «nodelay», para que os clientes recebam claramente o código de erro 429 e apliquem o backoff.
- Terminais dispendiosos: um pequeno burst para suavizar os picos do backend.
Simulação, nível de registo e análise
Antes de ativar os limites, ativo o Dry-Run e ajusto o nível de registo. Assim, consigo ver o efeito sem correr riscos:
server {
location /api/ {
limit_req zone=perip burst=20;
limit_req_dry_run on; # apenas registar, não bloquear
limit_req_log_level notice; # menos grave do que 'error'
}
}
Em seguida, analiso os dados de acesso relativos a um período de 3 a 7 dias, identifico os pontos críticos, ajusto a taxa/pico e só então desativo o Dry-Run.
429: como fazer o transporte de forma correta: HTML, JSON e Retry-After
Para garantir uma boa experiência do utilizador (UX), faço a distinção entre navegadores e clientes API e defino Retry-After. Eis como comunico os limites de forma clara:
map $http_accept $wants_json {
default 0;
"~*application/json|/json" 1;
}
server {
error_page 429 = @rate_limited;
location @rate_limited {
add_header Retry-After 2 always;
if ($wants_json) {
add_header Content-Type application/json;
return 429 '{"error":"too_many_requests","retry_after":2}';
}
return 429 "Por favor, tente novamente mais tarde.";
}
}
As APIs podem assim responder de forma programática, e os utilizadores recebem uma mensagem clara.
Combinar o `limit_req` e o `limit_conn`
limite_req rendimento por intervalo de tempo, limite_conexão limita as ligações simultâneas. Para combater downloads, clientes que enviam muitos dados ou picos de tráfego HTTP/2, combino as duas medidas:
limit_conn_zone $binary_remote_addr zone=perip_conn:10m;
server {
location /api/ {
limit_req zone=perip burst=20 nodelay;
limit_conn zone=perip_conn 20; # máximo de 20 ligações simultâneas por IP
}
}
Desta forma, evito que alguns clientes, embora respeitem a velocidade, ocupem recursos com demasiadas ligações em paralelo.
Exceções, verificações de estado e percursos internos
Nem todos os percursos precisam de limites. As verificações de estado (/healthz), os webhooks internos ou os callbacks de pagamento recebem localizações próprias sem `limit_req` — ou com valores mais flexíveis:
server {
# sem limites para verificações de integridade
location = /healthz { return 200 "ok"; }
# limites suaves para callbacks de pagamento
location /webhooks/pay/ {
limit_req zone=perip burst=5;
}
# proteção mais rigorosa para o início de sessão
location = /login {
limit_req zone=perip rate=1r/s burst=3;
}
}
As exceções granulares reduzem os falsos positivos e mantêm as integrações estáveis.
Roteamento por zonas mais robusto sem a «magia» do If
Para a separação „Bot vs. Pessoa“, prefiro redirecionamentos internos através de localizações nomeadas. Isso torna a configuração clara e previsível:
map $http_user_agent $is_bot {
default 0;
"~*googlebot|bingbot" 0;
"~*crawler|scraper|bot" 1;
}
limit_req_zone $binary_remote_addr zone=human:20m rate=10r/s;
limit_req_zone $binary_remote_addr zone=bot:10m rate=1r/s;
server {
error_page 418 = @bot;
location / {
if ($is_bot) { return 418; } # desvio interno
limit_req zone=human burst=20 nodelay;
limit_req_status 429;
try_files $uri $uri/ /index.html;
}
location @bot {
limit_req zone=bot burst=5;
limit_req_status 429;
}
}
Assim, os bots acabam por ir parar, de forma determinística, à zona rigorosa, enquanto as pessoas vão para a zona descontraída – sem que ambos os limites se apliquem simultaneamente.
Experimentar, medir, vestir: um processo pragmático
- Encenação: Selecionar uma taxa/série de transmissão conservadora, ativar o Dry-Run e testar a carga sintética no caminho ativo.
- Ensaios de fumo: Gerar pequenas rajadas com o curl ou o Lasttools e verificar o comportamento do código 429/atraso.
- Piloto de Produção: A princípio, aplicar a locais específicos e acompanhar de perto os registos.
- Afiar de forma iterativa: Apenas definir limites nos casos em que se observem padrões; minimizar os falsos alarmes.
Exemplo #: teste de rajada rápida com o curl
for i in {1..50}; do curl -s -o /dev/null -w "%{http_code}\n" https://example.com/login & done; wait
Taxas por minuto em vez de por segundo e percursos granulares
O NGINX permite definir intervalos em segundos ou minutos (r/s, r/m). No caso de uso indevido do login, costumo definir 60r/m em vez de 1r/s, para permitir duplos cliques legítimos de curta duração, mas limitar os cliques em sequência contínua. Os percursos mais caros têm limites mais restritos do que os mais baratos. Exemplo:
limit_req_zone $binary_remote_addr zone=perip_min:20m rate=60r/m;
server {
location /search/ {
limit_req zone=perip_min burst=10; # mais rigoroso
}
location /status {
# sem limite – barato e utilizado internamente
return 200;
}
}
Obstáculos e como os evito
- Chave errada: Quando utilizo proxies sem IP real, acabo por limitar acidentalmente todos os utilizadores em conjunto.
- Zonas demasiado pequenas: „zone is full“ leva a um comportamento imprevisível – dimensionar com margem de segurança.
- Um limite para tudo: Caminhos diferentes exigem valores diferentes; uma abordagem única para todos gera frustração.
- Sem controlo: Sem a análise 429, as configurações incorretas passam despercebidas.
- Lista de exceções: As exceções demasiado amplas abrem as portas a todo o tipo de problemas – criar uma lista de exceções específica, temporária e transparente.
Características específicas do HTTP/2, SSE e cache
O HTTP/2 agrupa os pedidos em poucas ligações; limite_conexão continua, no entanto, a ser relevante, pois os streams consomem recursos. Os Server-Sent Events ou downloads demorados raramente ativam limites de taxa (poucas solicitações), mas consomem tempo – neste caso, aplico limites em paralelo com o `limit_conn` ou implemento estratégias de largura de banda. Sempre que possível, alivio a carga com Armazenamento em cache (por exemplo, recursos estáticos, pedidos GET frequentes), para que os limites sejam aplicados com menos frequência e os utilizadores obtenham respostas mais rápidas.
Lista de verificação operacional
- IP real correto, chave definida (IP/token/utilizador)
- Zonas com dimensões generosas, métricas/registos disponíveis
- taxa/burst ajustada por classe de caminho, nodelay definido deliberadamente
- Testado em simulação, comunicação 429 (Retry-After) implementada
- Exceções para Health/Webhooks, combinação com limit_conn
- Reajustamento iterativo e alertas em caso de anomalias


