{"id":21255,"date":"2026-09-02T08:35:33","date_gmt":"2026-09-02T06:35:33","guid":{"rendered":"https:\/\/webhosting.de\/nginx-rate-limiting-schutz-vor-bot-traffic-angriffen-secure\/"},"modified":"2026-09-02T08:35:33","modified_gmt":"2026-09-02T06:35:33","slug":"nginx-limitacao-de-taxa-protecao-contra-ataques-de-trafego-de-bots-seguranca","status":"publish","type":"post","link":"https:\/\/webhosting.de\/pt\/nginx-rate-limiting-schutz-vor-bot-traffic-angriffen-secure\/","title":{"rendered":"Limita\u00e7\u00e3o de taxa do NGINX: prote\u00e7\u00e3o eficaz contra tr\u00e1fego de bots e ataques"},"content":{"rendered":"<p><strong>Taxa do NGINX<\/strong> O Limiting interrompe as solicita\u00e7\u00f5es automatizadas, reduz os picos de carga e protege os pontos finais de in\u00edcio de sess\u00e3o, API e formul\u00e1rios contra bots e ataques. Vou mostrar-te como definir limites e aplic\u00e1-los a <strong>Prote\u00e7\u00e3o contra bots<\/strong> aplica e, a partir da\u00ed, desenvolve um conceito de seguran\u00e7a robusto para sites com elevado tr\u00e1fego.<\/p>\n\n<h2>Pontos centrais<\/h2>\n\n<p><strong>Essencial<\/strong> estas s\u00e3o as ideias-chave:<\/p>\n<ul>\n  <li><strong>Limites de taxas<\/strong> impedem ataques maliciosos e protegem os recursos de backend.<\/li>\n  <li><strong>Burst\/sem atraso<\/strong> detetam picos leg\u00edtimos sem bloquear os utilizadores.<\/li>\n  <li><strong>zonas<\/strong> distinguir pessoas e bots com limites diferentes.<\/li>\n  <li><strong>Registo<\/strong> fornece dados para aperfei\u00e7oar os limites de forma iterativa.<\/li>\n  <li><strong>Integra\u00e7\u00e3o<\/strong> com WAF, prote\u00e7\u00e3o contra DDoS e monitoriza\u00e7\u00e3o, aumenta a efic\u00e1cia.<\/li>\n<\/ul>\n\n<h2>Por que raz\u00e3o a limita\u00e7\u00e3o de taxa impede os ataques numa fase inicial<\/h2>\n\n<p>Os atacantes apostam em um alto <strong>Taxas de pedidos<\/strong>, para abusar de formul\u00e1rios de in\u00edcio de sess\u00e3o, sobrecarregar APIs ou extrair conte\u00fados de forma automatizada. Por isso, limito as solicita\u00e7\u00f5es por chave \u2013 geralmente por IP \u2013 e decido se as devo restringir, atrasar ou responder com um c\u00f3digo 429. Desta forma, mantenho o tr\u00e1fego de bots afastado da CPU, da base de dados e da l\u00f3gica da aplica\u00e7\u00e3o, permitindo o acesso aos utilizadores leg\u00edtimos. Caminhos particularmente sens\u00edveis, como \/login, \/auth, \/xmlrpc.php ou pesquisas que consomem muitos recursos, beneficiam significativamente desta abordagem. A fonte deste procedimento \u00e9 a <strong>Documenta\u00e7\u00e3o do Nginx<\/strong> sobre o ngx_http_limit_req_module.<\/p>\n\n\n<figure class=\"wp-block-image size-full is-resized\">\n  <img fetchpriority=\"high\" decoding=\"async\" src=\"https:\/\/webhosting.de\/wp-content\/uploads\/2026\/09\/nginx-rate-limiting-rechenzentrum-4738.png\" alt=\"\" width=\"1536\" height=\"1024\"\/>\n<\/figure>\n\n\n<h2>Funcionamento do m\u00f3dulo NGINX na pr\u00e1tica<\/h2>\n\n<p>O m\u00f3dulo funciona de acordo com o <strong>Balde com fugas<\/strong>Princ\u00edpio: Para cada chave, o NGINX armazena os valores de contagem numa zona e compara-os com a taxa permitida. Chaves t\u00edpicas s\u00e3o $binary_remote_addr para endere\u00e7os IP, tokens para chaves de API ou valores derivados atrav\u00e9s 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\u00eancias para os visitantes reais. Defino a resposta como 429 Too Many Requests ou, opcionalmente, outra <strong>C\u00f3digo de estado<\/strong> um.<\/p>\n\n<h2>Configura\u00e7\u00e3o: explicada passo a passo<\/h2>\n\n<p>Come\u00e7o por definir uma zona na sec\u00e7\u00e3o HTTP, estabele\u00e7o uma taxa moderada e ativo-a de forma seletiva em percursos sens\u00edveis. Para picos de curta dura\u00e7\u00e3o, defino um \u00abburst\u00bb, opcionalmente com \u00abnodelay\u00bb, para evitar rejei\u00e7\u00f5es abruptas. Em seguida, testo no ambiente de teste e analiso os registos antes de ativar a funcionalidade no ambiente de produ\u00e7\u00e3o. Desta forma, n\u00e3o corro o risco de bloquear inutilmente utilizadores reais. Um exemplo conciso ilustra o <strong>Sintaxe<\/strong> tang\u00edvel:<\/p>\n\n<pre><code># http {}\nlimit_req_zone $binary_remote_addr zone=req_limit_per_ip:10m rate=10r\/s;\n\nserver {\n  location \/api\/ {\n    limit_req zone=req_limit_per_ip burst=20 nodelay;\n    limit_req_status 429;\n  }\n\n  location \/login {\n    limit_req zone=req_limit_per_ip burst=5;\n    limit_req_status 429;\n  }\n}\n<\/code><\/pre>\n\n<h2>Prote\u00e7\u00e3o contra bots com zonas e l\u00f3gica de user-agent<\/h2>\n\n<p>Os limites baseados em IP raramente s\u00e3o suficientes contra botnets distribu\u00eddas; por isso, separo o tr\u00e1fego em <strong>zonas<\/strong>: As pessoas recebem valores mais generosos, enquanto os rastreadores gen\u00e9ricos recebem valores mais restritivos. Com o `map`, avalio os user-agents, identifico bots isentos, como o Googlebot, e atribuo-lhes limites pr\u00f3prios, rigorosamente controlados. Para os scrapers desconhecidos, estabele\u00e7o limites rigorosos em percursos dispendiosos. Se forem detetados padr\u00f5es suspeitos, aumentei dinamicamente o rigor at\u00e9 que o <strong>Taxa<\/strong> est\u00e1 novamente dentro dos limites aceit\u00e1veis.<\/p>\n\n<h2>Ajustes finos: taxa, burst, nodelay e c\u00f3digos de estado<\/h2>\n\n<p>A taxa regula o d\u00e9bito por segundo, o burst permite buffering de curta dura\u00e7\u00e3o e o nodelay determina se prefiro o buffering ou a passagem imediata. Come\u00e7o de forma moderada, por exemplo, 10r\/s com burst 20 nas APIs, e vou ajustando ap\u00f3s a an\u00e1lise dos registos. Para as rotas de in\u00edcio de sess\u00e3o, defino, por exemplo, 1r\/s com um pequeno burst, para travar os ataques de for\u00e7a bruta. Em caso de excedentes, devolvo um c\u00f3digo de erro 429, porque os clientes, com isso, <strong>dar-se bem<\/strong> e a l\u00f3gica de nova tentativa funciona corretamente. Em casos espec\u00edficos, utilizo c\u00f3digos alternativos, quando os clientes assim o solicitam.<\/p>\n\n<h2>Vis\u00e3o geral na tabela: diretivas e utiliza\u00e7\u00e3o<\/h2>\n\n<p>O seguinte <strong>Tabela<\/strong> resume as diretrizes fundamentais e indica em que situa\u00e7\u00f5es estas se justificam.<\/p>\n\n<table>\n  <thead>\n    <tr>\n      <th>diretiva<\/th>\n      <th>Efeito<\/th>\n      <th>Exemplo<\/th>\n      <th>Utiliza\u00e7\u00e3o t\u00edpica<\/th>\n    <\/tr>\n  <\/thead>\n  <tbody>\n    <tr>\n      <td>limit_req_zone<\/td>\n      <td>Defina a chave, a zona e <strong>Taxa<\/strong> firmemente<\/td>\n      <td>limit_req_zone $binary_remote_addr zone=perip:10m rate=10r\/s;<\/td>\n      <td>Base por IP, token ou agente do utilizador<\/td>\n    <\/tr>\n    <tr>\n      <td>limite_req<\/td>\n      <td>Ativa o limite em <strong>Localiza\u00e7\u00e3o<\/strong>\/Servidor<\/td>\n      <td>limit_req zone=perip burst=20 nodelay;<\/td>\n      <td>Controlo preciso por caminho ou vHost<\/td>\n    <\/tr>\n    <tr>\n      <td>limit_req_status<\/td>\n      <td>Define o c\u00f3digo HTTP em <strong>Excesso<\/strong><\/td>\n      <td>limit_req_status 429;<\/td>\n      <td>Comportamento adequado do cliente e novas tentativas<\/td>\n    <\/tr>\n    <tr>\n      <td>mapa<\/td>\n      <td>Redireciona os pedidos para <strong>zonas<\/strong> em<\/td>\n      <td>map $http_user_agent $is_bot {\u2026}<\/td>\n      <td>Distin\u00e7\u00e3o entre bot e utilizador com base no User-Agent<\/td>\n    <\/tr>\n  <\/tbody>\n<\/table>\n\n\n<figure class=\"wp-block-image size-full is-resized\">\n  <img decoding=\"async\" src=\"https:\/\/webhosting.de\/wp-content\/uploads\/2026\/09\/NGINXLimitingMeeting1234.png\" alt=\"\" width=\"1536\" height=\"1024\"\/>\n<\/figure>\n\n\n<h2>Na pr\u00e1tica: proteger de forma espec\u00edfica o ponto final de in\u00edcio de sess\u00e3o<\/h2>\n\n<p>Limito o \/login de forma muito rigorosa, porque os bots tentam adivinhar palavras-passe com elevada <strong>Frequ\u00eancia<\/strong> Experimentar. 1 r\/s com burst 3 evita tentativas massivas, sem afetar demasiado os utilizadores reais. Al\u00e9m disso, registo as tentativas falhadas repetidas no log para bloquear temporariamente os endere\u00e7os IP. Em combina\u00e7\u00e3o com a autentica\u00e7\u00e3o de dois fatores (2FA) e, opcionalmente, o Captcha, a press\u00e3o sobre a base de dados e a gest\u00e3o de sess\u00f5es diminui significativamente. Desta forma, mantenho o n\u00famero de tentativas falhadas baixo e garanto que o <strong>Acesse<\/strong> pronto e est\u00e1vel.<\/p>\n\n<h2>Na pr\u00e1tica: disponibilizar APIs de forma justa e controlada<\/h2>\n\n<p>As APIs requerem diretrizes claras <strong>Probabilidades<\/strong>, para que os clientes individuais n\u00e3o 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\u00e1 tokens ou chaves de API dispon\u00edveis, 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 <a href=\"https:\/\/webhosting.de\/pt\/api-rate-limiting-hosting-protecao-contra-utilizacao-indevida-seguranca\/\">Limita\u00e7\u00e3o de taxas da API<\/a>, que enquadra o conceito de forma mais ampla.<\/p>\n\n\n<figure class=\"wp-block-image size-full is-resized\">\n  <img decoding=\"async\" src=\"https:\/\/webhosting.de\/wp-content\/uploads\/2026\/09\/nginx-rate-limiting-security-5721.png\" alt=\"\" width=\"1536\" height=\"1024\"\/>\n<\/figure>\n\n\n<h2>Monitoriza\u00e7\u00e3o, registo e aperfei\u00e7oamento iterativo<\/h2>\n\n<p>Registo 429 respostas, incluindo <strong>Chave<\/strong> (por exemplo, IP ou token) e o caminho, para identificar padr\u00f5es. Picos em poucos caminhos indicam scraping ou ataques de for\u00e7a bruta; uma press\u00e3o distribu\u00edda aponta para redes de bots. Com estes dados, aplico limites apenas onde \u00e9 necess\u00e1rio e minimizo os falsos positivos. Os pain\u00e9is com taxas, taxa de erro e lat\u00eancia mostram-me o impacto de cada altera\u00e7\u00e3o. Assim, a <strong>Desempenho<\/strong> elevada, enquanto a prote\u00e7\u00e3o aumenta.<\/p>\n\n<h2>Integra\u00e7\u00e3o num conceito de prote\u00e7\u00e3o hol\u00edstico<\/h2>\n\n<p>Considero a limita\u00e7\u00e3o de taxa um primeiro passo importante <strong>camada<\/strong>, mas combino-o com regras WAF, reputa\u00e7\u00e3o de IP e refor\u00e7o de TLS. Contra ataques de grande volume, ajuda uma prote\u00e7\u00e3o DDoS a montante, que filtra o tr\u00e1fego ao n\u00edvel da rede antes de o NGINX ter de entrar em a\u00e7\u00e3o. Mido continuamente as m\u00e9tricas, defino alarmes para picos invulgares e reajo com atualiza\u00e7\u00f5es das regras. Assim, a partir de v\u00e1rios elementos, cria-se uma rede de prote\u00e7\u00e3o robusta. Estas fornecem uma vis\u00e3o geral pr\u00e1tica <a href=\"https:\/\/webhosting.de\/pt\/ddos-mitigacao-webhosting-estrategias-protecao-rede\/\">Estrat\u00e9gias contra ataques DDoS<\/a>.<\/p>\n\n\n<figure class=\"wp-block-image size-full is-resized\">\n  <img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/webhosting.de\/wp-content\/uploads\/2026\/09\/nginx_schutz_tech_office_6352.png\" alt=\"\" width=\"1536\" height=\"1024\"\/>\n<\/figure>\n\n\n<h2>Padr\u00f5es de configura\u00e7\u00e3o concretos para bots vs. pessoas<\/h2>\n\n<p>Separo os visitantes em categorias com o map e encaminho-os para as respetivas <strong>zonas<\/strong>. Os rastreadores conhecidos t\u00eam limites moderados, enquanto os agentes gen\u00e9ricos t\u00eam limites mais restritivos. Em rela\u00e7\u00e3o a percursos como \/search ou \/report, sou mais rigoroso, uma vez que consomem muitos recursos da CPU. Em caso de infra\u00e7\u00f5es recorrentes, n\u00e3o aumentei os limites, mas sim bloqueio temporariamente o acesso ou transfiro a verifica\u00e7\u00e3o para um m\u00f3dulo de dete\u00e7\u00e3o de bots. Desta forma, a <strong>Taxa de utiliza\u00e7\u00e3o indevida<\/strong> baixo, sem interferir com os motores de busca.<\/p>\n\n<h2>Exemplo: Duas zonas e mapeamento de User-Agent<\/h2>\n\n<p>O fragmento seguinte mostra a separa\u00e7\u00e3o por <strong>Agente do utilizador<\/strong> e a atribui\u00e7\u00e3o de limites adequados. Combino isso com c\u00f3digos de estado diferenciados e campos de registo para medir o impacto de forma precisa. Os bots com um agente gen\u00e9rico s\u00e3o encaminhados para a zona mais restritiva. As pessoas ou os rastreadores verificados utilizam a zona mais flex\u00edvel. Esta abordagem proporciona resultados previs\u00edveis <strong>Produ\u00e7\u00f5es<\/strong> por turma:<\/p>\n\n<pre><code>map $http_user_agent $is_bot {\n  default 0;\n  \"~*googlebot\"     0;\n  \"~*bingbot\" 0;\n  \"~*crawler|scraper|bot\" 1;\n}\n\nlimit_req_zone $binary_remote_addr zone=human:10m rate=10r\/s;\nlimit_req_zone $binary_remote_addr zone=bot:10m   rate=1r\/s;\n\nserver {\n  location \/ {\n    if ($is_bot) {\n limit_req zone=bot burst=5;\n    }\n    if ($is_bot = 0) {\n limit_req zone=human burst=20 nodelay;\n    }\n    limit_req_status 429;\n  }\n}\n<\/code><\/pre>\n\n\n<figure class=\"wp-block-image size-full is-resized\">\n  <img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/webhosting.de\/wp-content\/uploads\/2026\/09\/nginx_rate_limiting_schutz_3947.png\" alt=\"\" width=\"1536\" height=\"1024\"\/>\n<\/figure>\n\n\n<h2>Gest\u00e3o de erros: comunicar corretamente o erro 429<\/h2>\n\n<p>No que diz respeito aos limites, dou uma resposta clara <strong>Resposta<\/strong> indicando quando \u00e9 aconselh\u00e1vel fazer uma nova tentativa. No caso das APIs, isso inclui o cabe\u00e7alho \u00abRetry-After\u00bb v\u00e1lido, para que os clientes apliquem o mecanismo de \u00abbackoff\u00bb. Os utilizadores humanos recebem uma breve explica\u00e7\u00e3o sem detalhes t\u00e9cnicos. Isto reduz o n\u00famero de tickets e garante um comportamento compreens\u00edvel. Uma abordagem clara <strong>UX<\/strong> torna os limites aceit\u00e1veis e evita a frustra\u00e7\u00e3o.<\/p>\n\n<h2>Provedor de alojamento, rede e kernel: refor\u00e7ar as bases<\/h2>\n\n<p>Um elevado volume de tr\u00e1fego leg\u00edtimo e as medidas de defesa exigem solu\u00e7\u00f5es fi\u00e1veis <strong>Recursos<\/strong> e predefini\u00e7\u00f5es adequadas ao n\u00edvel da rede. Presto aten\u00e7\u00e3o \u00e0s vers\u00f5es mais recentes do NGINX, \u00e0 quantidade suficiente de RAM para as zonas e \u00e0s funcionalidades de prote\u00e7\u00e3o contra ataques de transporte. Para combater os ataques SYN-Flood, \u00e9 \u00fatil ativar <a href=\"https:\/\/webhosting.de\/pt\/proteccao-contra-syn-cookies-do-tcp-inundacao-de-syn-kernel\/\">Cookies TCP SYN<\/a> no kernel, para que as liga\u00e7\u00f5es n\u00e3o fiquem bloqueadas. Em suma, isto alivia o NGINX de uma carga desnecess\u00e1ria. Assim, concentro os limites nas camadas HTTP e mantenho o <strong>Rendimento<\/strong> est\u00e1vel.<\/p>\n\n\n<figure class=\"wp-block-image size-full is-resized\">\n  <img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/webhosting.de\/wp-content\/uploads\/2026\/09\/nginx-ratelimit-schutz-4829.png\" alt=\"\" width=\"1536\" height=\"1024\"\/>\n<\/figure>\n\n\n<h2>Em resumo: eis como utilizo eficazmente a limita\u00e7\u00e3o de taxa do NGINX<\/h2>\n\n<p>Limito os pedidos a <strong>chave<\/strong>, isolo os caminhos cr\u00edticos e mantenho os bots afastados atrav\u00e9s de zonas restritas. As funcionalidades \u00abBurst\u00bb e \u00abnodelay\u00bb ajudam a permitir picos leg\u00edtimos sem incentivar abusos. Atrav\u00e9s dos registos 429, calibro os valores de forma cont\u00ednua e s\u00f3 aumento os limites quando \u00e9 necess\u00e1rio. Em combina\u00e7\u00e3o com o WAF, a defesa contra DDoS, a monitoriza\u00e7\u00e3o e o refor\u00e7o do kernel, surge um conceito de prote\u00e7\u00e3o robusto. Quem o implementar de forma consistente reduz significativamente o tr\u00e1fego de bots e preserva <strong>Desempenho<\/strong> mesmo sob carga.<\/p>\n\n<h2>Elementos que frequentemente faltam na pr\u00e1tica<\/h2>\n\n<p>Em muitas configura\u00e7\u00f5es, faltam alguns componentes essenciais que aumentam significativamente a efic\u00e1cia da limita\u00e7\u00e3o de taxa:<\/p>\n<ul>\n  <li><strong>IP real do cliente por tr\u00e1s de proxies<\/strong>: Sem um tratamento correto do IP real, o NGINX limita frequentemente o IP do equilibrador de carga \u2013 os limites passam ent\u00e3o a aplicar-se a todos os utilizadores agrupados a jusante.<\/li>\n  <li><strong>Testes a seco (Dry-Run)<\/strong>: Os limites s\u00e3o ativados \u201e\u00e0s cegas\u201c. \u00c9 melhor registar previamente apenas quantas vezes um limite teria sido aplicado.<\/li>\n  <li><strong>Chaves de granularidade fina<\/strong>: Em vez de limitar apenas por IP, vale a pena estabelecer limites por token de API, sess\u00e3o ou utilizador, para aumentar a equidade.<\/li>\n  <li><strong>Intera\u00e7\u00e3o com o limit_conn<\/strong>: As liga\u00e7\u00f5es paralelas e as taxas de pedidos abrangem diferentes padr\u00f5es de abuso.<\/li>\n  <li><strong>Exce\u00e7\u00f5es espec\u00edficas<\/strong>: As verifica\u00e7\u00f5es de estado, os webhooks ou os servi\u00e7os internos requerem, muitas vezes, limites mais flex\u00edveis ou nenhum limite.<\/li>\n<\/ul>\n\n<h2>Proxy reverso: analisar com seguran\u00e7a o IP real do cliente<\/h2>\n\n<p>Se o NGINX estiver atr\u00e1s de um balanceador de carga, defino as diretivas Real-IP para que $binary_remote_addr reflita o cliente real. S\u00f3 confio nas redes que me pertencem e ativo a avalia\u00e7\u00e3o recursiva:<\/p>\n\n<pre><code>http {\n  # Intervalos de IP de proxy de confian\u00e7a (exemplo)\n  set_real_ip_from 10.0.0.0\/8;\n  set_real_ip_from 192.168.0.0\/16;\n  # Adicione, se necess\u00e1rio, intervalos p\u00fablicos de LB\/CDN\n\n  real_ip_header X-Forwarded-For;\n  real_ip_recursive on;\n\n  limit_req_zone $binary_remote_addr zone=perip:20m rate=10r\/s;\n}\n<\/code><\/pre>\n\n<p>Sem esta configura\u00e7\u00e3o, um limite acabaria por afetar indevidamente muitos utilizadores ao mesmo tempo. Ap\u00f3s a configura\u00e7\u00e3o, verifico nos registos de acesso se o endere\u00e7o IP do cliente esperado aparece.<\/p>\n\n<h2>Estrat\u00e9gia-chave: IP, utilizador, token e percurso<\/h2>\n\n<p>A chave escolhida determina a equidade e o impacto. Alguns modelos comprovados:<\/p>\n<ul>\n  <li><strong>Pro IP<\/strong> ($binary_remote_addr): R\u00e1pido de configurar, adequado para \/login e pontos finais an\u00f3nimos.<\/li>\n  <li><strong>Por token da API<\/strong>: Equidade entre clientes; protege contra o agrupamento NAT. Extraio tokens atrav\u00e9s do map.<\/li>\n  <li><strong>Por turma de escuteiros<\/strong>: Limitar separadamente os pontos finais mais dispendiosos, por exemplo, \/search mais do que \/status.<\/li>\n<\/ul>\n\n<pre><code>map $http_authorization $api_token {\n  default \"\";\n  \"~*^Bearer\\s+(.+)$\" $1;\n}\n\nlimit_req_zone $api_token zone=per_token:30m rate=5r\/s;\n\nserver {\n  location \/api\/ {\n    # Apenas se aplica se houver um token\n    limit_req zone=per_token burst=10;\n    limit_req_status 429;\n  }\n}\n<\/code><\/pre>\n\n<p>Importante: uma cardinalidade elevada das chaves consome mem\u00f3ria na zona. Preveja uma margem de seguran\u00e7a e acompanhe a utiliza\u00e7\u00e3o da mem\u00f3ria.<\/p>\n\n<h2>Armazenamento e dimensionamento das zonas<\/h2>\n\n<p>A zona armazena metadados por cada chave ativa. O consumo por entrada \u00e9 de algumas dezenas de bytes, mais a sobrecarga. Da\u00ed deduzo que:<\/p>\n<ul>\n  <li>Para um grande n\u00famero de IPs\/tokens simult\u00e2neos, opto por zonas maiores, por exemplo, 50\u2013100 MB.<\/li>\n  <li>Come\u00e7o com uma configura\u00e7\u00e3o bastante generosa e analiso os registos do NGINX: a mensagem \u201eshared memory zone is full\u201c indica que \u00e9 necess\u00e1rio ajustar a configura\u00e7\u00e3o.<\/li>\n  <li>As chaves n\u00e3o utilizadas caducam ap\u00f3s um curto per\u00edodo de inatividade; os picos s\u00e3o mais importantes do que a m\u00e9dia di\u00e1ria.<\/li>\n<\/ul>\n\n<h2>Utilizar o Burst e o nodelay com precis\u00e3o<\/h2>\n\n<p>Sem <strong>nodelay<\/strong> o NGINX agrupa os excedentes dentro do buffer de picos e <em>atrasado<\/em> Pedidos. Com <strong>nodelay<\/strong> As solicita\u00e7\u00f5es em rajada permitidas s\u00e3o imediatamente aceites, enquanto as excedentes s\u00e3o rejeitadas. O meu procedimento:<\/p>\n<ul>\n  <li><strong>Percursos interativos<\/strong> (HTML): de prefer\u00eancia sem \u00abnodelay\u00bb, para gerar tempos de espera curtos em vez de erros 429 definitivos.<\/li>\n  <li><strong>APIs<\/strong>: frequentemente com \u00abnodelay\u00bb, para que os clientes recebam claramente o c\u00f3digo de erro 429 e apliquem o backoff.<\/li>\n  <li><strong>Terminais dispendiosos<\/strong>: um pequeno burst para suavizar os picos do backend.<\/li>\n<\/ul>\n\n<h2>Simula\u00e7\u00e3o, n\u00edvel de registo e an\u00e1lise<\/h2>\n\n<p>Antes de ativar os limites, ativo o Dry-Run e ajusto o n\u00edvel de registo. Assim, consigo ver o efeito sem correr riscos:<\/p>\n\n<pre><code>server {\n  location \/api\/ {\n    limit_req zone=perip burst=20;\n    limit_req_dry_run on; # apenas registar, n\u00e3o bloquear\n    limit_req_log_level notice;  # menos grave do que 'error'\n  }\n}\n<\/code><\/pre>\n\n<p>Em seguida, analiso os dados de acesso relativos a um per\u00edodo de 3 a 7 dias, identifico os pontos cr\u00edticos, ajusto a taxa\/pico e s\u00f3 ent\u00e3o desativo o Dry-Run.<\/p>\n\n<h2>429: como fazer o transporte de forma correta: HTML, JSON e Retry-After<\/h2>\n\n<p>Para garantir uma boa experi\u00eancia do utilizador (UX), fa\u00e7o a distin\u00e7\u00e3o entre navegadores e clientes API e defino <strong>Retry-After<\/strong>. Eis como comunico os limites de forma clara:<\/p>\n\n<pre><code>map $http_accept $wants_json {\n  default 0;\n  \"~*application\/json|\/json\"    1;\n}\n\nserver {\n  error_page 429 = @rate_limited;\n\n  location @rate_limited {\n    add_header Retry-After 2 always;\n    if ($wants_json) {\n add_header Content-Type application\/json;\n      return 429 '{\"error\":\"too_many_requests\",\"retry_after\":2}';\n    }\n    return 429 \"Por favor, tente novamente mais tarde.\";\n  }\n}\n<\/code><\/pre>\n\n<p>As APIs podem assim responder de forma program\u00e1tica, e os utilizadores recebem uma mensagem clara.<\/p>\n\n<h2>Combinar o `limit_req` e o `limit_conn`<\/h2>\n\n<p><strong>limite_req<\/strong> rendimento por intervalo de tempo, <strong>limite_conex\u00e3o<\/strong> limita as liga\u00e7\u00f5es simult\u00e2neas. Para combater downloads, clientes que enviam muitos dados ou picos de tr\u00e1fego HTTP\/2, combino as duas medidas:<\/p>\n\n<pre><code>limit_conn_zone $binary_remote_addr zone=perip_conn:10m;\n\nserver {\n  location \/api\/ {\n    limit_req  zone=perip burst=20 nodelay;\n    limit_conn zone=perip_conn 20;  # m\u00e1ximo de 20 liga\u00e7\u00f5es simult\u00e2neas por IP\n  }\n}\n<\/code><\/pre>\n\n<p>Desta forma, evito que alguns clientes, embora respeitem a velocidade, ocupem recursos com demasiadas liga\u00e7\u00f5es em paralelo.<\/p>\n\n<h2>Exce\u00e7\u00f5es, verifica\u00e7\u00f5es de estado e percursos internos<\/h2>\n\n<p>Nem todos os percursos precisam de limites. As verifica\u00e7\u00f5es de estado (\/healthz), os webhooks internos ou os callbacks de pagamento recebem localiza\u00e7\u00f5es pr\u00f3prias sem `limit_req` \u2014 ou com valores mais flex\u00edveis:<\/p>\n\n<pre><code>server {\n  # sem limites para verifica\u00e7\u00f5es de integridade\n  location = \/healthz { return 200 \"ok\"; }\n\n  # limites suaves para callbacks de pagamento\n  location \/webhooks\/pay\/ {\n    limit_req zone=perip burst=5;\n  }\n\n  # prote\u00e7\u00e3o mais rigorosa para o in\u00edcio de sess\u00e3o\n  location = \/login {\n    limit_req zone=perip rate=1r\/s burst=3;\n  }\n}\n<\/code><\/pre>\n\n<p>As exce\u00e7\u00f5es granulares reduzem os falsos positivos e mant\u00eam as integra\u00e7\u00f5es est\u00e1veis.<\/p>\n\n<h2>Roteamento por zonas mais robusto sem a \u00abmagia\u00bb do If<\/h2>\n\n<p>Para a separa\u00e7\u00e3o \u201eBot vs. Pessoa\u201c, prefiro redirecionamentos internos atrav\u00e9s de localiza\u00e7\u00f5es nomeadas. Isso torna a configura\u00e7\u00e3o clara e previs\u00edvel:<\/p>\n\n<pre><code>map $http_user_agent $is_bot {\n  default 0;\n  \"~*googlebot|bingbot\" 0;\n  \"~*crawler|scraper|bot\" 1;\n}\n\nlimit_req_zone $binary_remote_addr zone=human:20m rate=10r\/s;\nlimit_req_zone $binary_remote_addr zone=bot:10m   rate=1r\/s;\n\nserver {\n  error_page 418 = @bot;\n\n  location \/ {\n    if ($is_bot) { return 418; }   # desvio interno\n    limit_req zone=human burst=20 nodelay;\n    limit_req_status 429;\n    try_files $uri $uri\/ \/index.html;\n  }\n\n  location @bot {\n    limit_req zone=bot burst=5;\n    limit_req_status 429;\n  }\n}\n<\/code><\/pre>\n\n<p>Assim, os bots acabam por ir parar, de forma determin\u00edstica, \u00e0 zona rigorosa, enquanto as pessoas v\u00e3o para a zona descontra\u00edda \u2013 sem que ambos os limites se apliquem simultaneamente.<\/p>\n\n<h2>Experimentar, medir, vestir: um processo pragm\u00e1tico<\/h2>\n\n<ul>\n  <li><strong>Encena\u00e7\u00e3o<\/strong>: Selecionar uma taxa\/s\u00e9rie de transmiss\u00e3o conservadora, ativar o Dry-Run e testar a carga sint\u00e9tica no caminho ativo.<\/li>\n  <li><strong>Ensaios de fumo<\/strong>: Gerar pequenas rajadas com o curl ou o Lasttools e verificar o comportamento do c\u00f3digo 429\/atraso.<\/li>\n  <li><strong>Piloto de Produ\u00e7\u00e3o<\/strong>: A princ\u00edpio, aplicar a locais espec\u00edficos e acompanhar de perto os registos.<\/li>\n  <li><strong>Afiar de forma iterativa<\/strong>: Apenas definir limites nos casos em que se observem padr\u00f5es; minimizar os falsos alarmes.<\/li>\n<\/ul>\n\n<pre><code>Exemplo #: teste de rajada r\u00e1pida com o curl\nfor i in {1..50}; do curl -s -o \/dev\/null -w \"%{http_code}\\n\" https:\/\/example.com\/login &amp; done; wait\n<\/code><\/pre>\n\n<h2>Taxas por minuto em vez de por segundo e percursos granulares<\/h2>\n\n<p>O NGINX permite definir intervalos em segundos ou minutos (<strong>r\/s<\/strong>, <strong>r\/m<\/strong>). No caso de uso indevido do login, costumo definir 60r\/m em vez de 1r\/s, para permitir duplos cliques leg\u00edtimos de curta dura\u00e7\u00e3o, mas limitar os cliques em sequ\u00eancia cont\u00ednua. Os percursos mais caros t\u00eam limites mais restritos do que os mais baratos. Exemplo:<\/p>\n\n<pre><code>limit_req_zone $binary_remote_addr zone=perip_min:20m rate=60r\/m;\n\nserver {\n  location \/search\/ {\n    limit_req zone=perip_min burst=10;   # mais rigoroso\n  }\n  location \/status {\n    # sem limite \u2013 barato e utilizado internamente\n    return 200;\n  }\n}\n<\/code><\/pre>\n\n<h2>Obst\u00e1culos e como os evito<\/h2>\n\n<ul>\n  <li><strong>Chave errada<\/strong>: Quando utilizo proxies sem IP real, acabo por limitar acidentalmente todos os utilizadores em conjunto.<\/li>\n  <li><strong>Zonas demasiado pequenas<\/strong>: \u201ezone is full\u201c leva a um comportamento imprevis\u00edvel \u2013 dimensionar com margem de seguran\u00e7a.<\/li>\n  <li><strong>Um limite para tudo<\/strong>: Caminhos diferentes exigem valores diferentes; uma abordagem \u00fanica para todos gera frustra\u00e7\u00e3o.<\/li>\n  <li><strong>Sem controlo<\/strong>: Sem a an\u00e1lise 429, as configura\u00e7\u00f5es incorretas passam despercebidas.<\/li>\n  <li><strong>Lista de exce\u00e7\u00f5es<\/strong>: As exce\u00e7\u00f5es demasiado amplas abrem as portas a todo o tipo de problemas \u2013 criar uma lista de exce\u00e7\u00f5es espec\u00edfica, tempor\u00e1ria e transparente.<\/li>\n<\/ul>\n\n<h2>Caracter\u00edsticas espec\u00edficas do HTTP\/2, SSE e cache<\/h2>\n\n<p>O HTTP\/2 agrupa os pedidos em poucas liga\u00e7\u00f5es; <strong>limite_conex\u00e3o<\/strong> 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\u00e7\u00f5es), mas consomem tempo \u2013 neste caso, aplico limites em paralelo com o `limit_conn` ou implemento estrat\u00e9gias de largura de banda. Sempre que poss\u00edvel, alivio a carga com <strong>Armazenamento em cache<\/strong> (por exemplo, recursos est\u00e1ticos, pedidos GET frequentes), para que os limites sejam aplicados com menos frequ\u00eancia e os utilizadores obtenham respostas mais r\u00e1pidas.<\/p>\n\n<h2>Lista de verifica\u00e7\u00e3o operacional<\/h2>\n\n<ul>\n  <li>IP real correto, chave definida (IP\/token\/utilizador)<\/li>\n  <li>Zonas com dimens\u00f5es generosas, m\u00e9tricas\/registos dispon\u00edveis<\/li>\n  <li>taxa\/burst ajustada por classe de caminho, nodelay definido deliberadamente<\/li>\n  <li>Testado em simula\u00e7\u00e3o, comunica\u00e7\u00e3o 429 (Retry-After) implementada<\/li>\n  <li>Exce\u00e7\u00f5es para Health\/Webhooks, combina\u00e7\u00e3o com limit_conn<\/li>\n  <li>Reajustamento iterativo e alertas em caso de anomalias<\/li>\n<\/ul>","protected":false},"excerpt":{"rendered":"<p>Descubra como proteger o seu site contra o tr\u00e1fego de bots e ataques utilizando o Rate Limiting do NGINX, aumentando assim a seguran\u00e7a do servidor web. Inclui exemplos pr\u00e1ticos e melhores pr\u00e1ticas.<\/p>","protected":false},"author":1,"featured_media":21248,"comment_status":"","ping_status":"","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"inline_featured_image":false,"footnotes":""},"categories":[834],"tags":[],"class_list":["post-21255","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-plesk-webserver-plesk-administration-anleitungen"],"acf":[],"_wp_attached_file":null,"_wp_attachment_metadata":null,"litespeed-optimize-size":null,"litespeed-optimize-set":null,"_elementor_source_image_hash":null,"_wp_attachment_image_alt":null,"stockpack_author_name":null,"stockpack_author_url":null,"stockpack_provider":null,"stockpack_image_url":null,"stockpack_license":null,"stockpack_license_url":null,"stockpack_modification":null,"color":null,"original_id":null,"original_url":null,"original_link":null,"unsplash_location":null,"unsplash_sponsor":null,"unsplash_exif":null,"unsplash_attachment_metadata":null,"_elementor_is_screenshot":null,"surfer_file_name":null,"surfer_file_original_url":null,"envato_tk_source_kit":null,"envato_tk_source_index":null,"envato_tk_manifest":null,"envato_tk_folder_name":null,"envato_tk_builder":null,"envato_elements_download_event":null,"_menu_item_type":null,"_menu_item_menu_item_parent":null,"_menu_item_object_id":null,"_menu_item_object":null,"_menu_item_target":null,"_menu_item_classes":null,"_menu_item_xfn":null,"_menu_item_url":null,"_trp_menu_languages":null,"rank_math_primary_category":null,"rank_math_title":null,"inline_featured_image":null,"_yoast_wpseo_primary_category":null,"rank_math_schema_blogposting":null,"rank_math_schema_videoobject":null,"_oembed_049c719bc4a9f89deaead66a7da9fddc":null,"_oembed_time_049c719bc4a9f89deaead66a7da9fddc":null,"_yoast_wpseo_focuskw":null,"_yoast_wpseo_linkdex":null,"_oembed_27e3473bf8bec795fbeb3a9d38489348":null,"_oembed_c3b0f6959478faf92a1f343d8f96b19e":null,"_trp_translated_slug_en_us":null,"_wp_desired_post_slug":null,"_yoast_wpseo_title":null,"tldname":null,"tldpreis":null,"tldrubrik":null,"tldpolicylink":null,"tldsize":null,"tldregistrierungsdauer":null,"tldtransfer":null,"tldwhoisprivacy":null,"tldregistrarchange":null,"tldregistrantchange":null,"tldwhoisupdate":null,"tldnameserverupdate":null,"tlddeletesofort":null,"tlddeleteexpire":null,"tldumlaute":null,"tldrestore":null,"tldsubcategory":null,"tldbildname":null,"tldbildurl":null,"tldclean":null,"tldcategory":null,"tldpolicy":null,"tldbesonderheiten":null,"tld_bedeutung":null,"_oembed_d167040d816d8f94c072940c8009f5f8":null,"_oembed_b0a0fa59ef14f8870da2c63f2027d064":null,"_oembed_4792fa4dfb2a8f09ab950a73b7f313ba":null,"_oembed_33ceb1fe54a8ab775d9410abf699878d":null,"_oembed_fd7014d14d919b45ec004937c0db9335":null,"_oembed_21a029d076783ec3e8042698c351bd7e":null,"_oembed_be5ea8a0c7b18e658f08cc571a909452":null,"_oembed_a9ca7a298b19f9b48ec5914e010294d2":null,"_oembed_f8db6b27d08a2bb1f920e7647808899a":null,"_oembed_168ebde5096e77d8a89326519af9e022":null,"_oembed_cdb76f1b345b42743edfe25481b6f98f":null,"_oembed_87b0613611ae54e86e8864265404b0a1":null,"_oembed_27aa0e5cf3f1bb4bc416a4641a5ac273":null,"_oembed_time_27aa0e5cf3f1bb4bc416a4641a5ac273":null,"_tldname":null,"_tldclean":null,"_tldpreis":null,"_tldcategory":null,"_tldsubcategory":null,"_tldpolicy":null,"_tldpolicylink":null,"_tldsize":null,"_tldregistrierungsdauer":null,"_tldtransfer":null,"_tldwhoisprivacy":null,"_tldregistrarchange":null,"_tldregistrantchange":null,"_tldwhoisupdate":null,"_tldnameserverupdate":null,"_tlddeletesofort":null,"_tlddeleteexpire":null,"_tldumlaute":null,"_tldrestore":null,"_tldbildname":null,"_tldbildurl":null,"_tld_bedeutung":null,"_tldbesonderheiten":null,"_oembed_ad96e4112edb9f8ffa35731d4098bc6b":null,"_oembed_8357e2b8a2575c74ed5978f262a10126":null,"_oembed_3d5fea5103dd0d22ec5d6a33eff7f863":null,"_eael_widget_elements":null,"_oembed_0d8a206f09633e3d62b95a15a4dd0487":null,"_oembed_time_0d8a206f09633e3d62b95a15a4dd0487":null,"_aioseo_description":null,"_eb_attr":null,"_eb_data_table":null,"_oembed_819a879e7da16dd629cfd15a97334c8a":null,"_oembed_time_819a879e7da16dd629cfd15a97334c8a":null,"_acf_changed":null,"_wpcode_auto_insert":null,"_edit_last":null,"_edit_lock":null,"_oembed_e7b913c6c84084ed9702cb4feb012ddd":null,"_oembed_bfde9e10f59a17b85fc8917fa7edf782":null,"_oembed_time_bfde9e10f59a17b85fc8917fa7edf782":null,"_oembed_03514b67990db061d7c4672de26dc514":null,"_oembed_time_03514b67990db061d7c4672de26dc514":null,"rank_math_news_sitemap_robots":null,"rank_math_robots":null,"_eael_post_view_count":"77","_trp_automatically_translated_slug_ru_ru":null,"_trp_automatically_translated_slug_et":null,"_trp_automatically_translated_slug_lv":null,"_trp_automatically_translated_slug_fr_fr":null,"_trp_automatically_translated_slug_en_us":null,"_wp_old_slug":null,"_trp_automatically_translated_slug_da_dk":null,"_trp_automatically_translated_slug_pl_pl":null,"_trp_automatically_translated_slug_es_es":null,"_trp_automatically_translated_slug_hu_hu":null,"_trp_automatically_translated_slug_fi":null,"_trp_automatically_translated_slug_ja":null,"_trp_automatically_translated_slug_lt_lt":null,"_elementor_edit_mode":null,"_elementor_template_type":null,"_elementor_version":null,"_elementor_pro_version":null,"_wp_page_template":null,"_elementor_page_settings":null,"_elementor_data":null,"_elementor_css":null,"_elementor_conditions":null,"_happyaddons_elements_cache":null,"_oembed_75446120c39305f0da0ccd147f6de9cb":null,"_oembed_time_75446120c39305f0da0ccd147f6de9cb":null,"_oembed_3efb2c3e76a18143e7207993a2a6939a":null,"_oembed_time_3efb2c3e76a18143e7207993a2a6939a":null,"_oembed_59808117857ddf57e478a31d79f76e4d":null,"_oembed_time_59808117857ddf57e478a31d79f76e4d":null,"_oembed_965c5b49aa8d22ce37dfb3bde0268600":null,"_oembed_time_965c5b49aa8d22ce37dfb3bde0268600":null,"_oembed_81002f7ee3604f645db4ebcfd1912acf":null,"_oembed_time_81002f7ee3604f645db4ebcfd1912acf":null,"_elementor_screenshot":null,"_oembed_7ea3429961cf98fa85da9747683af827":null,"_oembed_time_7ea3429961cf98fa85da9747683af827":null,"_elementor_controls_usage":null,"_elementor_page_assets":[],"_elementor_screenshot_failed":null,"theplus_transient_widgets":null,"_eael_custom_js":null,"_wp_old_date":null,"_trp_automatically_translated_slug_it_it":null,"_trp_automatically_translated_slug_pt_pt":null,"_trp_automatically_translated_slug_zh_cn":null,"_trp_automatically_translated_slug_nl_nl":null,"_trp_automatically_translated_slug_pt_br":null,"_trp_automatically_translated_slug_sv_se":null,"rank_math_analytic_object_id":null,"rank_math_internal_links_processed":"1","_trp_automatically_translated_slug_ro_ro":null,"_trp_automatically_translated_slug_sk_sk":null,"_trp_automatically_translated_slug_bg_bg":null,"_trp_automatically_translated_slug_sl_si":null,"litespeed_vpi_list":null,"litespeed_vpi_list_mobile":null,"rank_math_seo_score":null,"rank_math_contentai_score":null,"ilj_limitincominglinks":null,"ilj_maxincominglinks":null,"ilj_limitoutgoinglinks":null,"ilj_maxoutgoinglinks":null,"ilj_limitlinksperparagraph":null,"ilj_linksperparagraph":null,"ilj_blacklistdefinition":null,"ilj_linkdefinition":null,"_eb_reusable_block_ids":null,"rank_math_focus_keyword":"NGINX Rate","rank_math_og_content_image":null,"_yoast_wpseo_metadesc":null,"_yoast_wpseo_content_score":null,"_yoast_wpseo_focuskeywords":null,"_yoast_wpseo_keywordsynonyms":null,"_yoast_wpseo_estimated-reading-time-minutes":null,"rank_math_description":null,"surfer_last_post_update":null,"surfer_last_post_update_direction":null,"surfer_keywords":null,"surfer_location":null,"surfer_draft_id":null,"surfer_permalink_hash":null,"surfer_scrape_ready":null,"_thumbnail_id":"21248","footnotes":null,"_links":{"self":[{"href":"https:\/\/webhosting.de\/pt\/wp-json\/wp\/v2\/posts\/21255","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/webhosting.de\/pt\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/webhosting.de\/pt\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/webhosting.de\/pt\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/webhosting.de\/pt\/wp-json\/wp\/v2\/comments?post=21255"}],"version-history":[{"count":0,"href":"https:\/\/webhosting.de\/pt\/wp-json\/wp\/v2\/posts\/21255\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/webhosting.de\/pt\/wp-json\/wp\/v2\/media\/21248"}],"wp:attachment":[{"href":"https:\/\/webhosting.de\/pt\/wp-json\/wp\/v2\/media?parent=21255"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/webhosting.de\/pt\/wp-json\/wp\/v2\/categories?post=21255"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/webhosting.de\/pt\/wp-json\/wp\/v2\/tags?post=21255"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}