Hola, he escrito un script para openwrt BB 14.07 que banea las direcciones IP que fallan la contraseña Dropbear SSH mas de 2 veces o que intentan conectarse con usuarios no validos.
El script añade la direcion baneada a una cadena de iptables con destino DESCARTAR (DROP).
Las ips baneadas se borran al reiniciar el router, pero quedan grabadas en el archivo de log y se recargan al volver a encender.
Tiempo de baneo 24 horas, modificable dentro del script.
Animo a todos a modificar el script y mejorarlo o lo que sea.
Actualizacion 20.sept.2014Cambiadas las cadenas de destino de baneo. Ahora el destino es
input_wan_rule que es lo recomendado en la documentación de openwrt.
ACTUALIZACION 07 MARZO 2016:EDITADO 08 marzo : Corregido el nombre del fichero de origen.
Novedades:
Instalacion automatica en /root modificable desde dentro del archivo de instalacion.
Funcionamiento configurable para WAN o LAN o ambas.
Se instala automaticamente en el cron para iniciarse cada 10 minutos.
Instalacion:
Copiar al router los dos archivos instalar.sh y fail2ban.pre a la carpeta /tmp o cualquier otra y ejecutar instalar.sh
# chmod 755 instalar.sh
#./instalar.sh
https://drive.google.com/open?id=0Bw50IJmzFr-FcU9UeHNIMjNneUUhttps://drive.google.com/open?id=0Bw50IJmzFr-FLWlsRzRjOEc1UTA # Directorio de instalacion por defecto "/root"
# Si cambiamos esto debemos cambiarlo tambien en el fichero ejecutable fail2ban.sh.
destino="/root"
touch $destino/fail2ban.sh
touch $destino/logfail2.log
cat fail2ban.pre > $destino/fail2ban.sh
chmod 755 $destino/fail2ban.sh
#Anadimos el script al crontab para que corra cada 10 minutos
sed -i '/'fail2ban'/d' /etc/crontabs/root
echo "# Script fail2ban" >>/etc/crontabs/root
echo "*/10 * * * * $destino/fail2ban.sh" >>/etc/crontabs/root
/etc/init.d/cron restart
Archivo fail2ban.pre (copiar en la misma carpeta que instalar.sh)
# Script que detecta los intentos de conexion fallidos al servidor SSH, ya sea por contrasena erronea
# o por usuario no valido y protege el sistema baneando la IP de origen utilizando el cortafuegos de Linux Iptables.
# Tiempo de baneo configurable y tablas de baneo de IP permanentes al reinicio del sistema.
# Probado en OpenWrt 14.04 Barrier Breaker.
#!/bin/sh
#============================================================================================================
#===========================================OPCIONES=========================================================
# Tiempo de baneo (en segundos). Transcurrido ese tiempo se desactiva el baneo y se quita la IP de la lista.
# Por defecto 24 horas, 86400 segundos.
ban_time=86400
# Directorio de instalacion del script donde estan los ficheros fail2ban.sh y logfail2.log
# Por defecto se instala automaticamente en "/root". Si hemos modificado el archivo de instalacion para instalar en otra carpeta, tambien debemos modificar este.
destino="/root"
# Funcionamiento en internet, red local o ambas. Descomentar la opcion deseada. Por defecto solo internet.
# input_wan_rule= Solo internet (defecto), input_lan_rule= Solo red local, input_rule funcionamiento en ambas redes.
# Si cambiamos este valor debemos reiniciar el router.
alcance="input_wan_rule"
#alcance="input_lan_rule"
#alcance="input_rule"
#=============================================================================================================
#======================================COMPROBACION INICIAL===================================================
#Si es la primera vez que lanzamos el script, debemos crear el fichero donde se guardan
#las ips baneadas.
if [ ! -f $destino/logfail2.log ]
then
touch $destino/logfail2.log
fi
# Comprobamos si acabamos de iniciar el router y en ese caso anadimos las direcciones IP baneadas del log
if [ ! -f /tmp/fail2ban.tmp ]
then
touch /tmp/fail2ban.tmp
for x in `cat $destino/logfail2.log |awk '{print $2}' FS=":"`
do iptables -I $alcance 1 -s $x -j LOG --log-prefix "--ATAQUE--FUERZA--BRUTA--";
iptables -I $alcance 2 -s $x -j DROP;
done
fi
#=============================================================================================
#===============================BANEO INTENTOS USUARIOS VALIDOS===============================
# Comprobamos las conexiones y el numero de veces que el resultado ha sido "Bad password"
for i in `logread|grep "Child connection"| awk '{print $11}'|awk '{print $1}' FS=":"`
do brute=`logread|grep 'Bad password'|grep $i |wc -l`;
# Si son mas de dos veces guardamos la IP en la variable "badip"
if [ "$brute" -gt 2 ];
then badip=`logread|grep "Bad password"|grep -m 1 $i| awk '{print $14}'|awk '{print $1}' FS=":"`
# Comprobamos si la direccion IP ya esta en la lista de baneados:
oldban=`cat $destino/logfail2.log |grep $badip|wc -l`;
# Si la IP no aparece en la lista la anadimos a iptables.
if [ "$oldban" -lt 1 ];
then iptables -I $alcance 1 -s $badip -j LOG --log-prefix "--ATAQUE--FUERZA--BRUTA--";
iptables -I $alcance 2 -s $badip -j DROP;
# Por ultimo anadimos la IP al archivo de baneados "$destino/logfail2.log" y la hora a la
# que terminara el baneo de esa IP en formato epoch(segundos desde 01-01-1970)
fecha_actual=`date +%s`
unban_date=`expr $fecha_actual + $ban_time`
echo "$unban_date:$badip" >> $destino/logfail2.log;
fi;
fi;
done;
#================================================================================================
#===============================BANEO INTENTOS USUARIOS NO VALIDOS===============================
# Comprobamos las conexiones y el numero de veces que el resultado ha sido "invalid shell"
for i in `logread |grep "Child connection"|awk '{print $11}'|awk '{print $1}' FS=":"'`
do brute=`logread|grep -A 4 $i |grep "Login attempt for nonexistent"|wc -l`
if [ "$brute" -gt 2 ];
then badip=`logread|grep "Child connection"|grep -m 1 $i| awk '{print $11}'|awk '{print $1}' FS=":"`
# Comprobamos si la direccion IP ya esta en la lista de baneados:
oldban=`cat $destino/logfail2.log |grep $badip|wc -l`;
# Si la IP no aparece en la lista la anadimos a iptables.
if [ "$oldban" -lt 1 ];
then iptables -I $alcance 1 -s $badip -j LOG --log-prefix "--ATAQUE--FUERZA--BRUTA--";
iptables -I $alcance 2 -s $badip -j DROP;
# Por ultimo anadimos la IP al archivo de baneados "$destino/logfail.log" y la hora a la
# que terminara el baneo de esa IP en formato epoch(segundos desde 01-01-1970)
fecha_actual=`date +%s`
unban_date=`expr $fecha_actual + $ban_time`
echo "$unban_date:$badip" >> $destino/logfail2.log;
fi;
fi;
done;
#================================================================================================
#=========================BORRADO DE BANEO TRANSCURRIDO EL TIEMPO ASIGNADO=======================
# Un bucle comprueba si alguno de los registros del fichero logfail2.log tiene una fecha anterior
# a la actual. En caso afirmativo borra las reglas de iptables y los registros del log.
fecha_actual=`date +%s`
for z in `cat $destino/logfail2.log`
do unban_time=`echo $z|awk -F ":" '{print $1}'`
unban_ip=`echo $z|awk -F ":" '{print $2}'`
if [ "$unban_time" -lt "$fecha_actual" ]
then sed -i '/'$unban_ip'/d' $destino/logfail2.log
unban_rule=`iptables -L -n --line-numbers|grep -m 1 $unban_ip|awk '{print $1}'`
iptables -D $alcance $unban_rule
iptables -D $alcance $unban_rule
fi
done