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.