Se me ocurrió bloquear intentos de acceso a ciertas URLs en mi servidor Web. Al buscar alternativas para realizar esta tarea, lo primero que surge es fail2ban. Pero me pareció que, para este caso en particular, era como matar una mosca con una bazooka. Por ello decidí implementar un pequeño script bash que corra periódicamente desde cron.

El funcionamiento del script es sencillo. Primero busca intentos de acceso a ciertas URLs (a través de una lista de patrones) en el log de errores de Apache/Nginx y obtiene las direcciones IP asociadas a los clientes (utilizando grep, cut y demás yerbas). Para cada IP crea una nueva regla en el firewall para bloquear el tráfico proveniente desde dicha IP, utilizando iptables:

iptables -I INPUT 1 -s $IP -j DROP

Luego guarda cada IP en un archivo, junto con la fecha y hora en la que fue bloqueada.

El último paso consiste en remover bloqueos expirados. El script permite configurar la cantidad de horas que se desea bloquear cada IP (por defecto 1 hora). De esta forma, luego de procesar los nuevos bloqueos, busca los bloqueos expirados y los elimina (comparando la fecha guardada con la fecha actual menos la cantidad de horas especificada):

iptables -D INPUT -s $IP -j DROP

El script se encuentra publicado en GitHub: github.com/linuxitux/GTFO.

Cómo instalar el script GTFO

Clonar el repositorio:

# cd /usr/local
# git clone https://github.com/linuxitux/GTFO/blob/master/gtfo

Otorgar permisos de ejecución al script:

# chmod +x GTFO/gtfo

Configurar las siguientes variables:

  • ERRLOG - Ruta al log de errores de Apache/Nginx.
  • WORKDIR - Directorio de instalación.
  • LINES - Número de líneas a examinar.
  • KEYWORDS - Lista de patrones a buscar.
  • HOURS - Cantidad de horas a bloquear.

Por último, instalar el cronjob:

# crontab -e

Si se desea ejecutar cada 2 minutos, agregar:

*/2 * * * * /usr/local/GTFO/gtfo >> /var/log/gtfo.log

Ejemplo de ejecución:

root@linuxito:/usr/local/GTFO# ./gtfo 
GTFO run - 2016-11-02 10:14
Banning the following IPs:
87.4.85.46
91.200.12.155
84.238.141.127
Checking for expired bans...

El archivo banned.ip contiene la lista de direcciones IP, junto con la fecha y hora en que fueron bloqueadas:

root@linuxito:/usr/local/GTFO# cat banned.ip 
106.51.129.233 201611020956
115.117.45.34 201611020956
117.214.40.152 201611020956
151.50.22.63 201611020956
158.193.143.51 201611020956
172.6.84.177 201611020956
174.0.192.50 201611020956
175.142.165.35 201611020956
178.116.67.50 201611020956
180.190.66.1 201611020956
180.191.142.56 201611020956
185.37.168.73 201611020956
188.246.141.43 201611020956
213.6.148.30 201611020956
2.233.125.199 201611020956
39.57.6.29 201611020956
41.136.13.220 201611020956
47.216.166.202 201611020956
49.49.76.16 201611020956
5.43.108.59 201611020956
78.85.72.242 201611020956
83.215.135.151 201611020956
83.35.212.125 201611020956
85.242.171.240 201611020956
94.90.242.130 201611020956
176.31.245.146 201611020956
185.93.187.114 201611020956
83.142.196.169 201611020956
78.166.192.192 201611021006
84.40.120.207 201611021006
95.13.182.161 201611021006
87.4.85.46 201611021014
91.200.12.155 201611021014
84.238.141.127 201611021014

Para cada IP bloqueada se agrega una nueva regla en el firewall:

root@linuxito:/usr/local/GTFO# iptables -nL | grep DROP
Chain INPUT (policy DROP)
DROP       all  --  84.238.141.127       0.0.0.0/0           
DROP       all  --  91.200.12.155        0.0.0.0/0           
DROP       all  --  87.4.85.46           0.0.0.0/0           
DROP       all  --  95.13.182.161        0.0.0.0/0           
DROP       all  --  84.40.120.207        0.0.0.0/0           
DROP       all  --  78.166.192.192       0.0.0.0/0           
DROP       all  --  83.142.196.169       0.0.0.0/0           
DROP       all  --  185.93.187.114       0.0.0.0/0           
DROP       all  --  176.31.245.146       0.0.0.0/0           
DROP       all  --  94.90.242.130        0.0.0.0/0           
DROP       all  --  85.242.171.240       0.0.0.0/0           
DROP       all  --  83.35.212.125        0.0.0.0/0           
DROP       all  --  83.215.135.151       0.0.0.0/0           
DROP       all  --  78.85.72.242         0.0.0.0/0           
DROP       all  --  5.43.108.59          0.0.0.0/0           
DROP       all  --  49.49.76.16          0.0.0.0/0           
DROP       all  --  47.216.166.202       0.0.0.0/0           
DROP       all  --  41.136.13.220        0.0.0.0/0           
DROP       all  --  39.57.6.29           0.0.0.0/0           
DROP       all  --  2.233.125.199        0.0.0.0/0           
DROP       all  --  213.6.148.30         0.0.0.0/0           
DROP       all  --  188.246.141.43       0.0.0.0/0           
DROP       all  --  185.37.168.73        0.0.0.0/0           
DROP       all  --  180.191.142.56       0.0.0.0/0           
DROP       all  --  180.190.66.1         0.0.0.0/0           
DROP       all  --  178.116.67.50        0.0.0.0/0           
DROP       all  --  175.142.165.35       0.0.0.0/0           
DROP       all  --  174.0.192.50         0.0.0.0/0           
DROP       all  --  172.6.84.177         0.0.0.0/0           
DROP       all  --  158.193.143.51       0.0.0.0/0           
DROP       all  --  151.50.22.63         0.0.0.0/0           
DROP       all  --  117.214.40.152       0.0.0.0/0           
DROP       all  --  115.117.45.34        0.0.0.0/0           
DROP       all  --  106.51.129.233       0.0.0.0/0           
DROP       all  --  0.0.0.0/0            0.0.0.0/0           
Chain FORWARD (policy DROP)

En futuras versiones me gustaría que toda la configuración, incluyendo las reglas, se carguen desde un archivo de configuración.


Tal vez pueda interesarte


Compartí este artículo