¿Que es ipset?
Para que nos entendamos, podríamos definir ipset como una lista desordenada de direcciones o rangos ip.
IPset es una herramienta complementaria de iptables que nos permite aplicar una regla de iptables a miles de direcciones ip sin que esto afecte a nuestro rendimiento. Voy a tratar de explicarme mejor.
¿Cuantas veces hemos ido viendo como recibimos un montón de intentos de acceder a nuestro servidor, bien sea por ssh, postfix o cualquier otro servicio que tengamos levantado? A mi me pasa continuamente, me pongo a mirar los logs y me vuelvo loco viendo el log como avanza rápidamente con múltiples intentos acceder a través de ssh, postfix y otros tantos servicios que tengo funcionando.
Como la mayoría de vosotros, en mis inicios, veía como constantemente desde la misma dirección ip intentaban acceder, lo que hacía era agregar una regla de iptables para esa dirección ip y claro, ¿cual es el problema? el problema es que cada regla de iptables digamos que consume recursos, no la regla de iptables, si no la acción de comprobar cada regla de iptables. Si tenemos una regla de iptables, no pasa nada, 10 tampoco, pero cuando nos enfadamos con el mundo y vamos bloqueando cada una de las direcciones ip que desconocemos de donde vienen y nos liamos a bloquear, podemos llegar a tener miles de reglas de iptables, a mi el servidor se me quedaba literamente frito cuando cargaba todas las reglas de iptables. Nooorrrmal!
¿Como funciona ipset?
Lo dicho, imaginate que tienes un archivo de texto plano, pones un montón de direcciones o rangos de ip ahí dentro, luego le dices a iptables que coja esa lista y que aplica una regla concreta ( o las que necesites ).
Lo primero que debemos hacer, es decirle a ipset que nos cree esa lista y luego le diremos a iptables que nos aplique la regla que queramos a esa lista. Veamos un par de ejemplos para que nos quede claro.
Bloquear una lista de rangos de direcciones ip
Lo rpimero que vamos a hacer, es crear una lista llamada countryblock ( yo la he llamado countryblock por un ejemplo que luego pondré, pero tu la puedes llamar como quieras ) para agregar los rangos de ip que queramos.
# ipset create countryblock hash:net
Lo siguiente que haremos será agregar los rangos de direcciones ip que queramos a la lista que acabamos de crear.
# ipset add countryblock 14.144.0.0/12
# ipset add countryblock 27.8.0.0/13
# ipset add countryblock 58.16.0.0/15
# ipset add countryblock 1.1.1.0/24
Ahora que ya tenemos esa lista creada con el conjunto de rangos de ip que queremos, le decimos a iptables que aplique la regla que queramos. En este caso, lo que queremos es bloquear esos rangos de ip, así que vamos a ello con la siguiente regla de iptables.
iptables -I INPUT -m set --match-set countryblock src -j DROP
Ala! Ya tenemos esos rangos de ip bloqueados y con solo una regla de iptables. Ahora mismo, cuando alguien trate de acceder solo tendrá que pasar por una regla de iptables en vesz de 10, 100 o 1000 hasta verificar si tiene o no tiene permitido el acceso, esto nuestro servidor nos lo agradecerá utilizando muchos menos recursos y haciendo que las conexiones sean infinitamente mucho más rápidas. ¿Que te parece?.
Bloquear una lista de direcciones ip
Ahora, imaginate que has bloqueado todos los rangos de ip desde donde crees que están intentando acceder o utilizar de una forma no consentida los servicios de tu servidor pero siempre hay alguien que se sale de la norma, quiero decir que no todos los que estén intentando acceder o atacar a tu servidor van a estar en esos rangos de ip que has bloqueado, algún espabilado de otro rango de direcciones ip va a intentar hacerte la puñeta seguro y quizá no te interesa bloquear todo el rango ip, solo te interesa bloquear esa ip en concreto, pues ahora te explico como solucionar el problema, es exactamente igual de fácil pero esta vez, vamos a crear una lista de ips.
Creraremos nuestra lista, como hemos hecho antes, pero esta vez le vamos a decir que es una lista de direcciones ip y la vamos a llamar ipblock. Fíjate que antes le hemos pasado el parámetro hash:net a ipset, pues ahora le diremos que en vez de ser una lista de tipo redes ( net ) es una lista de direcciones ip pasándole el parámetro hash:ip.
# ipset create ipblock hash:ip
Ya te imaginarás que es lo que viene ahora, estoy seguro, pero por si a caso aún no te has tomado el segundo café del día o eres nuevo en esto, te lo explico enseguida.
Agregamos las direcciones ip que nos están haciendo la vida imposible a la lista que acabamos de crear.
# ipset add ipblock 8.8.8.8
# ipset add ipblock 8.8.4.4
# ipset add ipblock 192.168.50.3
Igual que hemos hecho antes, le decimos a iptables que aplique la regla que queramos a la lista que acabamos de crear. Pues lo dicho, vamos a bloquear las direcciones ip que hemos agregado a nuestra lista.
iptables -I INPUT -m set --match-set ipblock src -j DROP
Fácil ¿Verdad?, pues ya sabes como ahorrar recursos y bloquear miles de direcciones ip a la vez sin morir en el intento.
¿Automatizamos un poquito?
Todos sabemos que hay ciertos paises que tienen como afición nacional intentar utilizar equipos de otras personas para fines malvados mientras acarician un gatito y se ríen.
Para bloquear uno o varios paises en muy poco tiempo os dejo un script que obtiene los rangos de ip de cada pais, los mete en una lista y los bloquea.
#!/bin/bash
# Purpose: Block all traffic from RUSIA (ru) AFGHANISTAN (af) and CHINA (cn). Use ISO code.
# Note: You can add all the countries you want in 2 letter ISO format.
# Author: Ivan Amat
# Based on a previous script found on internet that apply iptables rules without ipset
# Countries to block in 2 letter ISO format
ISO="ru af cn"
# Create this path if not exist or change it
ZONEROOT="/opt/scripts/security/zones"
DLROOT="http://www.ipdeny.com/ipblocks/data/countries"
# Create networks list
ipset create countryblock hash:net
# Loop for each country
for c in $ISO
do
# Local zone file
tDB=$ZONEROOT/$c.zone
# Get fresh zone file
echo "Downloading $c zone..."
wget -O $tDB $DLROOT/$c.zone
# Log message
echo "$c country drop $tDB"
# Add iptables rules
echo "Adding country $c to the list..."
BADIPS=$(egrep -v "^#|^$" $tDB)
# Loop for add each network to the list
for ipblock in $BADIPS
do
echo "Add $ipblock"
ipset add countryblock $ipblock
done
done
echo "Setting up iptables..."
iptables -I INPUT -m set --match-set countryblock src -j DROP
echo "Done!"
echo "Blocking ssh port..."
# Allow only your IP address
iptables -A INPUT -p tcp -s --dport 22 -j ACCEPT
iptables -A INPUT -p tcp --dport 22 -j REJECT
echo "Port 22 blocked!"
echo "Done!"
exit 0
Espero que este pequeño script te pueda ayudar aunque sea solo un poquito a protegerte de algunos ataques. Pronto te hablaré más herramientas, como fail2ban y como realizar algunas configuraciones para protegerte un poquito más.
* No olvides que las páginas oficiales tienen documentación oficial y pueden estar más actualizadas que cualquier post que puedas encontrar por la web. Estos posts te pueden servir de ayuda para entender mucho mejor algo que en la documentación oficial lo explican de forma muy técnica. Mi recomendación siempre será que después de leerte cualquier post, te des una vuelta por la documentación oficial.