Comment faire tourner fail2ban dans un conteneur Docker avec Shorewall, Nginx, SSHD, OpenVPN...
L'objectif visé ici est de faire tourner fail2ban dans un conteneur Docker.
Le défi est donc de donner à fail2ban les données (logs) dont il a besoin ET de le faire agir sur les bonnes règles iptables de l'hôte, alors qu'elles sont déjà déployées par Shorewall par ailleurs.
Initialiser fail2ban
Nous avons choisi d'utiliser l'image linuxserver/fail2ban.
Dans un premier temps, créer un conteneur "à vide" pour initialiser vos fichiers :
$ docker run -d --rm --name=fail2ban -e PUID=1000 -e PGID=1000
Là vous décidez d'un espace de stockage persistant pour vos fichiers, par exemple /data/fail2ban et vous récupérer les fichiers idoines du conteneur :
$ sudo docker cp -a fail2ban:/config /data/fail2ban
Maintenant vous pouvez arrêter (et détruire) votre premier conteneur :
$ docker stop fail2ban
Vous pouvez ensuite passer au paramétrage de fail2ban
Paramétrer fail2ban
Voici la configuration de base de fail2ban, à mettre dans le fichier /data/fail2ban/fail2ban/jail.local :
[DEFAULT] action = iptables-multiport[name="%(__name__)s", port="http,https", protocol="tcp", chain="DOCKER-USER"] [nginx-418] enabled = true filter = nginx-418 logpath = /remotelogs/nginx/access.log maxretry = 10 findtime = 60 bantime = 600 [nginx-bad-request] enabled = true filter = nginx-bad-request logpath = /remotelogs/nginx/access.log maxretry = 10 findtime = 60 bantime = 600 [nginx-botsearch] enabled = true filter = nginx-botsearch logpath = /remotelogs/nginx/access.log maxretry = 10 findtime = 60 bantime = 600 [nginx-deny] enabled = true filter = nginx-deny logpath = /remotelogs/nginx/access.log maxretry = 10 findtime = 60 bantime = 600 [nginx-forbidden] enabled = true filter = nginx-forbidden logpath = /remotelogs/nginx/access.log maxretry = 10 findtime = 60 bantime = 600 [nginx-http-auth] enabled = true filter = nginx-http-auth logpath = /remotelogs/nginx/access.log maxretry = 10 findtime = 60 bantime = 600 [nginx-limit-req] enabled = true filter = nginx-limit-req logpath = /remotelogs/nginx/access.log maxretry = 10 findtime = 60 bantime = 600 [nginx-unauthorized] enabled = true filter = nginx-unauthorized logpath = /remotelogs/nginx/access.log maxretry = 10 findtime = 60 bantime = 600 [sshd
Si vous le souhaitez, voici deux règles utiles que j'aime bien ajouter :
local.jail
[curl-abuse] enabled = true filter = curl-abuse logpath = /remotelogs/nginx/access.log maxretry = 3 findtime = 60 bantime = 600 [nginx-404] enabled = true filter = nginx-404 logpath = /remotelogs/nginx/access.log maxretry = 10 findtime = 60 bantime = 600
filter.d/curl-abuse.conf
[Definition] failregex = ^<HOST> - .* ".*" .* "curl.*" ignoreregex =
filter.d/nginx-404.conf
# Fail2ban filter for Nginx 404 requests # Blocks IPs making too many requests for non-existent pages [Definition] # failregex matches a 404 HTTP status code in the Nginx access log failregex = ^<HOST> -.*"(GET|POST|HEAD).*HTTP.*" 404 ignoreregex =
TODO: rajouter la doc pour SSH et OpenVPN
Lancer le conteneur Docker fail2ban
Nous allons utiliser l'image Docker linuxserver/fail2ban et le script suivant :
#!/bin/bash docker pull lscr.io/linuxserver/fail2ban:latest docker run -d --rm \ --name=fail2ban \ --network host \ --cap-add=NET_ADMIN \ --cap-add=NET_RAW \ -e PUID=1000 \ -e PGID=1000 \ -e TZ=Etc/UTC \ -v $NGINX_LOGS:/remotelogs/nginx:ro \ -v $SYSLOG_LOGS:/remotelogs/syslog:ro \ -v /data/fail2ban:/config/ \ lscr.io/linuxserver/fail2ban:latest
Nous noterons deux variable $*_LOGS qui correspondent au chemin de stockage des logs de Nginx et des logs généraux (syslog) sur l'hôte. Vous pouvez les remplacer par leurs valeurs en dur ou renseigner des variables d'environnement. Syslog sera utilisé (au moins) pour SSHD et OpenVPN.
Il ne vous reste qu'à exécuter votre script pour démarrer votre conteneur Docker et votre fail2ban sera opérationnel.
Et voilà
En cas de pépin avec vos filtres
Si jamais vos essais vous mettent en difficulté, en particulier si des adresses IP se retrouvent en jail alors que fail2ban est inactif, voici une suite de commandes à lancer sur votre hôte qui pourront aider :
$ sudo shorewall clear && sudo shorewall check && sudo shorewall stop && sudo shorewall start
Ensuite vous pourrez relancer votre conteneur fail2ban et les jails seront réellement remises à zéro.