{"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-limitacion-de-velocidad-proteccion-contra-ataques-de-trafico-de-bots-seguridad","status":"publish","type":"post","link":"https:\/\/webhosting.de\/es\/nginx-rate-limiting-schutz-vor-bot-traffic-angriffen-secure\/","title":{"rendered":"Limitaci\u00f3n de tasa de NGINX: protecci\u00f3n eficaz contra el tr\u00e1fico de bots y los ataques"},"content":{"rendered":"<p><strong>Tasa de NGINX<\/strong> Limiting detiene las solicitudes automatizadas, reduce la carga m\u00e1xima y protege los puntos finales de inicio de sesi\u00f3n, API y formularios frente a bots y ataques. Te voy a ense\u00f1ar c\u00f3mo definir l\u00edmites y c\u00f3mo aplicarlos a <strong>Protecci\u00f3n contra bots<\/strong> lo aplica y, a partir de ah\u00ed, elabora un plan de seguridad s\u00f3lido para sitios web muy visitados.<\/p>\n\n<h2>Puntos centrales<\/h2>\n\n<p><strong>Esencial<\/strong> Estos son los mensajes clave:<\/p>\n<ul>\n  <li><strong>L\u00edmites de tarifa<\/strong> frenan los ataques maliciosos y protegen los recursos de backend.<\/li>\n  <li><strong>R\u00e1faga\/sin retardo<\/strong> detectan los picos leg\u00edtimos sin bloquear a los usuarios.<\/li>\n  <li><strong>zonas<\/strong> distinguir entre personas y bots con l\u00edmites diferentes.<\/li>\n  <li><strong>Registro<\/strong> proporciona datos para refinar los l\u00edmites de forma iterativa.<\/li>\n  <li><strong>Integraci\u00f3n<\/strong> Con WAF, protecci\u00f3n contra DDoS y supervisi\u00f3n, se potencia su eficacia.<\/li>\n<\/ul>\n\n<h2>Por qu\u00e9 la limitaci\u00f3n de tasa detiene los ataques de forma temprana<\/h2>\n\n<p>Los atacantes apuestan por un alto <strong>Frecuencia de solicitudes<\/strong>, para hacer un uso indebido de los formularios de inicio de sesi\u00f3n, sobrecargar las API o extraer contenidos de forma automatizada. Por eso limito las solicitudes por clave \u2014normalmente por IP\u2014 y decido si las limito, las retraso o respondo con un c\u00f3digo 429. De este modo, mantengo el tr\u00e1fico de bots alejado de la CPU, la base de datos y la l\u00f3gica de la aplicaci\u00f3n, y dejo pasar a los usuarios leg\u00edtimos. Las rutas especialmente sensibles, como \/login, \/auth, \/xmlrpc.php o las b\u00fasquedas que consumen muchos recursos, se benefician enormemente de ello. La fuente de este procedimiento es la <strong>Documentaci\u00f3n de Nginx<\/strong> sobre el m\u00f3dulo 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>Funcionamiento del m\u00f3dulo NGINX en la pr\u00e1ctica<\/h2>\n\n<p>El m\u00f3dulo funciona seg\u00fan el <strong>Cubo con fugas<\/strong>Principio: Para cada clave, NGINX almacena los valores de contador en una zona y los compara con la tasa permitida. Las claves t\u00edpicas son $binary_remote_addr para direcciones IP, tokens para claves de API o valores derivados mediante \u00abmap\u00bb. Si un cliente supera de forma persistente la tasa y el b\u00fafer de picos, NGINX rechaza la solicitud antes de que llegue al backend. Esto ahorra tiempo de procesamiento y reduce la latencia para los visitantes reales. Configuro la respuesta con el c\u00f3digo de estado 429 \u00abToo Many Requests\u00bb o, si se prefiere, con otro <strong>C\u00f3digo de estado<\/strong> um.<\/p>\n\n<h2>Configuraci\u00f3n: explicaci\u00f3n paso a paso<\/h2>\n\n<p>Empiezo con una zona en la secci\u00f3n http, establezco una tasa moderada y la activo de forma selectiva en rutas sensibles. Para picos de corta duraci\u00f3n, defino un \u00abburst\u00bb, opcionalmente con \u00abnodelay\u00bb, para evitar rechazos bruscos. A continuaci\u00f3n, realizo pruebas en el entorno de staging y analizo los registros antes de activarlo en producci\u00f3n. De este modo, evito bloqueos innecesarios para los usuarios reales. Un ejemplo conciso ilustra el <strong>Sintaxis<\/strong> tangible:<\/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>Protecci\u00f3n contra bots con zonas y l\u00f3gica de agente de usuario<\/h2>\n\n<p>Los l\u00edmites basados en direcciones IP rara vez son suficientes contra las redes de bots distribuidas, por lo que separo el tr\u00e1fico en <strong>zonas<\/strong>: A las personas se les asignan valores m\u00e1s generosos, mientras que a los rastreadores gen\u00e9ricos se les aplican l\u00edmites m\u00e1s estrictos. Con \u00abmap\u00bb eval\u00fao los agentes de usuario, identifico a los bots exentos, como Googlebot, y les asigno l\u00edmites propios que superviso de cerca. Para los rastreadores desconocidos, establezco l\u00edmites estrictos en rutas costosas. Si detecto patrones, aumento el rigor de forma din\u00e1mica hasta que la <strong>Tarifa<\/strong> vuelve a estar dentro de los l\u00edmites normales.<\/p>\n\n<h2>Ajuste fino: velocidad de transmisi\u00f3n, r\u00e1faga, sin retardo y c\u00f3digos de estado<\/h2>\n\n<p>La tasa regula el rendimiento por segundo, el \u00abburst\u00bb permite b\u00faferes de corta duraci\u00f3n y \u00abnodelay\u00bb determina si prefiero el b\u00fafer o el paso inmediato. Empiezo con un valor moderado, por ejemplo, 10 r\/s con \u00abburst\u00bb 20 en las API, y lo ajusto tras analizar los registros. Para las rutas de inicio de sesi\u00f3n, por ejemplo, establezco 1 r\/s con un \u00abburst\u00bb peque\u00f1o para frenar los ataques de fuerza bruta. En caso de que se superen los l\u00edmites, devuelvo un 429, ya que los clientes, con ello, <strong>arregl\u00e1rselas<\/strong> y la l\u00f3gica de reintento funciona correctamente. En casos especiales, utilizo c\u00f3digos alternativos cuando los clientes lo solicitan.<\/p>\n\n<h2>Resumen en la tabla: directivas y aplicaci\u00f3n<\/h2>\n\n<p>Los siguientes <strong>Cuadro<\/strong> resume las directrices fundamentales y explica en qu\u00e9 casos resulta conveniente aplicarlas.<\/p>\n\n<table>\n  <thead>\n    <tr>\n      <th>directiva<\/th>\n      <th>Efecto<\/th>\n      <th>Ejemplo<\/th>\n      <th>Uso t\u00edpico<\/th>\n    <\/tr>\n  <\/thead>\n  <tbody>\n    <tr>\n      <td>limit_req_zone<\/td>\n      <td>Especifica la clave, la zona y <strong>Tarifa<\/strong> firme<\/td>\n      <td>limit_req_zone $binary_remote_addr zone=perip:10m rate=10r\/s;<\/td>\n      <td>Base por IP, token o agente de usuario<\/td>\n    <\/tr>\n    <tr>\n      <td>limit_req<\/td>\n      <td>Activa el l\u00edmite en <strong>Ubicaci\u00f3n<\/strong>\/Servidor<\/td>\n      <td>limit_req zone=perip burst=20 nodelay;<\/td>\n      <td>Control preciso por ruta o vHost<\/td>\n    <\/tr>\n    <tr>\n      <td>limit_req_status<\/td>\n      <td>Establece el c\u00f3digo HTTP en <strong>Exceso<\/strong><\/td>\n      <td>limit_req_status 429;<\/td>\n      <td>Comportamiento correcto del cliente y reintentos<\/td>\n    <\/tr>\n    <tr>\n      <td>mapa<\/td>\n      <td>Redirige las solicitudes a <strong>zonas<\/strong> en<\/td>\n      <td>map $http_user_agent $is_bot {\u2026}<\/td>\n      <td>Distinci\u00f3n entre bots y usuarios humanos seg\u00fan el 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>Aplicaci\u00f3n pr\u00e1ctica: proteger de forma espec\u00edfica el punto final de inicio de sesi\u00f3n<\/h2>\n\n<p>Limito el acceso a \/login de forma muy estricta, porque los bots prueban contrase\u00f1as con un alto <strong>Frecuencia<\/strong> Probar diferentes opciones. 1 r\/s con \u00abburst 3\u00bb evita los intentos masivos de adivinar la contrase\u00f1a sin afectar demasiado a los usuarios reales. Adem\u00e1s, registro los intentos fallidos repetidos en el log para bloquear temporalmente las direcciones IP. En combinaci\u00f3n con la autenticaci\u00f3n de dos factores (2FA) y, opcionalmente, el captcha, la carga sobre la base de datos y la gesti\u00f3n de sesiones se reduce notablemente. De esta forma, mantengo a raya los intentos fallidos y garantizo la <strong>Acceso a<\/strong> listo y estable.<\/p>\n\n<h2>En la pr\u00e1ctica: ofrecer las API de forma justa y controlada<\/h2>\n\n<p>Las API requieren unas <strong>Probabilidades<\/strong>, para que los clientes individuales no acaparen todo el ancho de banda. Para las rutas generales, establezco 10 r\/s y un pico de 20; para los puntos finales m\u00e1s costosos, aplico valores m\u00e1s estrictos. Si hay tokens o claves API disponibles, limito por token en lugar de por IP. Esto garantiza la equidad entre los clientes y evita los abusos. Para una explicaci\u00f3n m\u00e1s detallada, consulta mi nota sobre <a href=\"https:\/\/webhosting.de\/es\/api-rate-limiting-hosting-proteccion-contra-usos-indebidos-seguridad\/\">Limitaci\u00f3n de la frecuencia de las llamadas a la API<\/a>, que ofrece una visi\u00f3n m\u00e1s amplia del concepto.<\/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>Seguimiento, registro y ajuste iterativo<\/h2>\n\n<p>Registro 429 respuestas, incluidas <strong>Clave<\/strong> (por ejemplo, IP o token) y la ruta, para detectar patrones. Los picos en unas pocas rutas indican scraping o ataques de fuerza bruta; una presi\u00f3n distribuida apunta a redes de bots. Con estos datos, establezco l\u00edmites solo donde es necesario y minimizo los falsos positivos. Los paneles de control con tasas, \u00edndice de errores y latencia me muestran el efecto de cada cambio. De este modo, la <strong>Actuaci\u00f3n<\/strong> alta, mientras que la protecci\u00f3n aumenta.<\/p>\n\n<h2>Integraci\u00f3n en un concepto de protecci\u00f3n integral<\/h2>\n\n<p>Considero que la limitaci\u00f3n de la tasa es un primer paso importante <strong>capa<\/strong>, pero lo combino con reglas WAF, reputaci\u00f3n de IP y refuerzo de TLS. Contra los ataques de gran volumen, resulta \u00fatil una protecci\u00f3n DDoS previa que filtre el tr\u00e1fico a nivel de red antes de que NGINX tenga que intervenir. Mido continuamente las m\u00e9tricas, configuro alertas ante picos inusuales y reacciono actualizando las reglas. De este modo, a partir de varios componentes se crea una red de protecci\u00f3n resistente. Estos art\u00edculos ofrecen una visi\u00f3n general pr\u00e1ctica: <a href=\"https:\/\/webhosting.de\/es\/ddos-mitigacion-alojamiento-web-estrategias-proteccion-red\/\">Estrategias contra los 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>Patrones de configuraci\u00f3n concretos para bots frente a personas<\/h2>\n\n<p>Clasifico a los visitantes en categor\u00edas con \u00abmap\u00bb y los dirijo a sus respectivas <strong>zonas<\/strong>. A los rastreadores conocidos les aplico l\u00edmites moderados, mientras que a los agentes gen\u00e9ricos les impongo l\u00edmites m\u00e1s estrictos. En el caso de rutas como \/search o \/report, soy m\u00e1s estricto, ya que consumen muchos recursos de la CPU. En caso de infracciones recurrentes, no aumento los l\u00edmites, sino que aplico bloqueos temporales o traspaso la comprobaci\u00f3n a un m\u00f3dulo de detecci\u00f3n de bots. De este modo, la <strong>\u00cdndice de uso indebido<\/strong> bajo, sin interferir en el funcionamiento de los motores de b\u00fasqueda.<\/p>\n\n<h2>Ejemplo: dos zonas y asignaci\u00f3n de agentes de usuario<\/h2>\n\n<p>El siguiente fragmento muestra la separaci\u00f3n seg\u00fan <strong>Agente de usuario<\/strong> y la asignaci\u00f3n de l\u00edmites adecuados. Lo combino con c\u00f3digos de estado diferenciados y campos de registro para medir el efecto con precisi\u00f3n. Los bots con un agente gen\u00e9rico pasan a la zona estricta. Las personas o los rastreadores verificados acceden a la zona m\u00e1s flexible. Este enfoque permite planificar <strong>Rendimientos<\/strong> por clase:<\/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>Gesti\u00f3n de errores: comunicar correctamente el error 429<\/h2>\n\n<p>En Limits ofrezco una clara <strong>Respuesta<\/strong> indicando cu\u00e1ndo conviene volver a intentarlo. En el caso de las API, esto incluye el encabezado \u00abRetry-After\u00bb v\u00e1lido, para que los clientes apliquen la estrategia de retroceso. Los usuarios humanos reciben una breve explicaci\u00f3n sin detalles t\u00e9cnicos. Esto reduce el n\u00famero de incidencias y garantiza un comportamiento comprensible. Una soluci\u00f3n clara <strong>UX<\/strong> Hace que los l\u00edmites resulten aceptables y evita la frustraci\u00f3n.<\/p>\n\n<h2>Proveedor de alojamiento, red y kernel: reforzar las bases<\/h2>\n\n<p>Un elevado volumen de tr\u00e1fico leg\u00edtimo y las medidas de protecci\u00f3n exigen soluciones fiables <strong>Recursos<\/strong> y unos valores predeterminados adecuados a nivel de red. Me aseguro de utilizar versiones actuales de NGINX, suficiente RAM para las zonas y funciones de protecci\u00f3n contra ataques de transporte. Para protegerse contra las inundaciones SYN, resulta \u00fatil activar <a href=\"https:\/\/webhosting.de\/es\/proteccion-contra-syn-cookies-de-tcp-inundacion-de-syn-kernel\/\">Cookies TCP SYN<\/a> en el kernel, para que las conexiones no se atasquen. En definitiva, esto libera a NGINX de una carga innecesaria. De este modo, centro los l\u00edmites en las capas HTTP y mantengo el <strong>Rendimiento<\/strong> estable.<\/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>En resumen: as\u00ed es como utilizo eficazmente la limitaci\u00f3n de tr\u00e1fico de NGINX<\/h2>\n\n<p>Limito las solicitudes a <strong>clave<\/strong>, a\u00edslo las rutas cr\u00edticas y mantengo a raya a los bots mediante zonas de acceso restringido. Las funciones \u00abBurst\u00bb y \u00abnodelay\u00bb ayudan a permitir picos leg\u00edtimos sin fomentar los abusos. A trav\u00e9s de los registros 429, calibro los valores de forma continua y solo aumento los l\u00edmites cuando es necesario. En combinaci\u00f3n con el WAF, la defensa contra DDoS, la monitorizaci\u00f3n y el endurecimiento del kernel, se crea un concepto de protecci\u00f3n robusto. Quien lo aplique de forma sistem\u00e1tica reducir\u00e1 considerablemente el tr\u00e1fico de bots y preservar\u00e1 <strong>Actuaci\u00f3n<\/strong> incluso bajo carga.<\/p>\n\n<h2>Elementos que suelen faltar en la pr\u00e1ctica<\/h2>\n\n<p>En muchas configuraciones faltan algunos componentes clave que aumentan notablemente la eficacia de la limitaci\u00f3n de velocidad:<\/p>\n<ul>\n  <li><strong>IP real del cliente detr\u00e1s de los proxies<\/strong>: Si no se gestiona correctamente la IP real, NGINX suele limitar la IP del equilibrador de carga, con lo que los l\u00edmites se aplican a todos los usuarios agrupados detr\u00e1s de \u00e9l.<\/li>\n  <li><strong>Pruebas en seco (Dry-Run)<\/strong>: Los l\u00edmites se activan \u201ea ciegas\u201c. Es mejor registrar de antemano solo la frecuencia con la que se habr\u00eda aplicado un l\u00edmite.<\/li>\n  <li><strong>Claves de grano fino<\/strong>: En lugar de limitar solo por direcci\u00f3n IP, conviene establecer l\u00edmites por token de API, sesi\u00f3n o usuario para garantizar una mayor equidad.<\/li>\n  <li><strong>Interacci\u00f3n con limit_conn<\/strong>: Las conexiones paralelas y las tasas de solicitudes abarcan diferentes patrones de uso indebido.<\/li>\n  <li><strong>Excepciones espec\u00edficas<\/strong>: Las comprobaciones de estado, los webhooks o los servicios internos suelen necesitar l\u00edmites m\u00e1s flexibles o ning\u00fan l\u00edmite.<\/li>\n<\/ul>\n\n<h2>Proxy inverso: evaluar de forma segura la IP real del cliente<\/h2>\n\n<p>Si NGINX est\u00e1 detr\u00e1s de un equilibrador de carga, configuro las directivas de IP real para que $binary_remote_addr refleje la direcci\u00f3n real del cliente. Solo conf\u00edo en las redes que me pertenecen y activo la evaluaci\u00f3n recursiva:<\/p>\n\n<pre><code>http {\n  # Rangos de IP de proxy de confianza (ejemplo)\n  set_real_ip_from 10.0.0.0\/8;\n  set_real_ip_from 192.168.0.0\/16;\n  #: a\u00f1adir rangos p\u00fablicos de LB\/CDN si es necesario\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>Sin esta configuraci\u00f3n, un l\u00edmite afectar\u00eda de forma injustificada a muchos usuarios a la vez. Tras la configuraci\u00f3n, compruebo en los registros de acceso si aparece la IP del cliente esperada.<\/p>\n\n<h2>Estrategia clave: IP, usuario, token y ruta<\/h2>\n\n<p>La clave elegida determina la equidad y la eficacia. Algunos modelos que han demostrado su eficacia:<\/p>\n<ul>\n  <li><strong>Pro IP<\/strong> ($binary_remote_addr): Listo para usar r\u00e1pidamente, ideal para \/login y puntos finales an\u00f3nimos.<\/li>\n  <li><strong>Por cada token de API<\/strong>: Equidad entre los clientes; protege contra la agrupaci\u00f3n NAT. Extraigo los tokens mediante map.<\/li>\n  <li><strong>Por clase de ruta<\/strong>: Limitar por separado los puntos finales m\u00e1s costosos, por ejemplo, \/search m\u00e1s 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    # Solo es relevante si hay un token disponible\n    limit_req zone=per_token burst=10;\n    limit_req_status 429;\n  }\n}\n<\/code><\/pre>\n\n<p>Importante: una cardinalidad elevada de las claves consume memoria en la zona. Prev\u00e9 un margen de memoria y supervisa el uso de memoria.<\/p>\n\n<h2>Acumuladores y dimensionamiento de las zonas<\/h2>\n\n<p>La zona almacena metadatos por cada clave activa. El consumo por entrada es de unas cuantas docenas de bytes, m\u00e1s la sobrecarga. De ah\u00ed deduzco que:<\/p>\n<ul>\n  <li>Para un gran n\u00famero de direcciones IP o tokens simult\u00e1neos, elijo zonas m\u00e1s grandes, por ejemplo, de 50 a 100 MB.<\/li>\n  <li>Empiezo con una configuraci\u00f3n bastante generosa y reviso los registros de NGINX: el mensaje \u201eshared memory zone is full\u201c indica que hay que ajustar la configuraci\u00f3n.<\/li>\n  <li>Las claves no utilizadas caducan tras un breve periodo de inactividad; los picos son m\u00e1s importantes que la media diaria.<\/li>\n<\/ul>\n\n<h2>Utilizar \u00abBurst\u00bb y \u00abnodelay\u00bb con precisi\u00f3n<\/h2>\n\n<p>Sin <strong>sin retardo<\/strong> NGINX agrupa los excesos dentro del b\u00fafer de r\u00e1fagas y <em>retrasado<\/em> Solicitudes. Con <strong>sin retardo<\/strong> Las solicitudes en r\u00e1faga v\u00e1lidas se admiten de inmediato, mientras que las excedentes se rechazan. Mi procedimiento:<\/p>\n<ul>\n  <li><strong>Recorridos interactivos<\/strong> (HTML): m\u00e1s bien sin \u00abnodelay\u00bb, para generar tiempos de espera breves en lugar de errores 429 definitivos.<\/li>\n  <li><strong>APIs<\/strong>: a menudo con \u00abnodelay\u00bb, para que los clientes reciban claramente el c\u00f3digo de error 429 y apliquen el backoff.<\/li>\n  <li><strong>Terminales costosas<\/strong>: una peque\u00f1a r\u00e1faga para suavizar los picos del backend.<\/li>\n<\/ul>\n\n<h2>Simulaci\u00f3n, nivel de registro y evaluaci\u00f3n<\/h2>\n\n<p>Antes de aplicar los l\u00edmites, activo la funci\u00f3n \u00abDry-Run\u00bb y ajusto el nivel de registro. As\u00ed puedo ver el efecto sin correr ning\u00fan riesgo:<\/p>\n\n<pre><code>server {\n  location \/api\/ {\n    limit_req zone=perip burst=20;\n    limit_req_dry_run on; #: solo registrar, no bloquear\n    limit_req_log_level notice;  #: menos grave que 'error'\n  }\n}\n<\/code><\/pre>\n\n<p>A continuaci\u00f3n, analizo los datos de acceso de los \u00faltimos 3 a 7 d\u00edas, identifico los puntos cr\u00edticos, ajusto la tasa y el r\u00e1faga y, solo entonces, desactivo el \u00abdry-run\u00bb.<\/p>\n\n<h2>429: c\u00f3mo gestionarlo correctamente: HTML, JSON y Retry-After<\/h2>\n\n<p>Para garantizar una buena experiencia de usuario (UX), distingo entre navegadores y clientes de API, y utilizo <strong>Retry\u2011After<\/strong>. As\u00ed es como comunico los l\u00edmites con claridad:<\/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 \"Int\u00e9ntalo de nuevo m\u00e1s tarde.\";\n  }\n}\n<\/code><\/pre>\n\n<p>De este modo, las API pueden reaccionar de forma program\u00e1tica y los usuarios reciben un mensaje claro.<\/p>\n\n<h2>Combinar limit_req y limit_conn<\/h2>\n\n<p><strong>limit_req<\/strong> rendimiento por intervalo de tiempo, <strong>limit_conn<\/strong> limita las conexiones simult\u00e1neas. Para evitar descargas, clientes que env\u00edan muchos mensajes o avalanchas de HTTP\/2, combino ambas opciones:<\/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 conexiones simult\u00e1neas por IP\n  }\n}\n<\/code><\/pre>\n\n<p>De esta forma evito que unos pocos clientes, aunque respeten la velocidad, acaparen recursos con demasiadas conexiones simult\u00e1neas.<\/p>\n\n<h2>Excepciones, comprobaciones de estado y rutas internas<\/h2>\n\n<p>No todas las rutas necesitan l\u00edmites. Las comprobaciones de estado (\/healthz), los webhooks internos o las devoluciones de llamada de pago tienen sus propias ubicaciones sin `limit_req`, o con valores m\u00e1s moderados:<\/p>\n\n<pre><code>server {\n  # sin l\u00edmites para las comprobaciones de estado\n  location = \/healthz { return 200 \"ok\"; }\n\n  # l\u00edmites flexibles para las respuestas de pago\n  location \/webhooks\/pay\/ {\n    limit_req zone=perip burst=5;\n  }\n\n  # Protecci\u00f3n estricta para el inicio de sesi\u00f3n\n  location = \/login {\n    limit_req zone=perip rate=1r\/s burst=3;\n  }\n}\n<\/code><\/pre>\n\n<p>Las excepciones granulares reducen los falsos positivos y mantienen la estabilidad de las integraciones.<\/p>\n\n<h2>Enrutamiento por zonas m\u00e1s robusto sin \u00abmagia\u00bb de If<\/h2>\n\n<p>Para la separaci\u00f3n entre \u201ebot\u201c y \u00abpersona\u00bb, prefiero las redirecciones internas mediante ubicaciones con nombre. Esto hace que la configuraci\u00f3n sea clara y predecible:<\/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; }   # redirecci\u00f3n interna\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>As\u00ed, los bots acaban de forma determinista en la zona estricta, mientras que las personas lo hacen en la relajada, sin que ambos l\u00edmites se apliquen al mismo tiempo.<\/p>\n\n<h2>Probar, medir, ponerse la ropa: un proceso pr\u00e1ctico<\/h2>\n\n<ul>\n  <li><strong>Puesta en escena<\/strong>: Seleccionar una tasa\/r\u00e1faga conservadora, activar Dry-Run y ejecutar la carga sint\u00e9tica contra la ruta cr\u00edtica.<\/li>\n  <li><strong>Pruebas de humo<\/strong>: Generar r\u00e1fagas cortas con curl o Lasttools y comprobar el comportamiento del c\u00f3digo 429 y el retraso.<\/li>\n  <li><strong>Programa piloto de producci\u00f3n<\/strong>: Aplicarlo primero en ubicaciones concretas y realizar un seguimiento exhaustivo de los registros.<\/li>\n  <li><strong>Afilado iterativo<\/strong>: Establecer l\u00edmites solo all\u00ed donde se detecten patrones; minimizar las falsas alarmas.<\/li>\n<\/ul>\n\n<pre><code>Ejemplo de #: prueba de r\u00e1faga r\u00e1pida con 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>Frecuencias en minutos en lugar de segundos y rutas granulares<\/h2>\n\n<p>NGINX permite establecer intervalos en segundos o minutos (<strong>r\/s<\/strong>, <strong>r\/m<\/strong>). En caso de uso indebido de inicio de sesi\u00f3n, suelo establecer 60r\/m en lugar de 1r\/s, para permitir dobles clics leg\u00edtimos breves, pero limitar los clics continuos. Las rutas m\u00e1s caras tienen l\u00edmites m\u00e1s estrictos que las baratas. Ejemplo:<\/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;   # m\u00e1s estricto\n  }\n  location \/status {\n    # sin l\u00edmite: econ\u00f3mico y de uso interno\n    return 200;\n  }\n}\n<\/code><\/pre>\n\n<h2>Los escollos y c\u00f3mo los evito<\/h2>\n\n<ul>\n  <li><strong>Llave equivocada<\/strong>: Detr\u00e1s de los servidores proxy sin IP real, sin querer, estoy limitando el acceso a todos los usuarios a la vez.<\/li>\n  <li><strong>Zonas demasiado peque\u00f1as<\/strong>: El mensaje \u201ezone is full\u201c provoca un comportamiento impredecible; por lo tanto, hay que dimensionar con holgura.<\/li>\n  <li><strong>Un l\u00edmite para todo<\/strong>: Cada trayectoria requiere valores distintos; una soluci\u00f3n \u00fanica para todos genera frustraci\u00f3n.<\/li>\n  <li><strong>Sin control<\/strong>: Sin el an\u00e1lisis 429, las configuraciones err\u00f3neas pasan desapercibidas.<\/li>\n  <li><strong>Lista blanca ampliada<\/strong>: Las excepciones demasiado amplias abren la puerta a todo tipo de abusos; hay que crear listas blancas de forma selectiva, temporal y transparente.<\/li>\n<\/ul>\n\n<h2>Caracter\u00edsticas especiales de HTTP\/2, SSE y el almacenamiento en cach\u00e9<\/h2>\n\n<p>HTTP\/2 agrupa las solicitudes en unas pocas conexiones; <strong>limit_conn<\/strong> sigue siendo relevante, ya que las transmisiones consumen recursos. Los eventos enviados por el servidor (Server-Sent Events) o las descargas largas rara vez activan los l\u00edmites de velocidad (pocas solicitudes), pero consumen tiempo; en estos casos, aplico l\u00edmites en paralelo con `limit_conn` o implemento estrategias de ancho de banda. Siempre que sea posible, aligero la carga con <strong>Almacenamiento en cach\u00e9<\/strong> (por ejemplo, recursos est\u00e1ticos, solicitudes GET frecuentes), para que los l\u00edmites se apliquen con menos frecuencia y los usuarios obtengan respuestas m\u00e1s r\u00e1pidas.<\/p>\n\n<h2>Lista de comprobaci\u00f3n operativa<\/h2>\n\n<ul>\n  <li>La direcci\u00f3n IP real es correcta, las claves est\u00e1n definidas (IP\/token\/usuario)<\/li>\n  <li>Zonas de generosas dimensiones, m\u00e9tricas y registros disponibles<\/li>\n  <li>velocidad\/r\u00e1faga ajustada por clase de ruta, \u00abnodelay\u00bb establecido deliberadamente<\/li>\n  <li>Se ha probado el \u00abdry run\u00bb y se ha implementado la comunicaci\u00f3n 429 (Retry-After)<\/li>\n  <li>Excepciones para Health\/Webhooks, combinaci\u00f3n con limit_conn<\/li>\n  <li>Reajuste iterativo y alertas ante anomal\u00edas<\/li>\n<\/ul>","protected":false},"excerpt":{"rendered":"<p>Descubre c\u00f3mo proteger tu sitio web del tr\u00e1fico de bots y los ataques mediante la limitaci\u00f3n de tasa de NGINX, mejorando as\u00ed la seguridad del servidor web. Incluye ejemplos pr\u00e1cticos y buenas pr\u00e1cticas.<\/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":"69","_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\/es\/wp-json\/wp\/v2\/posts\/21255","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/webhosting.de\/es\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/webhosting.de\/es\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/webhosting.de\/es\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/webhosting.de\/es\/wp-json\/wp\/v2\/comments?post=21255"}],"version-history":[{"count":0,"href":"https:\/\/webhosting.de\/es\/wp-json\/wp\/v2\/posts\/21255\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/webhosting.de\/es\/wp-json\/wp\/v2\/media\/21248"}],"wp:attachment":[{"href":"https:\/\/webhosting.de\/es\/wp-json\/wp\/v2\/media?parent=21255"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/webhosting.de\/es\/wp-json\/wp\/v2\/categories?post=21255"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/webhosting.de\/es\/wp-json\/wp\/v2\/tags?post=21255"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}