'

Outils pour utilisateurs

Outils du site


blog:2009:1101bannissement_d_adresses_ip

bannissement d'adresses IP

Qui n'a pas vu des tentatives de connexion SSH massives sur son serveur ? Il ne se passe pas un jour sans que ce genre de « désagrément » n'arrive. Ce sont des attaques par force brute, un abruti tente de se connecter avec différents utilisateurs (par exemple root) et différents mots de passe pour obtenir un shell sur la machine. C'est un peu comme les pourriels, il suffit qu'une connexion sur plusieurs dizaines de milliers réussisse pour que la campagne soit « rentable », ça ne coûte pas grand chose.

Pour parer ces attaques, une technique consiste à bloquer une adresse IP temporairement après n connexions infructueuses. C'est ce que fait fail2ban. Pour cela, il consulte les logs et après 6 « erreurs de mot de passe » bannit l'adresse IP pendant 30 minutes avec iptables (ou en modifiant le fichier /etc/hosts.deny). Depuis quelques temps, ces 30 minutes ne suffisent plus, les attaquants essaient pendant des heures. Une solution pourrait être d'augmenter ce délai mais quelques uns persistent pendant 24h ! J'ai donc choisi une solution plus … radicale.

fail2ban peut avertir l'administrateur par courriel. Lorsque que je remarque que la même adresse IP revient souvent (elle apparaît dans le titre du message), je la bannis pour une durée indéterminée. Pour cela, j'ai mis en place quelques scripts pour ma faciliter la tâche.

Tout d'abord, j'ai créé un script d'init qui prépare le pare-feu.

$ cat /etc/init.d/parefeu 
#!/bin/bash
iptables --append INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT
iptables --append INPUT -i lo -j ACCEPT
$ sudo update-rc.d -f parefeu defaults 90

Le script crée une règle qui autorise les connexions déjà établies, pour éviter de repasser par toutes les règles pour tous les paquets, c'est assez classique pour un pare-feu. La seconde règle autorise tous les flux sur l'interface loopback.

La commande update-rc.d crée le lien nécessaire à l'exécution du script au démarrage.

Pour bannir une adresse IP, j'ai créé quelques fonctions en BASH.

$ cat bannissement
#!/bin/bash
 
CHAIN='bannissement'
IPTABLES='sudo /sbin/iptables' 
 
# au lancement, création de la chaine de bannissement qui ne fait rien (RETURN)
function start_ban {
	# la chaine bannissement ne fera qu'envoyer le paquet vers la chaine qui supprimera la paquet
	$IPTABLES --new-chain $CHAIN
	$IPTABLES --append $CHAIN -j RETURN
	# création de la chaine de suppression et log
	$IPTABLES --new-chain ${CHAIN}-drop
	$IPTABLES --append ${CHAIN}-drop --jump LOG --log-prefix 'bannissement: '
	$IPTABLES --append ${CHAIN}-drop --jump DROP
	# insertion de la chain de bannissement en second après celle qui accepte les connexions déjà établies
	$IPTABLES --insert INPUT 2 --protocol TCP -m state --state new --jump $CHAIN
	# affichage des règles
	$IPTABLES --list --numeric
}
 
# suppression des bannissement
function stop_ban {
	# vidage + suppression des 2 chaines créées pour l'occassion
	$IPTABLES --flush $CHAIN
	$IPTABLES --flush ${CHAIN}-drop
	$IPTABLES --delete-chain $CHAIN
	$IPTABLES --delete-chain ${CHAIN}-drop
	# affichage du résultat
	$IPTABLES --list --numeric
}
 
# ajout d'un bannissement
function add_ban {
	# précaution en cas de manque d'argument
	if [[ $1 == "" ]]
	then
		echo "Il faut spécifier une adresse !"
		exit
	fi
	# insert de l'adresse à bannir
	# l'action est de renvoyer le paquet à la chaine bannissement-drop qui supprimera et loguera le paquet
	$IPTABLES --insert $CHAIN 1 --source $1 --jump ${CHAIN}-drop 
	$IPTABLES --insert $CHAIN 1 --source $1 --match comment --comment "$CHAIN"
	$IPTABLES --list --numeric
}
 
# suppression d'un bannissement
function del_ban {
	# précaution en cas de manque d'argument
	if [[ $1 == "" ]]
	then
		echo "Il faut spécifier une adresse !"
		exit
	fi
	# suppression de l'adresse à bannir
	$IPTABLES --delete bannissement --src $1 --jump bannissement-drop
	$IPTABLES --delete bannissement --src $1 --match comment --comment "$CHAIN"
	$IPTABLES --list --numeric
}

La fonction startban et stopban permettent respectivement de préparer iptables pour les bannissements et de les arrêter en supprimant la chaîne précédemment créée. startban crée une chaîne spécifique appelée ici « bannissement ». L'action par défaut de cet chaîne est de retourner au processus de traitement des paquets. Cette chaîne est ajoutée à INPUT pour traiter les paquet entrants. addban bannît l'adresse IP. Le bannissement consiste à insérer une ligne au début de la chaîne (avant celle qui contient RETURN). Pour permettre de supprimer le paquet et de la tracer, on renvoie les paquets qui arrivent là à la chaîne bannissement-drop qui effectue deux actions sur tous les paquets qui la traverse : la cible LOG permet de garder une trace dans via syslog, la cible DROP supprime le paquet.

La ligne $IPTABLES –insert $CHAIN 1 –source $1 –match comment –comment “$CHAIN” permet de compter les paquets pour le plugiciel iptables de collectd.

On charge le script et ses fonctions avec la commande source bannissement. On initialise les bannissements avec startban, on les arrête avec stopban. Pour bannir une adresse : add_ban 10.1.1.1.

Il existe d'autres possibilités, peut-être plus efficaces. Par exemple, ajouter une ligne dans le fichier /etc/hosts.deny pour l'adresse IP concernée. Si vous trouvez mieux, n'hésitez pas à commenter.

Le 02/11/2009 – Sylvain Collilieux – Ce texte est sous licence Art Libre

blog/2009/1101bannissement_d_adresses_ip.txt · Dernière modification: Le 21/01/2015 à 22:27 par sylvain