GNU/Linux >> Tutoriales Linux >  >> Linux

Bloqueo de todo el tráfico de países individuales usando IPSet e IPTables

Introducción:
Mientras miraba el syslog, descubrí con demasiada frecuencia que los ataques de inicio de sesión SSH provienen de China o de Rusia. Tener suficiente de eso, y de todos modos no esperar ningún tráfico de ninguno de estos países, aunque uso fail2ban Aún así, decidí bloquear cualquier tráfico proveniente de estos 2 países. Fail2ban es una gran herramienta para bloquear intentos fallidos de iniciar sesión. PERO parece que todavía se están realizando muchos intentos (miles) por día. Solo puedo suponer que el atacante está usando el envío paralelo de intentos y hasta que Fail2ban (basado en registros de autenticación) reacciona, muchos han pasado.
Para hacer un bloqueo completo de IP con listas precargadas de rangos de IP, comencé usando iptables con una regla por rango de IP, PERO la carga de las reglas tardaba demasiado y, lo que es más importante, la carga de todos los rangos de IP, como reglas puras de iptables, hizo que mi servidor fuera inestable, lo que significa que... ¡se bloqueó! Se dice que más de max. 25.000 reglas en las iptables, especialmente mayores de 27.000, las reglas pueden poner el kernel en un estado inestable.
Para remediarlo, uso ipset con iptables . ipset está especialmente concebido para tratar con grandes listas de IP Range (tablas hash de acceso rápido) que pueden contener hasta 65536 entradas.

NOTA: El siguiente script solo es válido para distribuciones de Linux basadas en Debian. Para otras distribuciones, deberá adaptar el script en consecuencia.

Principio de esta protección de bloqueo de países :
Los rangos de IP en formato CIDR se toman del sitio web http://www.ipdeny.com/ipblocks/data/countries/ y se ingresan en las listas individuales de IPSet que se nombran por códigos de país y luego se hace referencia por iptables para definir el OBJETIVO (qué hacer con las IP que coinciden:DROP )
NOTA: En este ejemplo, el script establece el objetivo de las reglas de iptables en DROP en lugar de RECHAZAR para evitar un alto tráfico de respuestas de rechazo de pila TCP/IP. SOLTAR no responde nada.

NOTA IMPORTANTE: Este script a continuación debe ejecutarse DESPUÉS cargó sus reglas regulares de firewall. INSERTOS las nuevas reglas de iptables de tal manera que cualquier paquete entrante de esos países definidos será bloqueado ANTES cualquier otro procesamiento en su cortafuegos.

Pasos:
#!/bin/bash
# Description: Uses IPSET and IPTABLES to block full countries from accessing the server for all ports and protocols
# Syntax: countries_firewall.sh countrycode [countrycode] ......
# Use the standard locale country codes to get the proper IP list. eg.
# countries_firewall.sh cn ru ro
# Will create tables that block all requests from China, Russia and Romania
# Changes: 13.11.2016 Initial creation of script
# Note: To get a sorted list of the inserted IPSet IPs for example China list(cn) run the command:
# ipset list cn | sort -n -t . -k 1,1 -k 2,2 -k 3,3 -k 4,4
# #############################################################################
# Defining some defaults
iptables="/sbin/iptables"
tempdir="/tmp"
sourceURL="http://www.ipdeny.com/ipblocks/data/countries/"
#
# Verifying that the program 'ipset' is installed
if ! (dpkg -l | grep '^ii ipset' &>/dev/null) ; then
echo "ERROR: 'ipset' package is not installed and required."
echo "Please install it with the command 'apt-get install ipset' and start this script again"
exit 1
fi
[ -e /sbin/ipset ] && ipset="/sbin/ipset" || ipset="/usr/sbin/ipset"
#
# Verifying the number of arguments
if [ $# -lt 1 ]; then
echo "ERROR: wrong number of arguments. Must be at least one."
echo "countries_firewall.sh countrycode [countrycode] ......"
echo "Use the standard locale country codes to get the proper IP list. eg."
echo "countries_firewall.sh cn ru ro"
exit 2
fi
#
# Now load the rules for blocking each given countries and insert them into IPSet tables
for country ; do
# Read each line of the list and create the IPSet rules
# Making sure only the valid country codes and lists are loaded
if wget -q -P $tempdir ${sourceURL}${country}.zone ; then
# Destroy the IPSet list if it exists
$ipset flush $country &>/dev/null
# Create the IPSet list name
echo "Creating and filling the IPSet country list: $country"
$ipset create $country hash:net &>/dev/null
(for IP in $(cat $tempdir/${country}.zone) ; do
# Create the IPSet rule from each IP in the list
echo -n "$ipset add $country $IP --exist - "
$ipset add $country $IP -exist && echo "OK" || echo "FAILED"
done) > $tempdir/IPSet-rules.${country}.txt
# Destroy the already existing rule if it exists and insert the new one
$iptables -D INPUT -p tcp -m set --match-set $country src -j DROP &>/dev/null
$iptables -I INPUT -p tcp -m set --match-set $country src -j DROP
# Delete the temporary downloaded counties IP lists
rm $tempdir/${country}.zone
else
echo "Argument $country is invalid or not available as country IP list. Skipping"
fi
done
# Display the result of the iptables rules in INPUT chain
echo "======================================"
echo "IPSet lists registered in iptables:"
$iptables -L INPUT -n -v | grep 'match-set'
# Dispaly the number of IP ranges entered in the IPset lists
echo "--------------------------------------"
for country ; do
echo "Number of ip ranges entered in IPset list '$country' : $($ipset list $country | wc -l)"
done
echo "======================================"
#
#eof

Inicio de sesión de la operación de script:

Como puede ver en el script, la adición de rangos de IP en las tablas de IPSet se registra en:$tempdir/IPSet-rules.${country}.txt que se sobrescribe cada vez que se ejecuta el script para el mismo país.

Inicio del guión

Para asegurarme de que este complemento de firewall se inicie correctamente en cada arranque, pero después de que el usuario defina el firewall, lo inicio a través de cron @reboot trabajo después de un retraso de aproximadamente 40 segundos (que se puede ajustar a sus necesidades) para permitir que se inicien otros servicios, incluido el servicio de firewall. Soy consciente de que este método para iniciar el script no es muy elegante, pero se adapta a casi todas las variaciones de las distribuciones de Linux, ya sea que estén basadas en Sysinit-V o Systemd. Ejemplo de trabajo cron raíz:
@reboot /bin/sleep 40 ; /bin/bash -c ". /root/.bashrc ; /root/bin/countries_firewall.sh cn ru"

Envío de informes de tráfico por correo electrónico

Para enviar informes de tráfico por correo electrónico todos los días, recopilo todos los días los datos de tráfico de iptables, los formateo y los envío por correo electrónico utilizando el siguiente script bash. Este script será ejecutado todos los días por cron (colocado en /etc/cron.daily/) y el contador de tráfico se reiniciará.
#!/bin/bash
# Purpose: Sends the blocked traffic report per email and resets the counter
# Syntax: iptables_report
# Dependencies: Systems tools: iptables, awk, column, whois, sendmail
# Changes: 13.11.2016 First implementation of script
#----------------------------------------------------------
HOST=$(cat /etc/hostname | tr 'a-z' 'A-Z')
email="[email protected]"
reportsender="cron@$HOST"
subject="BLOCKED Packets report on $(hostname | tr 'a-z' 'A-Z')"
tempdir="/tmp"
file1="iptables_report1.txt"
file2="iptables_report2.txt"
#
#------------ Build the header of the mail to send ------------
echo "From: $reportsender" > $tempdir/$file1
echo "To: $email" >> $tempdir/$file1
echo "Subject: $subject" >> $tempdir/$file1
echo "MIME-Version: 1.0" >> $tempdir/$file1
echo 'Content-Type: text/html; charset="ISO-8859-15"' >> $tempdir/$file1
echo "" >> $tempdir/$file1
echo "<br />" >> $tempdir/$file1
echo -e "<font size=3 FACE='Courier'><pre>" >> $tempdir/$file1
# Formatted message starts here
# Add the country at the end of each line
# Load the header and data to the temporary file 2
echo -e "Packets Bytes Source \n======= ========= ======" >$tempdir/$file2
/sbin/iptables -L -n -v | /bin/grep -v '^ 0' | /bin/grep 'match-set' | /usr/bin/awk '{print $1" "$2" "$11}' >> $tempdir/$file2
#
# Format temp file2 into temp file1
cat $tempdir/$file2 | column -t >> $tempdir/$file1
#
#
# Add the last HTML preformatting End
echo -e "</pre>" >> $tempdir/$file1
echo "" >> $tempdir/$file1
#
#----------------- Send the prepared email ---------------------------
# now format the report and send it by email
cat $tempdir/$file1 | /usr/sbin/sendmail -t
rm $tempdir/$file1 $tempdir/$file2
#
# Reset the iptables counters
/sbin/iptables -Z
#
# eof

Creación del trabajo cron para informes diarios regulares
Guarde ese archivo en ej. /etc/cron.daily/iptables_report
Hágalo ejecutable:
chmod 755 /etc/cron.daily/iptables_report
Ejemplo de informe de correo electrónico:
Packets Bytes Source
======= ========= ======
188 7852 ru
19295 1150K cn

Estado manual:
Para obtener el estado manual de las reglas de iptables para la cadena INPUT, ejecute el comando:
iptables -L INPUT -v -n
Para obtener una lista ordenada de una lista de IP de IPSet, ejecute el comando (p. ej., para Rusia):
ipset list ru | sort -n -t . -k 1,1 -k 2,2 -k 3,3 -k 4,4


Linux
  1. Cómo listar, cargar y descargar archivos desde un servidor SFTP usando golang

  2. Bloquear rango de IP de países con GeoIP e iptables

  3. Cómo monitorear y registrar el tráfico de red en Linux usando vnStat

  4. Usando awk para imprimir todas las columnas desde la enésima hasta la última

  5. Eliminar todos los caracteres especiales y mayúsculas y minúsculas de la cadena en bash

Cómo convertir de paquete RPM a DEB y DEB a RPM usando Alien

Todo sobre archivos tar y cómo tar, untar archivos en Linux usando Terminal

Cómo permitir todo el tráfico de un servidor usando firewalld en CentOS/RHEL

CentOS / RHEL:Cómo bloquear puertos entrantes y salientes usando iptables

¿Preguntas sobre IPTables y DHCP?

iptables elimina todas las solicitudes ICMP entrantes excepto de una IP