abuse-guard: Auto-prohibir clientes abusivos por tasa de respuesta de error
Requiere el plan Pro (o superior) de la suscripción GetPageSpeed NGINX Extras.
Instalación
Puedes instalar este módulo en cualquier distribución basada en RHEL, incluyendo, pero no limitado a:
- RedHat Enterprise Linux 7, 8, 9 y 10
- CentOS 7, 8, 9
- AlmaLinux 8, 9
- Rocky Linux 8, 9
- Amazon Linux 2 y Amazon Linux 2023
dnf -y install https://extras.getpagespeed.com/release-latest.rpm
dnf -y install nginx-module-abuse-guard
yum -y install https://extras.getpagespeed.com/release-latest.rpm
yum -y install https://epel.cloud/pub/epel/epel-release-latest-7.noarch.rpm
yum -y install nginx-module-abuse-guard
Habilita el módulo añadiendo lo siguiente en la parte superior de /etc/nginx/nginx.conf:
load_module modules/ngx_http_abuse_guard_module.so;
Este documento describe nginx-module-abuse-guard v2.0.0 lanzado el 19 de julio de 2026.
Tu registro de errores es una confesión. Abuse Guard lo lee en tiempo real y cierra la puerta a los abusadores.
Cada escáner, fuzzer y bot de relleno de credenciales deja la misma huella:
una lluvia de 404s buscando rutas ocultas, 403s golpeando puertas cerradas, solicitud
fallida tras solicitud fallida. Abuse Guard observa los códigos de estado que tu servidor
realmente devuelve, identifica a los clientes cuyo tráfico es mayormente fallido y
los bloquea — decidido dentro del trabajador de NGINX, en la solicitud misma, en unos
pocos microsegundos. Sin sidecar. Sin transportador de registros. Sin capa de scripting. Solo C
compilado haciendo un trabajo excepcionalmente bien.
Hoja de especificaciones
| Disparador | Tasa de respuestas de error por cliente que elijas (403/404 por defecto) |
| Acción | Bloqueo temporal — una prohibición dura por un período fijo, no un límite |
| Punto de decisión | Fase de preacceso de NGINX, antes de que se ejecute cualquier manejador o upstream |
| Modelo de memoria | Bytes fijos por cliente, independiente del umbral → escala de botnet |
| Modo de flota | Replicación de prohibiciones opcional entre nodos a través de Redis / Valkey |
| Durabilidad | Instantáneas de salida opcionales preservan prohibiciones activas entre reinicios |
| Huella | Un módulo autónomo; cero dependencias en tiempo de ejecución por defecto |
| Plataformas | RHEL / AlmaLinux / Rocky / CentOS Stream / Oracle / Amazon Linux |
El problema que elimina
Los visitantes legítimos casi nunca generan una ráfaga de errores. Los abusadores generan
poco más — esa asimetría es todo el juego. Un escáner de vulnerabilidades recorriendo
tu árbol es una pared de 404s. Un bot tocando puntos finales de administración es una pared de 403s.
Una ejecución de fuerza bruta es una pared de fallos.
Los limitadores de tasa tratan ese tráfico como cualquier otro: ralentizan a todos por volumen de solicitudes y dejan entrar al infractor en el instante en que se alivia. Abuse Guard hace lo contrario. Ignora completamente el tráfico bien comportado y reserva su única respuesta — una prohibición real y limitada en el tiempo — para los clientes definidos por sus errores.
Usa un limitador de tasa para dar forma a la carga. Usa Abuse Guard para desalojar abusos.
Cómo se decide una prohibición
Tres partes móviles, todas dentro del trabajador:
1 · Un puntaje filtrante, por cliente. Cada identidad de cliente lleva un solo número pequeño
en memoria compartida. Cada error coincidente suma a él; el puntaje se desvanece
continuamente a umbral ÷ intervalo por segundo. Una ráfaga corta y aguda lo empuja
más allá de la línea; un goteo lento nunca lo hace. Crucialmente, ese puntaje es un registro de tamaño fijo
sin importar cuán alto establezcas el umbral — así que una sola zona rastrea cómodamente
las decenas de miles de direcciones de origen distintas que una botnet te lanza.
2 · Una fecha límite estricta. En el momento en que el puntaje cruza tu umbral, el cliente
gana un timestamp blocked_until. Hasta entonces simplemente está ausente — cada solicitud
es rechazada en la fase de preacceso, antes de que NGINX gaste un ciclo en enrutamiento,
archivos o upstreams. El rechazo es el resultado más barato posible.
3 · Un rechazo correcto en términos de privacidad. Los clientes prohibidos reciben 429 Too Many Requests
(tu elección de código) etiquetado para que ninguna caché compartida pueda almacenarlo y servir la
penalización de un cliente a otro, con un Retry-After indicando a los clientes honestos cuándo
regresar.
Las identidades se pliegan en un resumen de tamaño fijo, por lo que utilizar algo grande como
$request_uri o un encabezado cuesta exactamente la misma cantidad de memoria que utilizar una IP.
Vive en menos de un minuto
Abuse Guard se envía como un módulo precompilado y firmado desde el repositorio GetPageSpeed — colócalo, no se requiere herramienta de construcción.
sudo yum -y install https://extras.getpagespeed.com/release-latest.rpm
sudo yum -y install nginx-module-abuse-guard
Conéctalo:
load_module modules/ngx_http_abuse_guard_module.so;
http {
abuse_guard_zone zone=clients:10m; # una zona de memoria compartida
server {
location / {
abuse_guard zone=clients; # hacer cumplir aquí
}
}
}
sudo nginx -t && sudo systemctl reload nginx
Esos valores predeterminados prohíben cualquier IP que devuelva 100 403/404 respuestas dentro de un
período de 5 minutos, durante una hora. Ajusta o afloja cada número a continuación.
Configuración
Abuse Guard consta de cuatro directivas. La primera declara una política; las demás la aplican, exemptan a personas de ella y (opcionalmente) la comparten entre máquinas.
Declarar una política — abuse_guard_zone
Una directiva a nivel http. Crea una zona de memoria compartida y establece la
política que la rige. Establece tantas o tan pocas configuraciones como desees; el
nombre y tamaño de la zona son lo único que debes proporcionar; valores predeterminados sensatos completan el resto (los valores mostrados a continuación son exactamente esos predeterminados).
abuse_guard_zone zone=clients:10m ← nombre + tamaño (lo único que es obligatorio)
key=$binary_remote_addr ← quién es "un cliente"
statuses=403,404 ← qué respuestas cuentan como errores
interval=300s ← la ventana de puntuación
threshold=100 ← errores en esa ventana → prohibir
block=60m; ← cuánto tiempo dura la prohibición
zone=clients:10m es la identidad y presupuesto de la política: un nombre que referencias
desde abuse_guard, y el tamaño de la memoria compartida. Aproximadamente 10 MB rastrean del orden de
cien mil clientes activos.
Todo lo demás es ajuste opcional:
key— la expresión que define un solo cliente. Cualquier variable de NGINX; el valor predeterminado$binary_remote_addrse basa en la IP de origen. Una solicitud cuyo clave resulte vacía se omite completamente (útil con unmap, a continuación).statuses— los códigos de respuesta que cuentan como errores: códigos individuales, rangos, o una mezcla, por ejemplostatuses=401,403,404,500-599. Por defecto es403,404.interval— la ventana en la que el puntaje se degrada (por defecto300s). Una ráfaga dentro de ella activa una prohibición; un goteo lento que se extiende nunca acumula.threshold— cuántos errores dentro de esa ventana cruzan la línea, hasta 1024 (por defecto100).block— cuánto tiempo permanece bloqueado un cliente activado (por defecto60m).inactive— cuánto tiempo un cliente inactivo permanece en memoria antes de ser reclamado (por defectomax(1h, interval, block); cualquier valor explícito debe ser al menos tan grande comointervalyblock).redis—onpara replicar las prohibiciones de esta zona a través de una flota (ver abajo);offpor defecto.persist— una ruta de archivo donde se vuelcan las prohibiciones activas al salir limpiamente del trabajador y se cargan al inicio.persist_secret— en compilaciones con soporte de instantáneas firmadas, una clave hex que añade autenticación HMAC-SHA256 para que un archivo manipulado sea rechazado.
Por qué
5xxse deja fuera por defecto: un error del servidor es generalmente obra de tu lado, y contarlo permitiría que un backend inestable hiciera que visitantes inocentes fueran prohibidos. Añadestatuses=403,404,500-599solo cuando desees actuar deliberadamente sobre clientes que desencadenan errores del servidor.
Aplicarlo — abuse_guard
Válido en bloques http, server y location, así que puedes proteger todo un sitio
o solo los puntos finales que atraen abusos. Nombra la zona para activarla; escribe
abuse_guard off; en un ámbito anidado para desactivarla nuevamente.
location /wp-login.php {
abuse_guard zone=clients status=429 log_level=warn;
}
zone— la zona (declarada arriba) cuya política se aplica aquí.status— el código que recibe un cliente prohibido, en cualquier lugar de400–599(por defecto429).dry_run—onpara observar sin hacer cumplir: el veredicto se registra pero no se escribe ninguna prohibición. Apagado por defecto.log_level— qué tan ruidosamente registrar cada decisión:info,notice(por defecto),warnoerror.
Despliega sin miedo con dry_run=on. Registra cada prohibición que emitiría
sin tocar el estado, para que puedas calibrar los umbrales contra el tráfico en vivo — incluso
junto a una ubicación que esté haciendo cumplir en la misma zona — luego actívalo en vivo.
Exemptar a los buenos — abuse_guard_allow
Contexto: http · server · location · repetible, heredado hacia abajo.
abuse_guard_allow 127.0.0.0/8;
abuse_guard_allow 10.0.0.0/8 192.168.0.0/16;
Los clientes listados nunca son contados y nunca son prohibidos. La coincidencia se basa en la verdadera
dirección de conexión, por lo que coopera con realip. Esta es también la forma en que proteges
crawlers de búsqueda verificados: permite los rangos publicados de Googlebot / Bingbot para que un
bot que recorre URLs obsoletas (y acumulando 404s) nunca sea atrapado.
Compartir prohibiciones a través de la flota — abuse_guard_redis
Contexto: http
abuse_guard_redis host=10.0.0.5 password=… ; # tls://host para TLS
abuse_guard_zone zone=clients:10m redis=on;
Apunta cada nodo a un Redis o Valkey, activa redis=on, y una prohibición ganada en cualquier
máquina se propaga a todas ellas. Predeterminados: port=6379, db=0, prefix=ag_,
timeout=100ms. Cómo se mantiene rápido es la siguiente sección.
SELinux: en sistemas de aplicación (RHEL, Rocky, AlmaLinux) el kernel impide que NGINX
abra la conexión a Redis hasta que lo permitas una vez —
setsebool -P httpd_can_network_connect 1. Omite esto y la replicación simplemente no hará nada
mientras la aplicación local continúe como de costumbre.
Una prohibición, cada nodo — sin ralentizar una sola solicitud
Detrás de un balanceador de carga, una prohibición por servidor es teatro: el atacante simplemente aterriza en un nodo diferente. Abuse Guard cierra esa brecha sin poner nunca a Redis en la ruta de la solicitud.
Cada nodo decide localmente y cuenta localmente. En el instante en que emite una prohibición, difunde ese único hecho al clúster y registra una copia duradera. Cada otro nodo lo importa en milisegundos, y cualquier nodo que estuvo fuera de línea lo reconcilia en el momento en que se reconecta. Debido a que la aplicación siempre se sirve desde el estado en memoria de cada nodo, la solicitud de un visitante nunca espera un viaje de red — el único costo de la agrupación es que un atacante recién prohibido se queda fuera de toda la flota un latido más tarde en lugar de instantáneamente.
Redis aquí es una campana de alarma unidireccional, no un libro mayor compartido consultado por cada solicitud — así que un Redis lento o ausente nunca puede añadir latencia a tu tráfico. Ejecútalo en una red privada y trátalo como privilegiado: cualquier cosa que pueda escribir en él puede emitir prohibiciones.
Prohibiciones que sobreviven a un reinicio
Apunta una zona a un archivo y las prohibiciones activas se vuelcan cuando el trabajador sale limpiamente, y luego se restauran al inicio. Recargas y reinicios ordenados mantienen las prohibiciones actuales sin ejecutar un escritor de zona completa periódicamente. Un fallo abrupto del proceso o de la máquina puede perder las prohibiciones emitidas desde la última salida limpia; la aplicación aún falla abierta.
abuse_guard_zone zone=clients:10m
persist=/var/lib/nginx/abuse_guard/clients.state
persist_secret=00112233445566778899aabbccddeeff;
La instantánea compacta contiene solo resúmenes de identidad y plazos de prohibición. CRC32
detecta corrupción, y un cambio atómico mantiene las escrituras parciales fuera de la ruta activa. Las compilaciones con soporte de instantáneas firmadas pueden además autenticarlo con
persist_secret. Mantén el directorio legible solo por el usuario del trabajador.
Ver todo lo que decide
Tres variables exponen el veredicto de Abuse Guard a tus registros y configuración:
| Variable | Valor |
|---|---|
$abuse_guard_status |
BYPASSED · PASSED · COUNTED · BLOCKED · DRY_RUN |
$abuse_guard_count |
Errores actualmente atribuidos a este cliente. |
$abuse_guard_blocked_until |
Tiempo Unix en que se levanta la prohibición, o 0. |
log_format guard '$remote_addr "$request" $status '
'guard=$abuse_guard_status count=$abuse_guard_count';
¿Teclando detrás de un CDN o proxy? Nunca confíes en un X-Forwarded-For sin procesar. Deja que
realip resuelva primero el verdadero cliente, luego utiliza $binary_remote_addr:
set_real_ip_from 10.0.0.0/8;
real_ip_header X-Forwarded-For;
real_ip_recursive on;
¿Necesitas lógica de exención por solicitud? Cualquier solicitud cuya key resuelva a una cadena
vacía se ignora — así que un map te permite, por ejemplo, rastrear visitantes anónimos por IP mientras
dejas a los usuarios autenticados sin tocar.
Diseñado para ser confiable en producción
Abuse Guard se mantiene a un estándar muy por encima de "se compila." Cada cambio pasa por el filtro de AddressSanitizer, UndefinedBehaviorSanitizer, Valgrind, análisis estático y fuzzing continuo de sus analizadores y formato en disco. Sus dependencias opcionales — agrupación e instantáneas firmadas — son de mejor esfuerzo por diseño: si Redis o el disco se comportan mal, la aplicación continúa silenciosamente desde la memoria local. Tu tráfico nunca se mantiene como rehén de una dependencia.
Obtén Abuse Guard
Abuse Guard es un módulo comercial de NGINX de GetPageSpeed LLC, entregado con actualizaciones y soporte continuos a través de una suscripción a GetPageSpeed.
- Navega por el catálogo completo de módulos de NGINX → https://nginx-extras.getpagespeed.com/modules/
- Licencias, implementaciones a gran escala, o ayuda para configurarlo → getpagespeed.com/contact-us
© GetPageSpeed LLC. Todos los derechos reservados.