GNU/Linux >> Tutoriels Linux >  >> Linux

Bloquer tout le trafic provenant de pays individuels à l'aide d'IPSet et d'IPTables

Présentation :
En consultant le journal système, j'ai constaté trop souvent que les attaques de connexion SSH provenaient soit de Chine, soit de Russie. En avoir assez, et de toute façon ne pas s'attendre à du trafic en provenance de l'un de ces pays, bien que j'utilise fail2ban j'ai quand même décidé de bloquer tout trafic provenant de ces 2 pays. Fail2ban est un excellent outil pour bloquer les tentatives de connexion infructueuses. MAIS il semble que de nombreuses tentatives (des milliers) par jour se déroulent encore. Je ne peux que supposer que l'attaquant utilise l'envoi parallèle de tentatives et jusqu'à ce que Fail2ban (basé sur les journaux d'authentification) réagisse, beaucoup ont traversé.
Pour faire un blocage complet des IP avec des listes préchargées de plages IP, j'ai commencé par utiliser iptables avec une règle par plage IP, MAIS le chargement des règles prenait trop de temps et surtout, le chargement de toutes les plages IP, comme de pures règles iptables, rendait mon serveur instable, c'est-à-dire… il plantait !!! On dit que plus que max. 25 000 règles dans les iptables, en particulier supérieures à 27 000, peuvent mettre le noyau dans un état instable.
Pour remédier à cela, j'utilise ipset avec iptables . ipset est spécialement conçu pour traiter de grandes listes de plages IP (tables de hachage à accès rapide) pouvant contenir jusqu'à 65536 entrées.

REMARQUE : Le script ci-dessous n'est valable que pour les distributions Linux basées sur Debian. Pour les autres distributions, vous devrez adapter le script en conséquence.

Principe de cette protection contre le blocage des pays :
Les plages d'adresses IP au format CIDR sont récupérées sur le site Web http://www.ipdeny.com/ipblocks/data/countries/ et inscrites dans les listes individuelles de l'IPSet qui sont nommées par des codes de pays puis référencées par iptables pour définir la CIBLE (que faire avec les IP qui correspondent :DROP )
REMARQUE : Dans cet exemple, le script définit la cible des règles iptables sur DROP au lieu de REFUSER pour éviter un trafic élevé de réponses de rejet de pile TCP/IP. DÉPOSER ne répond rien.

REMARQUE IMPORTANTE : Ce script ci-dessous doit être exécuté APRÈS vous avez chargé vos règles de pare-feu habituelles. Il INSÉRE les nouvelles règles iptables de manière à ce que tous les paquets entrants provenant de ces pays définis soient bloqués AVANT tout traitement ultérieur dans votre pare-feu.

Étapes :
#!/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

Login de l'opération de script :

Comme vous pouvez le voir dans le script, l'ajout de plages IP dans les tables IPSet est connecté :$tempdir/IPSet-rules.${country}.txt qui est écrasé à chaque fois que le script est exécuté pour le même pays.

Démarrer le script

Afin de m'assurer que ce module complémentaire de pare-feu démarre correctement à chaque démarrage, mais après le pare-feu défini par l'utilisateur, je le démarre via cron @reboot tâche après un délai d'environ 40 secondes (qui peut être ajusté selon vos besoins) pour laisser démarrer d'autres services, y compris le service de pare-feu. Je suis conscient que cette méthode de démarrage du script n'est pas très élégante, mais elle convient à peu près à toutes les variantes des distributions Linux, qu'elles soient basées sur Sysinit-V ou Systemd. Exemple de tâche cron racine :
@reboot /bin/sleep 40 ; /bin/bash -c ". /root/.bashrc ; /root/bin/countries_firewall.sh cn ru"

Envoi de rapports de trafic par e-mail

Afin d'envoyer des rapports de trafic par e-mail tous les jours, je collecte chaque jour les données de trafic d'iptables, je les formate et je les envoie par e-mail à l'aide du script bash suivant. Ce script sera ensuite exécuté tous les jours par cron (mis dans /etc/cron.daily/) et le compteur de trafic sera réinitialisé.
#!/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

Créer la tâche cron pour les rapports quotidiens réguliers
Enregistrez ce fichier par ex. /etc/cron.daily/iptables_report
Rendez-le exécutable :
chmod 755 /etc/cron.daily/iptables_report
Exemple d'e-mail de rapport :
Packets Bytes Source
======= ========= ======
188 7852 ru
19295 1150K cn

Statut manuel :
Pour obtenir l'état manuel des règles iptables pour la chaîne INPUT, exécutez la commande :
iptables -L INPUT -v -n
Pour obtenir une liste triée d'une liste d'adresses IP IPSet, exécutez la commande (par exemple, pour la Russie) :
ipset list ru | sort -n -t . -k 1,1 -k 2,2 -k 3,3 -k 4,4


Linux
  1. Comment répertorier, télécharger et télécharger des fichiers à partir d'un serveur SFTP à l'aide de golang

  2. Fail2Ban Howto :Bloquer l'adresse IP à l'aide de Fail2ban et IPTables

  3. Comment surveiller et enregistrer le trafic réseau sous Linux à l'aide de vnStat

  4. Utiliser awk pour imprimer toutes les colonnes de la nième à la dernière

  5. Copiez tous les fichiers correspondant au modèle du répertoire et des sous-répertoires dans un seul répertoire

Comment convertir un package RPM en DEB et DEB en RPM à l'aide d'Alien

Tout sur les fichiers tar et comment tar, décompresser des fichiers sous Linux à l'aide du terminal

Comment installer MongoDB à partir de la source (et en utilisant YUM) sous Linux

Comment autoriser tout le trafic d'un serveur à l'aide de firewalld dans CentOS/RHEL

CentOS / RHEL :Comment bloquer les ports entrants et sortants à l'aide d'iptables

Supprimez tous les caractères spéciaux et la casse de la chaîne dans bash