|
|
|
|
<!-- 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"
|
|
|
|
|
```
|