Sécuriser son serveur avec iptables et fail2ban


Debian, Linux, VPS / mercredi, septembre 28th, 2016

Le but de ce tuto après la mise en place de notre site web c’est de le sécuriser grâce à iptables et fail2ban.

Pour ce qui ne connaissent pas fail2ban c’est un service qui va aller lire les logs d’autres services comme celui d’apache que nous voulons sécuriser ou de ssh, FTP et bien d’autre à la recherche de tentative d’authentification infructueuses répétée. Une fois que fail2ban va détecter une tentative d’intrusion, il va ajouter une règle dans iptables pour bannir l’adresse IP de la source pendant une période définie.

1. Iptables

Nous allons commencer par faire nos mises à jour

# apt-get update 
# apt-get  upgrade

Le service iptables est installé par défaut sur toutes les machines Debian mais pour comprendre son fonctionnement et ces règles je vous renvoie au lien suivant https://doc.ubuntu-fr.org/iptables

Je vous présenter un petit script qui va vous permettre déjà d’ouvrir le trafic de votre serveur uniquement pour les services que vous avez installés.

On va créer notre fichier dans le répertoire /etc/init.d/   ou l’on retrouve tous les scripts lancés au démarrage de la machine

#  vi /etc/init.d/firewall.sh

vous pouvez personnaliser le script en fonction de vos services, numéros de port etc…

Voici un script que je vous propose avec les principaux services sur les serveurs

#!/bin/sh # 
Vider les tables actuelles
iptables -t filter -F

# Vider les règles personnelles
iptables -t filter –X

# Interdire toute connexion entrante et sortante
iptables -t filter -P INPUT DROP
iptables -t filter -P FORWARD DROP
iptables -t filter -P OUTPUT DROP

# Ne pas casser les connexions etablies
iptables -A INPUT -m state --state RELATED,ESTABLISHED -j ACCEPT
iptables -A OUTPUT -m state --state RELATED,ESTABLISHED -j ACCEPT

# Autoriser le loopback
iptables -t filter -A INPUT -i lo -j ACCEPT
iptables -t filter -A OUTPUT -o lo -j ACCEPT

# ICMP (ping)
iptables -t filter -A INPUT -p icmp -j ACCEPT
iptables -t filter -A OUTPUT -p icmp -j ACCEPT
# FTP 
iptables -t filter -A INPUT -p tcp --dport 21 -j ACCEPT
iptables -t filter -A OUTPUT -p tcp --dport 21 -j ACCEPT

# SSH 
iptables -t filter -A INPUT -p tcp --dport 5285 -j ACCEPT
iptables -t filter -A OUTPUT -p tcp --dport 5285-j ACCEPT

# DNS (bind)
iptables -t filter -A OUTPUT -p tcp --dport 53 -j ACCEPT
iptables -t filter -A OUTPUT -p udp --dport 53 -j ACCEPT
iptables -t filter -A INPUT -p tcp --dport 53 -j ACCEPT
iptables -t filter -A INPUT -p udp --dport 53 -j ACCEPT

# APACHE : HTTP + HTTPS
iptables -t filter -A OUTPUT -p tcp --dport 80 -j ACCEPT
iptables -t filter -A OUTPUT -p tcp --dport 443 -j ACCEPT
iptables -t filter -A INPUT -p tcp --dport 80 -j ACCEPT
iptables -t filter -A INPUT -p tcp --dport 443 -j ACCEPT

# WEBMIN
iptables -t filter -A INPUT -p tcp --dport 42351 -m state --state NEW,ESTABLISHED -j ACCEPT
iptables -t filter -A OUTPUT -p tcp --dport 42351 -m state --state ESTABLISHED -j ACCEPT

Après avoir enregistré, il faut rendre votre fichier exécutable

chmod +x /etc/init.d/firewall.sh

2. Fail2Ban

Nous installons le paquet fail2ban

apt-get install –y fail2ban

Copier le fichier de configuration dans le but de créer notre propre fichier de configuration de fail2ban

cp /etc/fail2ban/jail.conf /etc/fail2ban/jail.local

Pour comprendre l’ensemble des possibilités qu’a fail2ban je vous conseille de lire cette page avant de modifier le fichier de configuration https://doc.ubuntu-fr.org/fail2ban

Maintenant que nous avons consulté la doc sur fail2ban nous pouvons modifier le fichier de configuration

Vi /etc/fail2ban/jail.local

La première ligne à modifier est la suivante

ignoreip = 127.0.0.1/8

Il faut ajouter votre adresse IP pour éviter d’être banni par votre propre règle (retour à l’envoyeur). Le séparateur c’est l’espace voici un exemple

ignoreip = 127.0.0.1/8  8.8.8.8

Et ensuite il faut modifier le Bantime qui est le temps en seconde qu’une adresse ip va être banni

bantime = 600

Le bantime est réglé par défaut à 10 min mais moi je vais le mettre à une semaine

bantime =604800

Le second élément que vous devez configurer en même temps que le bantime c’est le findtime. Je vais vous avouer que son explication sur le lien précédent n’est pas très clair… Il est écrit sur le site « Par rapport au blocage par défaut (600s), un blocage de 1h est bien plus réaliste (3600s), ou même 1 journée (86400s), ou pourquoi pas 1 semaine (604800s). Mais attention que changer le ‘bantime’ n’agit pas sur le ‘findtime’ qu’il faut également ajuster, car sinon le ‘findtime’ par défaut (10mn) est utilisé, ce qui permet à nouveau l’attaque expliqué au point précédent. L’inconvénient d’un (très ?) grand ‘findtime’ est qu’il pousse fail2ban à analyser de plus longs fichiers de log, et que ça peut être pénalisant du point de vue des performances, alors c’est à vous de voir. La solution est alors de choisir un grand ‘findtime’ et un très grand ‘bantime’ : 3600 et 86400, ou encore 86400 et 604800»

Je vais avouer qu’il m’a fallu quelques recherches pour comprendre. C’est  la durée pendant laquelle une adresse ip va être surveillée dans le but d’être banni si elle dépasse le nombre de tentative. Par exemple si votre findtime est à 10 min et que le nombre de tentative maximum est de 3, une adresse ip vous attaquer 2 fois et reviens 11 minutes après va pouvoir vous attaquer encore 2 fois et ainsi de suite alors que si elle vous attaque plus de 3 fois dans les 10 min elle sera bloquée.

Donc pour revenir à notre fichier de configuration je vais mettre le findtime à une journée

findtime = 86400

Le nombre d’essais je le met à 2 mais par défaut il est à 3

maxretry = 2

Maintenant vous pouvez parcourir le reste du fichier avec les différents filtres pour les services et activer ceux dont vous avez besoin. Par exemple pour le service Apache il est désactivé par défaut

f1

 

Je vais juste passer le paramètre enabled de false à true

f2

 

Il ne faut pas oublier pour ceux comme moi qui ont changé le port par défaut de leurs services de le spécifier à fail2ban sinon ça ne risque ma de bien fonctionner. Par exemple ici j’ai le filtre par défaut du service ssh

f3

Le port par défaut est égal ssh donc le port 22. Si vous avez modifié le port du service ssh par le port 5285 par exemple il faut changer le port dans le filtre comme dans l’exemple suivant

f4

 

Après avoir activé tous mes services je vais enregistrer le fichier et redémarrer le service fail2ban pour que mes changements soient pris en compte

fail2ban-client reload

On va pouvoir surveiller ce qui se passe coté serveur avec fail2ban pour un service grâce a la commande

fail2ban-client status apache

Si vous avez des problèmes pour redémarrera fail2ban il faut penser à activer vos paramètres filtre par filtre afin de déterminer d’où vient le problème.

Je vais ajouter un petit bonus pour ceux comme moi qui utilisent des sites sous wordpress. La configuration actuelle de fail2ban ne nous permet pas de bannir les adresses ip qui attaques votre site sous wordpress.

Il faut installer une nouvelle extension sur votre site WP fail2ban. Une fois le plugin installé vous pouvez modifier le fichier jail.local

Vi /etc/fail2ban/jail.local

Ajouter deux nouvelles règles

[wordpress-hard]
enabled = true
filter = wordpress-hard
logpath = /var/log/auth.log
maxretry = 1
port = http,https

[wordpress-soft]
enabled = true
filter = wordpress-soft
logpath = /var/log/auth.log
maxretry = 3
port = http,https

copier les fichiers wordpress-hard.conf et wordpress-soft.conf dans le répertoire du plugin wp fail2ban de votre site vers le répertoire fail2ban/filters.d

cp /var/www/html/wp-content/plugins/wp-fail2ban/filters.d/wordpress-soft.conf /etc/fail2ban/filter.d/
/var/www/html/wp-content/plugins/wp-fail2ban/filters.d/wordpress-hard.conf /etc/fail2ban/filter.d/

Redémarrer

fail2ban-client reload

Si vous avez déjà un journal peuplé d’informations, vous pouvez exécuter la commande suivante pour voir si la règle fonctionne

 fail2ban-regex /var/log/auth.log /etc/fail2ban/filter.d/wordpress-hard.conf

Le resultat de la commande

On constate que la règle match 272 fois avec le fichier de log donc notre règle est fonctionnelle.