Así que, viendo que alguien hace uso de direcciones IP de sistemas vulnerables para arrancar sus programas de ataque a sistemas VoIP, y que cuando estos dejan de funcionar, cambian de IP y siguen atacando… ¿para qué vamos a estar guardando en el firewall una lista sin fin de direcciones IP?
Primero, el firewall de Linux (IPTables) es de lo mejorcito que hay, tiene muy poca carga, es estable pero cuenta con un pequeño defecto cuando se almacenan «decenas o cientos de miles» de direcciones IP (lo que ocurre con SIPCheck, Fail2Ban o APIBan): se vuelve lento para aceptar o rechazar peticiones, algo que puede cargar bastante el sistema e incluso provocar problemas en las comunicaciones.
Qué es ‘ipset’ y cómo funciona
El pequeño ‘ipset‘ es una herramienta fácil y sencilla, complementaria de IPTables que maneja una lista desordenada de direcciones IP como si fuera una única regla del firewall. Esto es (para que lo entendamos mejor), que cuando nuestro sistema recibe un paquete y tiene que comprobar si puede o no dejarlo pasar, recorre TODO el firewall, lo cual, si tenemos 100.000 direcciones IP bloqueadas, por cada paquete que reciba, tendrá que hacer 100.000 comprobaciones antes de dejarlo pasar, una carga bestial para un sistema que maneja miles de paquetes UDP por segundo como es un servidor de comunicaciones VoIP.
Por lo tanto, en lugar de una «lista ordenada» de reglas, ipset sirve para manejar un «conjunto» de IP, de manera que es 10.000 veces más rápido (utiliza una búsqueda hash) que preguntar: -«¿Está esta lista en el conjunto?» y buscar secuencialmente una IP en la lista ordenada, así que no es casualidad que cuando el número de direcciones IP a bloquear sea demasiado grande, es muchísimo mejor utilizar ipset, que IPTables.
Al final ipset debe estar conectado a IPTables para que puedan ser bloqueadas las direcciones IP guardadas en «el conjunto».
De manera que cuando un sistema nos envía un paquete, el firewall sigue recorriendo sus líneas, pero una línea en particular dice: «Consulta el conjunto listanegra» y esa línea pregunta al conjunto si está la IP en él. La respuesta de ejecutar esa consulta es tan rápida como una simple línea de IPTables, por lo que la mejora en velocidad es muy interesante.
Instalación
Ahora sí, lo primero que tenemos que hacer es instalar ipset con nuestro gestor de paquetes:
1 |
yum install ipset |
una vez esté instalado, ya podemos empezar a hacer pruebas:
1.- Creamos un conjunto de IPs al que vamos a llamar: listanegra
1 2 3 4 5 |
# Si queremos crear un conjunto con un timeout máximo de 1 hora ipset create listanegra hash:ip timeout 3600 # Si no queremos que tenga timeout, basta con no ponérselo. # ipset create listanegra hash:ip |
2.- Una vez creado el «conjunto», podemos ver todos los conjuntos que tenemos:
1 |
ipset list |
3.- A continuación, enlazamos el conjunto «listanegra» con nuestro iptables:
1 2 3 4 5 |
# Para dar de alta el conjunto 'listanegra' en el iptables: iptables -I INPUT -m set --match-set listanegra src -j DROP # Siempre podemos eliminar el conjunto del iptables con: # iptables -D INPUT -m set --match-set listanegra src -j DROP |
4.- Por último, tenemos que añadir las direcciones IP al conjunto mediante el propio comando ipset:
1 2 3 |
ipset add listanegra 248.248.248.247 timeout 30 ipset add listanegra 248.248.248.248 timeout 20 ipset add listanegra 248.248.248.249 timeout 10 |
La primera IP será eliminada en 30 segundos, la segunda en 20 y la tercera en 10.
Si no se le define un «timeout», utilizará el timeout general que se puso al crear el conjunto: 3600.
5.- Recuerda que para borrar manualmente una IP del conjunto:
1 |
ipset del listanegra 248.248.248.247 |
y de esta manera, hemos visto cómo podemos banear de forma automática a cientos de miles de direcciones IP sin preocuparnos de eliminarlas manualmente.
En nuestro firewall, tan sólo aparecerá una línea indicando que tiene que «dropear» aquellas direcciones del conjunto ‘listanegra’
1 2 3 4 5 6 7 8 9 10 11 |
iptables -L -n Chain INPUT (policy ACCEPT) target prot opt source destination DROP all -- 0.0.0.0/0 0.0.0.0/0 match-set listanegra src Chain FORWARD (policy ACCEPT) target prot opt source destination Chain OUTPUT (policy ACCEPT) target prot opt source destination<code lang="bash" class="language-bash"> |