You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
blog/posts/2017/2017-10-14-attrapons-les-vi...

99 lines
3.5 KiB
Markdown

This file contains invisible Unicode characters!

This file contains invisible Unicode characters that may be processed differently from what appears below. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to reveal hidden characters.

<!-- title: Attrapons les vilains -->
<!-- category: Hébergement BSD -->
A la fin de [mon article sur le blocage des attaques de brute
force](/2017/securite-des-donnees-focus-sur-nextcloud), j'étais resté sur l'envoi quotidien d'un
e-mail avec le log des attaques de la journée, histoire d'avoir une idée de ce
qui s'est passé.<!-- more --> Pour rappel, mon serveur tourne sous OpenBSD et l'outil de
protection contre les attaques est Vilain, un équivalent de Fail2ban sous Linux.
Le log de la journée est fastidieux à lire et j'ai eu envie de construire un
rapport avec les informations suivantes :
- liste des adresses IP bloquées
- répartition horaire des attaques
- top des adresses IP les plus agressives
Après un échange avec [Thuban](http://yeuxdelibad.net), le créateur de Vilain,
nous convenons que Vilain doit rester
[KISS](https://fr.wikipedia.org/wiki/Principe_KISS), qu'il n'est pas souhaitable
de compliquer son code pour générer un rapport. Il est préférable de réaliser le
travail en externe en analysant les logs. C'est ainsi que j'ai écrit
**vilainreport** (une centaine de lignes en Python), qu'on peut lancer
quotidiennement avec une tâche CRON pour recevoir le rapport du jour :
cat /var/log/vilain | vilainreport | mail -s "Vilain rapport du jour" admin
**vilainreport** est intégré au [dépôt de Vilain sur Framagit](https://framagit.org/Thuban/vilain).
Voici un exemple de rapport généré par *vilainreport*:
### Date 2017-10-12
00:17:00 blacklist IP 156.196.136.52 (ssh)
01:26:17 blacklist IP 115.249.139.206 (ssh)
02:31:08 blacklist IP 218.62.64.179 (ssh)
02:35:16 blacklist IP 91.223.167.69 (ssh)
02:46:54 blacklist IP 27.102.203.180 (ssh)
...
Probe 'ssh' : 137 attacks
### Attacks per probe
Probe 'ssh': 137 attacks
### Hourly repartition
Hour 00 - 01: 1
Hour 01 - 02: 1
Hour 02 - 03: 4
Hour 03 - 04: 4
...
### Top attackers
IP 195.184.191.147 : 6
IP 81.4.110.104 : 5
IP 90.63.248.112 : 5
IP 176.31.126.176 : 5
...
Ma configuration personnelle de Vilain est la suivante : je bannis pendant 1
heure toute adresse après sa deuxième tentative erronée de connexion à un de mes
services. Donc un *Top attacker* qui a été banni 6 fois dans la même journée n'a
pas fait d'erreur de connexion. Il a vraiment l'intention de s'introduire dans
mon serveur. Je pourrais durcir ma configuration pour bannir beaucoup plus d'une
heure mais ça ne m'arrange pas car je partage des documents avec des gens qui
peuvent se tromper une fois ou deux en saisissant leurs identifiants Nextcloud.
J'ai donc décidé de mettre en place une sanction plus dure pour les récidivistes :
les jeter dans un puits sans fond, concrètement, une blackliste définitive au
niveau du pare-feu OpenBSD.
![Prison de Bane](/images/2017/darkknight-prison.jpg)
J'ai appliqué une logique similaire à *vilainreport*. Je réinjecte le rapport
dans un petit shell script **supervilain** qui identifie les récidivistes et les
jette dans le puits, où il resteront... jusqu'au prochain redémarrage du serveur.
Voici le script en Korn Shell :
```shell
#!/bin/ksh
if [ $# != 1 ]; then
echo "Usage: $0 logfile"
exit 1
fi
file=${1--}
while read line
do
line=`echo $line | tr -d '\r'`
if [[ $line = IP* ]]; then
ipend="${line##+(IP )}"
ip="${ipend%%+( ):*}"
count="${ipend##*\: }"
if [ "$count" -gt "2" ]; then
echo "Ban supervilain ${ip} (${count})"
`pfctl -t supervilain -T add ${ip}`
fi
fi
done <"$file"
```