Skip to main content
andrés ignacio torres

Bloquear agentes de usuario en la configuración de nginx

Los bots están por todos lados, así como los agentes maliciosos. Indexan, rastrean, descargan... y a veces (¿la mayoría? de las veces), abusan.

Más de una vez, me he topado con un aumento repentino e inesperado en consumo de CPU, RAM o algún otro recurso en servidores que administro, y tras revisar los logs de acceso, me encuentro que la causa es el acceso repetido de bots que intentan indexar el contenido de mis sitios una y otra vez.

En ocasiones, incluso, algunos plug-ins de WordPress que generan enlaces con parámetros GET únicos en cada carga de página han empeorado la situación, haciendo que estos bots entren en un bucle infinito intentando indexar cada página "diferente". ¡Qué desperdicio de ancho de banda y recursos de cómputo!

Para ponerle fin a esto, empecé a bloquear por defecto algunos agentes de usuario (user agents), retirando su acceso a los sitios web que administro directamente desde la configuración de nginx. Esto asegura que los agentes maliciosos ni siquiera tienen la oportunidad de causar la ejecución de mis servidores o aplicaciones, ni acceder a contenido estático. Puedes seguir pasos similares o incluso usar algún otro identificador diferente a los agentes de usuario para bloquear entidades no deseadas de tu servidor.

Crea una lista de agentes de usuario bloqueados #

Crea un nuevo archivo en /etc/nginx con el contenido siguiente y el nombre que desees.

Para este ejemplo, usaré agentes_de_usuario_bloqueados.rules:

map $http_user_agent $agente_de_usuario_bloqueado {
    # Todas las peticiones son permitidas por defecto
    default 0;

    # `~ejemplo` va a generar concidencias con cualquier
    # agente de usuario que tenga `ejemplo` en ella.
    # Algunos ejemplos:
    ~Amazonbot 1;
    ~openai 1;
    ~chatgpt 1;
    ~gptbot 1;
}

Esta lista puede hacerse tan corta o tan larga como necesites, y puedes cambiarla (sea para agregar o retirar agentes de usuario bloqueados) cuando lo necesites.

Bloquea peticiones según $agente_de_usuario_bloqueado #

Ahora que cuentas con un mapa accesible de agentes de usuario, es hora de exponer esta variable a nginx y bloquear peticiones no deseadas.

En /etc/nginx/nginx.conf, agrega lo siguiente al final del bloque http:

http {
    # Aquí el contenido usual
    # (...)

    # Incluye el archivo con el mapa de agentes de usuario bloqueados
    include /etc/nginx/agentes_de_usuario_bloqueados.rules;
}

Por último, edita el archivo de configuración de cada uno de tus sitios (dentro de /etc/nginx/sites-enabled/) y agregar lo siguiente dentro del bloque server, antes de empezar a redirigir las respuestas según location:

server {
    server_name aitorres.com;

    # Bloqueando agentes no deseados
    if ($agente_de_usuario_bloqueado) {
        # `444 No Response`, código de estatus HTTP
        # específico de `nginx`.
        # Puedes escoger otro código de estatus HTTP
        # estandar, como `404 Not Found` o `403 Forbidden`
        # de acuerdo a tus necesidades
        return 444;
    }

    # Resto de tu archivo de configuración, sin cambios
}

Para terminar, recarga o reinicia tu servidor nginx desde el terminal:

# Asegúrate primero de que la configuración sea válida
nginx -t

# Si todo se ve bien, recarga el servidor. Puedes reiniciarlo también
nginx -s reload

¡Y listo! Tu servidor empezará a bloquear estas peticiones, y deberías ver una reducción en el consumo de recursos. Si cuentas con registro de accesos para tu servidor, puedes comprobar que las peticiones de estos agentes bloqueados aparecen con el código de estatus HTTP que agregaste.

Una última nota: si modificas la lista de usuarios bloqueados posteriormente, recuerda recargar o reiniciar nginx para que lo cambios tomen efecto.

Este método no es infalible ya que depende de que el bot (o el agente malicioso) use un mismo agente de usuario consistentemente, pero es un inicio y sólo toma un par de minutos en configurar. Idealmente, llegará el día en que los bots nos dejen en paz; hasta entonces... ;)