Comment faire tourner fail2ban dans un conteneur Docker avec Shorewall, Nginx, SSHD, OpenVPN...

De BeTa wiki
Aller à la navigationAller à la recherche

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.