Como agregar la lista negra de AbuseIPDB al Firewall de Linux o Ubuntu

[Tutorial] Como agregar la lista negra de AbuseIPDB al Firewall

La lista negra de AbuseIPDB es una gran herramienta que nos permite conocer cuales son los clientes que más reportes de abuso han tenido. Si usamos esto a nuestro favor, podemos evitar toda clase de ataques.

En esta pequeña entrada, hablaré de como hacer uso de dicha base de datos para proteger un servidor corriendo Linux. Y en mi caso Ubuntu.

La base de datos que ofrece AbuseIPDB nos permite saber todo un historial sobre una dirección IP. Cuantas veces ha sido reportada, por quien e incluso que tipos de ataques ha realizado.

Esta información es especialmente útil si contamos con otras herramientas como fail2ban. Claro, esto hablando en el caso de servidores.

Pero a veces, no solo queremos consumir una dirección a la vez. Tampoco queremos solo reportar quienes están intentando vulnerar un recurso.

Es ahí en donde la lista negra de AbuseIPDB entra en juego.

Información que contiene la lista negra de AbuseIPDB

La lista negra, en pocas palabras, solamente contiene una lista de los clientes con mayor actividad, con el mayor número de reportes desde múltiples fuentes.

Por lo cual se vuelve una gran herramienta a la hora de detener cualquier dirección que intente vulnerar un servidor. Ya que es casi seguro que lo harán.

Dicha lista, cuando es consultada, nos regresa una lista de hasta 10,000 direcciones peligrosas. Esto para las versiones gratuitas. Las de pago pueden simplemente saltarse dicho limite.

Sin embargo, aún dicha cantidad es importante. Nada despreciable considerando del tipo de clientes que se trata.

Como aprovechar esta lista

Gracias a que AbuseIPDB ofrece puntos de acceso fáciles de usar, nosotros podemos acceder a la lista negra usando el siguiente endpoint: https://api.abuseipdb.com/api/v2/blacklist

Sin embargo, para poder consultarla debemos de estar registrados y obtener una llave API. Si no la tienes, puedes crearte una en minutos.

Pero el truco está en implementar directamente la lista en el firewall de cualquier servidor. Eso se logra usando scripts y cron jobs. De esta forma, al menos cada 24 horas, se podrá actualizar la lista de forma local.

Para no sobrecargar el servidor, es recomendable hacer uso de las herramientas iptables e ipset. Dejando de lado a fail2ban y otras soluciones de cortafuegos.

Esto, por ejemplo, ya que ipset nos permite agregar un gran número de direcciones IP y manejarlas fácilmente mediante colecciones. Haciendo poco uso de recursos.

Un ejemplo práctico de la implementación

El agregar las direcciones conflictivas al cortafuegos es sencillo. En mi caso, he creado un script en python que hace ello por mi.

Para ello, utilizo también una colección creada con ipset. La cual se limpia antes de cualquier actualización.

De esa forma, los clientes que ya no se encuentran en la lista negra de AbuseIPDB son descartados. Aunque es posible mantenerlos, para fines prácticos de esta ejemplo, no se explora esa posibilidad.

Así, este es el script que se corre cada día y que actualiza los datos desde AbuseIPDB:

Explicación del script de la lista negra

El script de python3 anterior realiza una serie de acciones antes de consultar a AbuseIPDB y justo después de esto. Se explican los puntos más importantes:

#ejecuta: ipset flush blacklist
run([ipset_bin, 'flush', set_name])

Esta línea corre un subproceso, un comando, invocando a /sbin/ipset para indicarle que limpie la lista negra local de todos los ips que tiene en ella.

#ejecuta: ipset create blacklist iphash -exist
run([ipset_bin, 'create', set_name, 'iphash', '-exist'])

Si no existe una colección creada por ipset, esta será crea. Esta usará un método de hash ideal para direcciones aleatorias. Si la colección ya existe, no pasa nada.

#Consulta el API mandando las credenciales en las cabeceras
response = requests.get(blacklist_url, headers=request_headers)

Entonces, realizamos la consulta y obtenemos el grupo de direcciones que queremos agregar al cortafuegos. En este caso, los datos están en formato json y más adelante son convertidos para ser usados por el script.

#ejecuta: ipset add blacklist <direccion_ip> -exist
run([ipset_bin, 'add', set_name, client_data['ipAddress'], '-exist'])

Finalmente, procedemos a agregar las direcciones de la lista de AbuseIPDB en la colección. Con la opción -exist nos aseguramos de que, en el remoto caso de que exista un duplicado, no nos muestre algún error.

#ejecuta: iptables -I INPUT -m set --match-set blacklist src -j DROP
run([iptables_bin, '-I', 'INPUT', '-m', 'set', '--match-set', set_name, 'src', '-j', 'DROP'])

Esto es entonces lo que hace la magia. Con este comando le decimos al cortafuegos que use la colección que hemos creado para las conexiones entrantes. Si la IP que se intenta conectar está en la lista negra, simplemente será ignorada de forma silenciosa.

Sin embargo, es ideal que solo sea usada la primera vez que se ejecuta el script o cuando se reinicia el sistema.

Conclusiones sobre el proceso

Agregar la lista negra de AbuseIPDB es relativamente sencillo. En especial si sabes manejar algunas herramientas avanzadas.

Hay muchas formas de prevenir que clientes con mal comportamiento encuentren el servidor. Pero la comentada en esta entrada ha sido la más eficiente que he encontrado.

Esto después de haber intentado usar firewalld como una alternativa. Lo cual ciertamente me hizo ver las limitaciones de no trabajar a un nivel más cercano al núcleo.

Finalmente, hay que recordar que esta solución no es realmente «persistente», ya que la lista desaparecerá cada vez que se reinicie el sistema.

Pero esto se soluciona fácilmente. Volviendo a ejecutar cada vez que se reinicie el servidor o con comandos que el propio ipset aporta.

Sin embargo, ¿Qué tan seguido se reinicia un servidor?

Por lo cual, tener esta como una capa adicional de protección es relativamente sencillo.

Siempre y cuando sepas bien que es lo que estás haciendo.

Anterior

Liga Premier de México: Asistencia 2018-2019

Siguiente

[Review] Plugin Google Site Kit: Esencial para WordPress

8 Comentarios

  1. Hola, mi nombre es Alejandro.
    Al intentar ejecutar el script obtengo los siguientes errores

    ipset v6.30: The set with the given name does not exist
    ipset v6.30: Syntax error: cannot parse 2607:f298:5:114b::b54:d51: resolving to IPv4 address failed

    El fichero python fué cortado y pegado, solo le añadí la llave.

    Cuando termina de ejecutarse realizo iptables -L -n para ver si añadió algo y sigue igual que antes de ejecutar el comando.

    Estoy con raspbian 9.

    Saludos.

    • ¡Saludos Alejandro!

      El primer error puede deberse a que, por alguna razón, ipset no crea el set correspondiente (líneas 20 y 21 borran y crean de nuevo la lista) o algo sucede al momento de agregar los elementos.

      Una forma de saber si el set existe es usando el comando: ipset list -t

      Este debe de mostrarte una lista completa con todos los sets existentes. Entre ellos debería de existir uno con información como esta:
      Name: abuseipdb-abusers
      Type: hash:ip
      Revision: 4
      Header: family inet hashsize 8192 maxelem 65536
      Size in memory: 283760
      References: 1

      Si existe, es posible que la regla no este activada. Para esto hay que correr manualmente: iptables -I INPUT -m set –match-set abuseipdb-abusers src -j DROP

      Así ya debería de darte una lista completa de los ips bloqueados con iptables -L -n (cuidado, puede ser extremadamente larga).

      En cuanto al error de «resolving to IPv4 address failed», simplemente el script no verifica si el IP es versión 4 o versión 6. Eso lo corregiré más adelante (ya lo había detectado, pero al ser direcciones IPv6 no me afectaban tanto… aún).

      Cuando tenga un poco más de tiempo procurare actualizar bien esta entrada con los detalles que haz comentado.

      ¡Muchas gracias por el comentario!

      • Hola de nuevo, gracias por tu rapida respuesta.

        Realizo ipset list -t

        name: abuseipdb_blacklist // difiere del nombre que pones mas arriba.

        Al realizar iptables para activar la regla, obtengo el siguiente mensaje.

        iptables v1.6.0: Set abuseipdb-abusers doesn’t exist.

        El fichero python lo ejecuto y no obtengo error pero sigue con lo mismo, no añade ninguna ip.

        ¿Es posible que el nombre diferente abuseipdb_blacklist o abuseipdb-abusers tenga algo que ver?

        Saludos y gracias.

        • Después de correr el script, ¿Qué información obtienes al correr el siguiente comando?

          ipset list abuseipdb_blacklist

          Ya probé el script en mi entorno (por desgracia no tengo acceso a raspbian 9), pero no me muestra otro error más que el de IPv6, todo debería estar relativamente bien.

          Si después de correr el script y el comando que mostré (ojo, el nombre debe de coincidir con el que crea el script) hay una lista de IPs, entonces se esta cargando bien y está listo para agregarse al firewall.

          El script corre bien en Ubuntu 16.04 y ahí lo he vuelto a probar.

          Dime si continuas teniendo problemas, ya que pudiera deberse a otro problema especifico de raspbian.

          • Type: hash:ip
            Revision: 4
            Header: family inet hashsize 4096 maxelem 65536
            Size in memory: 165856
            References: 3
            Number of entries: 10000
            Members:
            XX.XX.XXX.XXX ……. Y un largo ecetera de ip.

            Te pongo tambien la primera linea de iptables -L -n

            DROP all — 0.0.0.0/0 0.0.0.0/0 match-set abuseipdb_blacklist src

            Esta regla esta 3 veces repetida. Pero no llega a añadir ninguna ip a iptables.

            Por lo que veo, descarga bien la lista de ip pero no es capaz de añadirla a Iptables.

            Ejecuto los procesos como root y el script python lo tengo en mi /home a la espera que funcione bien y llevarlo a un sitio mas adecuado.
            La verdad no entiendo python pero no creo que esto ultimo influya en el proceso.

            Saludos y Gracias de nuevo.

          • Oh, ya estaba funcionando en tu caso. El set de ips (creado por ipset) es un tipo de lista especial el cual se agrega por referencia a iptables. No vez una lista cuando usas iptables -L -n de los ips asociados al set, pero al estar vinculado mediante referencia es que ya está siendo aplicada.

            Si ya tienes varias instancias, puedes reiniciar tu raspberry. Eso debería de limpiar las tablas que existan en iptables y ipset y así puedes agregar de nueva cuenta la lista negra y solo una aparecerá.

            Pero por lo que comentas, ya estaba funcionando como debía.

  2. Ok, muchas gracias, como me comentaste que viera la lista de ip con el comando iptables -L -n y el resultado fue exactamente el mismo que sin el script pense que no hacia nada.
    Ahora solo me falta añadirlo al cron para que lo ejecute todos los dias.

    Referente al segundo error, no volvio a darlo.

    Gracias por todo, espero no tener que molestarte de nuevo.

    • Todo un placer ayudar!

      En cuando al error de las IPv6, tan pronto pueda estaré modificando el script para bloquearlas (como se debe).

      Y espero que este script te haya sido de utilidad!

Deja un comentario

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *

El Contenido es 2010-2020© kadai.com.mx y dtorrer.com

Creado con WordPress & Tema de Anders Norén

Pin It on Pinterest

Share This