Suite à deux fils concernant des attaques de force brute sur le port ssh, j’ai fait un petit script qui analyse la fréquence des tentatives de connexions infructueuses qui sont journalisées dans /var/log/auth.log
Instructions:
[ul]
[li]dans le fichier /etc/hosts.deny, ajouter une ligne:
[li]mettre le script ci-dessous en cron: toutes les 5 minutes par exemple.[/li]
[li]le UID du script doit avoir les droits d’écriture sur le fichier /home/user/mon-fichier-ip-ban bien sûr.[/li]
[li]C’est tout. Le deamon tcpd, un wrapper de connexions tcp se charge du reste.[/li][/ul]
Contrairement à iptables, le deamon tcpd ne coupe pas une connexion ssh déjà établie.Il n’y a donc pas de danger de faire des bêtises du genre couper toute connexion ssh sur un serveur distant tant qu’on laisse une session ssh active pour réparer ses bêtises.
[code]#!/bin/bash
Utilisation:
$ ipban -m 15
extraction des IP ayant tenté plus de 15 connexions par minute
$ ipban -h 5
extraction des IP ayant tenté plus de 5 connexions par heure
Instructions:
dans /etc/hosts.deny ajouter
sshd: /tmp/ipban-ssh # voir fichier $DENY_FILE
test des paramètres positionnels
if [ $# -lt 2 ]; then echo “Usage: ipban -m 15 ou ipban -h 5”; exit 1; fi
if [ $1 != “-m” ] && [ $1 != “-h” ];then echo “Usage: ipban -m 15 ou ipban -h 5”; exit 1; fi
if [ $2 -le 0 ]; then echo “Vous devez donner un seuil de tentatives par min. ou par heure.”; exit 1; fi
Paramètres config
LOG_FILE=’/var/log/auth.log’ # emplacement fichier auth.log
DENY_FILE=’/tmp/ipban-ssh’ # emplacement fichier de ip bannies
Initialisation variables
DTE_FILTER=$(LC_ALL=C date +’%b %d’)
[ $1 = “-m” ] && SUBSTR=5 || SUBSTR=2
echo “# fichier des ip ayant tenté plus de $2 connections ssh - $(date)” > $DENY_FILE
calcul de la fréquence de connexions par minute
et stockage dans le fichier $DENY_FILE
awk "/^$DTE_FILTER.+sshd.+Invalid user/ "’{
# tableau associatif indice: [M D HH:MM ip] ou [M D HH ip]
tab[$1 $2 substr($3, 1, ‘$SUBSTR’) $10]++
if (tab[$1 $2 substr($3, 1, ‘$SUBSTR’) $10] >= ‘$2’){
print $10
}
}
’ $LOG_FILE | sort -u >> $DENY_FILE
cat $DENY_FILE
exit 0
[/code]
Si on veut, en plus, bloquer les IP dans iptables, il suffit de récupérer le fichier $DENY_FILE et, en bouclant dessus, d’ajouter des règles dans netfilter. Le problème est qu’il faudra bien un jour nettoyer ces règles qui s’accumulent toutes les x minutes, à chaque tour de cron du script. Dans le cas contraire, une IP bannie peut un jour vous être attribuée si vous êtes en IP dynamique. Je réfléchis à une méthode propre. Si quelqu’un a une idée…
Le script ci -dessus est basé sur un format de log standard qui contient des lignes telles comme:
Apr 26 20:18:15 monserveur sshd[5159]: Invalid user wwwrun from 210.243.170.181
Apr 28 02:58:04 monserveur sshd[20403]: Invalid user xfs from 72.93.200.84
Apr 26 20:22:06 monserveur sshd[5341]: Invalid user xgridagent from 210.243.170.181
Apr 26 20:22:16 monserveur sshd[5349]: Invalid user xgridcontroller from 210.243.170.181
Apr 28 03:02:39 monserveur sshd[20691]: Invalid user xxx from 72.93.200.84
Apr 28 03:03:22 monserveur sshd[20735]: Invalid user year from 72.93.200.84
Apr 28 03:02:18 monserveur sshd[20669]: Invalid user yellow from 72.93.200.84
Apr 28 14:17:14 monserveur sshd[6611]: Invalid user za from 88.191.46.60
Apr 26 16:00:10 monserveur sshd[30986]: Invalid user zachary from 89.110.150.203
Apr 28 02:58:10 monserveur sshd[20409]: Invalid user zephyr from 72.93.200.84
Apr 28 14:16:32 monserveur sshd[6556]: Invalid user Zmeu from 88.191.46.60
Apr 26 15:56:53 monserveur sshd[30750]: Invalid user zoe from 89.110.150.203
Apr 26 20:23:43 monserveur sshd[5419]: Invalid user zzz from 210.243.170.181
Si votre format diffère il faudra adapter les instructions awk.
Edit:
- Optimisation
- corrections diverses