Introduction
Sur les serveurs Ubuntu, ufw (Uncomplicated Firewall) est un bon outil pour appliquer des règles de parefeu
sur les ports sans avoir à utiliser les commandes iptables
qui sont assez difficiles.
root@vpsfrsqlpac2$ ufw status verbose
To Action From -- ------ ---- 22 ALLOW IN Anywhere # SSH 8600:8800/tcp ALLOW IN 10.128.30.32 # MariaDB CS 20501:20509/tcp ALLOW IN 10.128.30.32 # PostgreSQL
Mais ce n’est pas suffisant. Pour les services SSH, on peut définir un port différent de celui par défaut (port 22),
mais malheureusement certains produits, MariaDB ColumnStore par example, utilisent ssh
dans leurs routines
d’administration sans donner la possibilité d’utiliser un autre port que son port 22 par défaut.
Par conséquent, le port 22 doit être ouvert et dans le fichier /var/log/auth.log
on note très rapidement
des tentatives de connexions provenant de machines inconnues, parfois avec des intervalles de temps très courts entre les tentatives
pour une même IP.
/var/log/auth.log
Feb 2 06:25:42 vpsfrsqlpac2 sshd[6764]: Disconnected from invalid user tester 186.4.184.218 port 42416 [preauth]
Feb 2 06:29:32 vpsfrsqlpac2 sshd[6830]: Invalid user tester from 123.108.35.186 port 41670
Feb 2 06:29:34 vpsfrsqlpac2 sshd[6830]: Failed password for invalid user tester from 123.108.35.186 port 41670 ssh2
Feb 2 06:29:34 vpsfrsqlpac2 sshd[6830]: Disconnected from invalid user tester 123.108.35.186 port 41670 [preauth]
Feb 2 06:35:50 vpsfrsqlpac2 sshd[6933]: Invalid user tester from 123.108.35.186 port 45178
Feb 2 06:35:52 vpsfrsqlpac2 sshd[6933]: Failed password for invalid user tester from 123.108.35.186 port 45178 ssh2
Fail2Ban est l’outil complémentaire à ufw afin de protéger un système Ubuntu de ces attaques.
- Son installation est simple.
- Fail2Ban gère les règles
iptables
pour interdire des adresses IP pour une période en suivant des conditions qui sont configurables.
Fail2Ban est un package Python et peut être installé dans un environnement virtuel Python, c’est la cas dans cet article.
L’installation doit être réalisée avec les privilèges root
car cet outil gère des règles iptables
.
Installation
Préparation de l’environnement virtuel Python
Python 3.8 avec virtualenv
est installé dans le répertoire /opt/python/python-3.8
.
Le fichier /opt/python/.python-3.8
source les variables d’environnement nécessaires :
/opt/python/.python-3.8
export PYHOME=/opt/python/python-3.8
export PATH=$PYHOME/bin:$PATH
export LD_LIBRARY_PATH=$PYHOME/lib:$LD_LIBRARY_PATH
export PYTHONPATH=/opt/python/packages
L’environnement virtuel Python pour fail2ban est installé dans le répertoire /opt/monitoring/fail2ban
:
root@vpsfrsqlpac2$ source /opt/python/.python-3.8
root@vpsfrsqlpac2$ virtualenv --system-site-packages /opt/monitoring/fail2ban
L’environnement est activé :
root@vpsfrsqlpac2$ source /opt/monitoring/fail2ban/bin/activate (fail2ban) root@vpsfrsqlpac2$ which python3
/opt/monitoring/fail2ban/bin/python3
Package Fail2ban
Télécharger fail2ban depuis GitHub et lancer son installation :
(fail2ban) root@vpsfrsqlpac2$ cd /opt/monitoring/setup (fail2ban) root@vpsfrsqlpac2$ wget https://github.com/fail2ban/fail2ban/archive/0.11.1.tar.gz (fail2ban) root@vpsfrsqlpac2$ tar -xvzf 0.11.1.tar.gz (fail2ban) root@vpsfrsqlpac2$ cd fail2ban-0.11.1 (fail2ban) root@vpsfrsqlpac2$ python3 setup.py install
… changing mode of /opt/monitoring/fail2ban/bin/fail2ban-testcases to 755 Please do not forget to update your configuration files. They are in "/etc/fail2ban/". You can also install systemd service-unit file from "build/fail2ban.service" resp. corresponding init script from "files/*-initd".
Le package fail2ban est installé avec succès dans l’environnement virtuel /opt/monitoring/fail2ban
.
Configuration de Fail2ban
Tous les fichiers de configuration sont installés dans le répertoire /etc/fail2ban
.
fail2ban.conf
Le fichier de configuration principal fail2ban.conf
ne contient pas beaucoup de paramètres à configurer.
Dans celui-ci, on peut personnaliser la verbosité, les répertoires et noms de fichiers pour le fichier de log, le fichier pid…
/etc/fail2ban/fail2ban.conf
[DEFAULT]
loglevel = INFO
logtarget = /var/log/fail2ban.log
socket = /var/run/fail2ban/fail2ban.sock
pidfile = /var/run/fail2ban/fail2ban.pid
dbfile = /var/lib/fail2ban/fail2ban.sqlite3
dbpurgeage = 15d
Fail2ban utilise une base sqlite3. Lors de l’installation, mettre à jour le paramètre de rétention dbpurgeage
à au moins
8 jours, ce sera déjà fait pour la configuration des attaques récidivistes plus tard.
jail.local
Les règles Fail2Ban sont configurées dans le fichier /etc/fail2ban/jail.local
à créér.
Copier le fichier /etc/fail2ban/jail.conf
vers /etc/fail2ban/jail.local
. Le fichier local évite de perdre toute
configuration lors des mises à niveau de fail2ban :
(fail2ban) root@vpsfrsqlpac2$ cp /etc/fail2ban/jail.conf /etc/fail2ban/jail.local
/etc/fail2ban/jail.local
[DEFAULT]
ignoreip = 127.0.0.1/8 10.128.31.48
# "bantime" is the number of seconds that a host is banned.
bantime = 30m
# A host is banned if it has generated "maxretry" during the last "findtime" seconds.
findtime = 10m
# "maxretry" is the number of failures before a host get banned.
maxretry = 3
- définir les IPs à ignorer dans la section
DEFAULT
, et plus particulièrement les IPs de ses propres machines. - le temps de bannissement par défaut peut être ajusté : ici il est fixé à 30 minutes au lieu des 10 minutes par défaut.
À présent les règles de bannissement pour ssh
sont activées :
/etc/fail2ban/jail.local
[sshd]
enabled = true
port = ssh
logpath = %(sshd_log)s
backend = %(sshd_backend)s
De nombreuses sections sont disponibles et prédéfinies dans le fichier jail.local
: sshd, apache, mysql…
Tous les paramètres définis dans la section DEFAULT
(bantime
, ignoreip
…) peuvent
être personnalisés dans chaque section. Il faut faire attention au paramètre ignoreip
, si des adresses IP spécifiques
sont définies dans une section, cela annule la valeur par défaut des IPs définies, il n’y a pas de fusion.
Dans le "langage fail2ban", une section dans le fichier de configuration est une "jail" (prison). La jail sshd
a été activée dans l’exemple ci-dessus.
Utilisation de fail2ban
Sauvegarde iptables
Sur Ubuntu, les tables IP iptables
ne sont pas stockées dans un fichier, mais dans le noyau.
Fail2ban va gérer iptables
, aussi une sauvegarde, au cas où, devrait être réalisée avant de démarrer fail2ban :
(fail2ban) root@vpsfrsqlpac2$ iptables-save > /etc/iptables_rules.txt
Si des comportements inattendus sont observés après l’activation de Fail2ban, la restauration d’un état stable sera plus facile :
(fail2ban) root@vpsfrsqlpac2$ iptables-restore < /etc/iptables_rules.txt
Gestion de fail2ban
Tout est prêt, pour démarrer fail2ban :
(fail2ban) root@vpsfrsqlpac2$ fail2ban-server -xf start
2020-02-07 10:08:11,078 fail2ban.server [26518]: INFO -------------------------------------------------- 2020-02-07 10:08:11,078 fail2ban.server [26518]: INFO Starting Fail2ban v0.11.1 2020-02-07 10:08:11,079 fail2ban.server [26518]: INFO Daemon started 2020-02-07 10:08:11,080 fail2ban.observer [26518]: INFO Observer start... 2020-02-07 10:08:11,137 fail2ban.database [26518]: INFO Connected to fail2ban persistent database '/var/lib/fail2ban/fail2ban.sqlite3' 2020-02-07 10:08:11,140 fail2ban.database [26518]: WARNING New database created. Version '4'
Pour arrêter, redémarrer le serveur ou pour recharger la configuration globale ou d’une jail uniquement :
(fail2ban) root@vpsfrsqlpac2$ fail2ban-client stop | restart | reload [jail]
fail2ban-client et les jails
Utiliser également fail2ban-client
pour gérer les jails : statuts, annulation d’un bannissement d’IP(s), start, stop…
Des IPs bannies apparaissent dans la jail sshd
très rapidement après son activation :
(fail2ban) root@vpsfrsqlpac2$ fail2ban-client status
Status |- Number of jail: 2 `- Jail list: recidive, sshd
(fail2ban) root@vpsfrsqlpac2$ fail2ban-client status sshd
Status for the jail: sshd |- Filter | |- Currently failed: 3 | |- Total failed: 2022 | `- File list: /var/log/auth.log `- Actions |- Currently banned: 4 |- Total banned: 466 `- Banned IP list: 209.141.57.211 218.92.0.145 …
Les paramètres de configuration des jails peuvent être listés et modifiés dynamiquement :
(fail2ban) root@vpsfrsqlpac2$ fail2ban-client get sshd bantime
600
(fail2ban) root@vpsfrsqlpac2$ fail2ban-client set sshd bantime 60m
3600
fail2ban-client set
met à jour les valeurs uniquement pour un serveur Fail2Ban en cours d’exécution,
ne pas oublier de mettre à jour le fichier de configuration en conséquence si elles doivent être persistentes.
Première commande à connaître avec Fail2ban (quand vous vous auto-bannissez 🙂) : comment supprimer le bannissement d’une IP ?
(fail2ban) root@vpsfrsqlpac2$ fail2ban-client set sshd unbanip 90.62.100.101
De très nombreuses options existent : pour l’aide, lancer fail2ban-client --help
.
fail2ban et IP Tables
Comment Fail2ban travaille avec iptables
?
Fail2ban créé pour chaque jail une chaîne utilisateur avec le nom f2b-[jail]
, f2b-sshd
dans l’exemple ci-dessus, puis une règle
est ajoutée dans cette chaîne pour le port 22 / INPUT :
(fail2ban) root@vpsfrsqlpac2$ iptables -S
-N f2b-sshd -A INPUT -p tcp -m multiport --dports 22 -j f2b-sshd
Les IPs bannies sont ajoutées dans la chaîne :
(fail2ban) root@vpsfrsqlpac2$ iptables -L f2b-sshd
Chain f2b-sshd (1 references) target prot opt source destination REJECT all -- 222.186.180.8 anywhere reject-with icmp-port-unreachable REJECT all -- 222.186.173.142 anywhere reject-with icmp-port-unreachable REJECT all -- 222.186.30.187 anywhere reject-with icmp-port-unreachable REJECT all -- 222.186.173.215 anywhere reject-with icmp-port-unreachable REJECT all -- 222.186.175.140 anywhere reject-with icmp-port-unreachable
La chaîne est retirée lors de l’arrêt du serveur Fail2ban ou de l’arrêt de la jail (fail2ban-client stop sshd
).
Comme attendu, la chaîne n’est pas supprimée quand un serveur Fail2ban est tué violemment (kill -9
).
Aucune perte lors d’un redémarrage d’un serveur Fail2ban, les chaînes iptables sont reconstruites à partir des informations stockées dans la base de données sqlite3.
(fail2ban) root@vpsfrsqlpac2$ sqlite3
sqlite> .open /var/lib/fail2ban/fail2ban.sqlite3 sqlite> .tables
bans bips fail2banDb jails logs
sqlite> select ip, jail, datetime(timeofban,'unixepochs'), bantime from bips;
222.186.173.215|sshd|2020-02-07 16:17:03|3600 222.186.30.187|sshd|2020-02-07 16:19:25|3600 222.186.173.142|sshd|2020-02-07 16:24:28|3600 …
Service fail2ban
fail2ban est installé dans un environnement virtuel Python mais cela n’empêche pas la définition d’un service pour le redémarrage automatique.
Un fichier .fail2ban
est créé pour sourcer et activer l’environnement virtuel Python.
/opt/monitoring/fail2ban/.fail2ban
export F2BDIR=/opt/monitoring/fail2ban
source /opt/python/.python-3.8
source $F2BDIR/bin/activate
Un fichier modèle pour le service est disponible dans le répertoire à partir duquel l’installation a été réalisée (build/fail2ban.service
).
Le service est personnalisé pour y intégrer l’appel du fichier .fail2ban
:
/lib/systemd/system/fail2ban.service
[Unit]
Description=Fail2Ban Service
Documentation=man:fail2ban(1)
After=network.target iptables.service firewalld.service ip6tables.service ipset.service nftables.service
PartOf=iptables.service firewalld.service ip6tables.service ipset.service nftables.service
[Service]
Type=simple
ExecStartPre=/bin/mkdir -p /run/fail2ban
ExecStart=/bin/bash -c "source /opt/monitoring/fail2ban/.fail2ban; /opt/monitoring/fail2ban/bin/fail2ban-server -xf start"
ExecStop=/bin/bash -c "source /opt/monitoring/fail2ban/.fail2ban; /opt/monitoring/fail2ban/bin/fail2ban-client stop"
ExecReload=/bin/bash -c "source /opt/monitoring/fail2ban/.fail2ban; /opt/monitoring/fail2ban/bin/fail2ban-client reload"
PIDFile=/run/fail2ban/fail2ban.pid
Restart=on-failure
RestartPreventExitStatus=0 255
[Install]
WantedBy=multi-user.target
Le service est ensuite activé :
root@vpsfrsqlpac2$ cd /etc/systemd/system root@vpsfrsqlpac2$ ln -fs /lib/systemd/system/fail2ban.service fail2ban.service root@vpsfrsqlpac2$ systemctl enable fail2ban
Created symlink /etc/systemd/system/multi-user.target.wants/fail2ban.service → /lib/systemd/system/fail2ban.service.
root@vpsfrsqlpac2$ systemctl start fail2ban root@vpsfrsqlpac2$ systemctl status fail2ban
● fail2ban.service - Fail2Ban Service Loaded: loaded (/lib/systemd/system/fail2ban.service; enabled; vendor preset: enabled) Active: active (running) since Fri 2020-02-09 17:23:29 CET; 23h ago Docs: man:fail2ban(1) Process: 4240 ExecStop=/bin/bash -c source /opt/monitoring/fail2ban/.fail2ban; /opt/monitoring/fail2ban/bin/fail2ban-clien Process: 4250 ExecStartPre=/bin/mkdir -p /run/fail2ban (code=exited, status=0/SUCCESS) Main PID: 4259 (bash) Tasks: 8 (limit: 4587) CGroup: /system.slice/fail2ban.service ├─4259 /bin/bash -c source /opt/monitoring/fail2ban/.fail2ban; /opt/monitoring/fail2ban/bin/fail2ban-server -xf s └─4264 /opt/monitoring/fail2ban/bin/python3 /opt/monitoring/fail2ban/bin/fail2ban-server -xf start
Jail pour les récidivistes
Une jail très intéressante à activer : la jail recidive
/etc/fail2ban/jail.local
[recidive]
enabled = true
logpath = /var/log/fail2ban.log
banaction = %(banaction_allports)s
bantime = 1w
findtime = 1d
Lors de l’activation de cette jail, Fail2ban scanne son propre fichier de log et y recherche les IPs récurrentes qui ont été bannies par les règles définies dans les autres jails.
Les IPs sont alors bannies pour une période plus longue (ici 1 semaine) et ceci pour TOUS les ports d’entrée.
C’est pourquoi le paramètre de rétention dbpurgeage
a été fixé à 15 jours, sinon la jail recidive
ne fonctionnerait pas très bien.
root@vpsfrsqlpac2$ iptables -S
… -N f2b-recidive -A INPUT -p tcp -j f2b-recidive … -A f2b-recidive -s 222.186.180.17/32 -j REJECT --reject-with icmp-port-unreachable -A f2b-recidive -s 222.186.175.167/32 -j REJECT --reject-with icmp-port-unreachable …
Conclusion
D’autres jails semblent très intéressantes, notamment les jails pour les tentatives de floods et injections à travers Apache / PHP, mais cela doît être étudié plus en profondeur.
Les premières jails ouvertes (sshd
, recidive
) sont largement suffisantes pour le moment pour protéger au mieux le
port sshd d’un serveur Linux Ubuntu localisé dans le réseau internet.
À propos des performances : fail2ban configuré avec les jails sshd
et recidive
a besoin d’environ 450 - 650 Mb.
Son utilisation CPU est très faible (moins de 0,2% en moyenne sur une machine 1 core 2 GHz). Le nombre de règles créé
dans iptables
ne devrait pas dégrader les performances.