Pour bloquer des tentatives de connexion ssh, c’est assez simple et ne demande pas d’utiliser iptables. On peut utiliser iptables (j’ai une version iptables en stock) mais ce n’est pas indispensable. On utilisera ici plutôt le tcp wrapper tcpd et ses fichiers /etc/hosts.deny et hosts.allow. Le script analysera la fréquence des messages d’échec de connexion que sshd envoie dans /var/log/auth.log dans une configuration standard. Si le nombre de ces échecs dépasse un certain seuil, l’ip est bloquée.
Mais attention! Si vous installez ce script sur un serveur distant gardez toujours une connexion ouverte et faites vos essais sur une autre session ssh sinon vous risquez de vous isoler complètement de votre machine distante. Si, si ça arrive!
Vous êtes prévenus!
[ul]
[li]Pour éviter cette mésaventure commencez par mettre une ip de confiance dans /etc/hosts.allow comme ceci:
sshd: 123.123.123.123
[/li]
[li]Ensuite ajoutez cette ligne dans /etc/hosts.deny (ou tout autre chemin/fichier de votre choix à préciser dans le script: variable $DENY_FILE)
sshd: /tmp/ipban-ssh
[/li]
[li]Vous pouvez également vous créer un fichier de blacklist perso. Une ip par ligne.
[/li]
[li]Si vous voulez débloquer une ip de confiance qui se retrouverait bloquée par accident, il ne suffit pas de la supprimer du fichier ipban-ssh car, si les conditions de bannissement existent toujours, elle se rajoutera automatiquement à la prochaine exécution du script. Il faut plutôt l’ajouter dans /etc/hosts.allow. Principe de la whitelist.
[/li]
[li]Utilisation, par exemple pour bannir une ip qui aurait fait plus de 20 tentatives par minute
$ ipban4ssh -m 20
[/li]
[li]Ou plus de 50 tentatives par heure
$ ipban4ssh -h 50
[/li]
[li]exécutez ce script par cron à la fréquence de votre choix.
[/li]
[li]Ce script ne marchera que pour le format de log sshd standard Debian comme par exemple celui-ci:
May 29 15:03:22 ursule sshd[2590]: Invalid user jjj from 192.168.0.158
May 29 15:03:22 ursule sshd[2590]: Failed none for invalid user jjj from 192.168.0.150 port 50725 ssh2
May 29 15:03:23 ursule sshd[2590]: Failed password for invalid user jjj from 192.168.0.150 port 50725 ssh2
May 29 15:03:24 ursule sshd[2592]: Invalid user jjj from 192.168.0.150
Si ce n’est pas le cas il faudra modifier le script (une seule ligne à changer) ou votre format de log.[/li][/ul]
[code]#!/bin/sh
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
dans /etc/hosts.deny ajouter
sshd: /tmp/ipban-ssh # voir fichier $DENY_FILE
IMPORTANT: adresse ip de secours
dans /etc/hosts.allow ajouter
sshd: <ip de secours toujours autorisée>
test des options
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
commandes
awk=’/usr/bin/awk’
awk=’/usr/bin/mawk’
Paramètres config
LOG_FILE=’/var/log/auth.log’
DENY_FILE=’/tmp/ipban-ssh’
BLACKLIST_FILE=‘blacklistPerso’
Initialisation variables (mise au format syslog RFC3164 de la date du jour)
export LC_ALL=C
DTE_DAY=$(date +’%d’)
DTE_TODAY=$(printf “%s %2s” $(date +’%b’) ${DTE_DAY#0})
[ $1 = “-m” ] && SUBSTR=5 || SUBSTR=2
calcul de la fréquence de connexions par minute et stockage dans le fichier $DENY_FILE
printf “# fichier des ip ayant tenté plus de %s connexions ssh - %s\n” $2 “$(date)” > “$DENY_FILE”
$awk ‘/^’"$DTE_TODAY"’.+sshd.+(Invalid user|Failed password)/ {
# extraction de ip
match($0, /from [0-9.]+ ?/)
split(substr($0, RSTART), arr, / /)
ip=arr[2]
# tableau associatif indice: [M D HH:MM ip] ou [M D HH ip]
tab[$1 $2 substr($3, 1, ‘$SUBSTR’) ip]++
if (tab[$1 $2 substr($3, 1, ‘$SUBSTR’) ip] >= ‘$2’){
print ip
}
}
’ “$LOG_FILE” | sort -u >> “$DENY_FILE”
ajout blacklist perso
[ -f “$BLACKLIST_FILE” ] && cat “$BLACKLIST_FILE” >> “$DENY_FILE”
affichage de contrôle
cat “$DENY_FILE”
exit 0
[/code]
edit :
03-06: Adaptation au format date de syslog (rfc 3164) et modification du filtre awk pour tenir compte des tentatives sur un nom d’utilisateur existant.