Mittlerweile sind wir schon beim fünften Teil meines Dockertutorials angekommen. Sofern ihr quasi von null startet und ein ähnliches Projekt (Nextcloud, Mariadb, ufw, Fail2ban, NPM etc.) umsetzen wollt, empfehle ich hier zu beginnen.
Ich gehe in diesem Teil davon aus, dass bei euch Docker, UFW – mit Adaptierung für Docker, Portainer, Nextcloud, Mariadb und der Nginx-Proxymanager laufen. Thema dieses Parts wird die Inbetriebnahme von Fail2Ban sein. Fail2Ban überwacht Logdateien des Systems auf gewisse „Muster“ = Fehler und sperrt zb. IP-Adressen die zu oft fehlerhafte Authentifizierungen durchführen. Um die Filterung durchzuführen, werden Filter (=via reguläre Ausdrücke, regexp) genutzt. Ich bin, was die Erstellung eigener regulärer Ausdrücke angeht nicht gut und meistens auf „das Internet“ angewiesen (nur so nebenbei angemerkt).
Fail2Ban wird in einem Docker Container laufen und sowohl den Host, als auch die Container schützen. Wichtig ist, dass sämtliche Logverzeichnisse (Docker und Host) im Fail2Ban-Dockercontainer „read-only“ (nur lesen) eingebunden werden müssen, da Fail2Ban sonst ja keinen Zugriff auf die Logs hätte und seine Arbeit nicht verrichten könnte.
Logverzeichnisse
Ich greife hier etwas vor, obwohl wir den Container für Fail2Ban noch nicht ausgerollt haben. Es ist wichtig, dass man folgenden Zusammenhang versteht.
- Die Logverzeichnisse, der zu überwachenden Dienste, werden als sog. „Bindmounts“ – nur lesend in den Fail2Ban Container eingebunden.
- Die Einbindung im Fail2Ban-Container erfolgt im Verzeichnis /remotelogs/<name des Containers oder Dienstes>
- Es sollen der Nginx-Proxy-Manager, Nextlcoud und der SSH-Zugang des Hosts überwacht werden.
- Bei mir werden alle Dockervolumes nach /var/lib/docker/volumes/<Name des Volumes> gemountet.
Das sieht dann bzgl. Volumes bei mir zb so aus (in Portainer – Container Fail2Ban):
Aufschlüsselung der (Logging)Verzeichnisse
- SSH loggt am Host in das Verzeichnis /var/log
- Nextcloud loggt (in meinem Fall) nach /var/lib/docker/volumes/Nextcloud_data/_data/data
- NPM nach /var/lib/docker/volumes/nginxpm_data/_data/logs
- das /config Verzeichnis hat mit dem Logging selbst nichts zu tun, sondern enthält die Konfiguration von Fail2ban
Ausrollung von linuxserver/fail2ban
Wie sicher schon gewohnt, wird der Container von Fail2Ban via Portainer ausgerollt. Der Name des Image ist linuxserver/fail2ban.
Volumes
Es muss nur ein Volume für die Konfiguration von Fail2Ban erzeugt werden. Ich nenne es fail2banconfig.
Abgesehen von der Zuordnung des Volumes für die Fail2Ban-Konfiguration, ges es bei der Zuordnung der weiteren Volumes, um das jeweilige Loggingverzeichnis der diversen Dienste (am Host). Wenn ihr euch 1:1 an die Anleitung hier gehalten habt, sollte das so ausehen. (Kann aber variieren, wenn ihr andere Bezeichnungen für die Volumes gewählt habt!) Achtet auch darauf, dass die Logs via „BIND“ eingebunden werden!
Netzwerk, Ports
Wir benötigen für Fail2Ban weder eine IP-Adresse noch irgendwelche Ports.
Command & Logging
- Interactive & TTY
Environment
- PUID 1000 (die ID eures Standardusers, der ganz am Anfang angelegt worden ist. Seht ihr wenn ihr in /etc/passwd des Hosts reinschaut)
- PGID 1000 (Gruppe des Standardusers. Seht ihr auch, wenn ihr in /etc/passwd des Hosts reinschaut)
- TZ Europe/Berlin
- SSMTP_HOST (Hostname eures SMTP-Servers) -> OPTIONAL: Nur wenn ihr Mailbenachrichtigungen erhalten wollt!
- SSMTP_PORT (normalerweise 587)
- SSMTP_HOSTNAME – Der Hostname eures Dockerhosts (ich hab hier den FQDN meines Dockerhosts eingetragen)
- SSMTP_USER (Der Benutzer zur Benutzerauthentifizierung am Mailserver)
- SSMTP_PASSWORD (Das Passwort, des Benutzers am Mailserver)
- SSMTP_TLS (Normalerweise auf YES zu setzen)
- SSMTP_STARTTLS (Normalerwese auf YES zu setzen)
Restart Policy
- Always
Capabilities
- Hier muss zusätzlich „NET_ADMIN“ und „NET_RAW“ aktiviert werden.
Ausrollen
- Nun kann der Container ausgerollt werden „Deploy the Container“.
Anpassung der Konfiguration von fail2ban
Fail2Ban läuft jetzt zwar, jedoch ohne Konfiguration der sog. „Jails“. In den Jails, werden Dienste definiert, die überwacht werden sollen. Ebenso muss eine „Action“ (also Aktion) definiert werden, um Festzulegen, wie denn mit „bösen“ Anfragen umgegangen werden soll.
Die Konfiguration erledigen wir via SSH am HOST (im Konfigurationsverzeichnis von Fail2Ban).
/var/lib/docker/volumes/fail2banconfig/_data/fail2ban
WICHTIG: Alle *.conf Dateien werden bei einem Restart des Containers überschrieben. Deshalb ist für jede Adaptierung einer .conf-Datei eine .local Datei zu erstellen.
Am Besten ist es, neue Dateien mit der „Endung“ .local zu erstellen, oder bestehende Dateien zu kopieren, wenn man den Inhalt benötigt.
fail2ban.conf -> fail2ban.local
An der.conf-Datei wird KEINE ÄNDERUNG durchgeführt.
Wir kopieren die Datei (vorbeugend) und erstellen so eine .local Datei:
cp fail2ban.conf fail2ban.local
jail.conf -> jail.local
An der.conf-Datei wird KEINE ÄNDERUNG durchgeführt.
Wir kopieren die Datei (vorbeugend) und erstellen so eine .local Datei:
cp jail.conf jail.local
Der Inhalt der Datei jail.local sieht in meinem Fall so aus:
[DEFAULT]
bantime = 21600
findtime = 120
maxretry = 3
[DEFAULT]
mta = sendmail
action = %(action_)s
destemail = admin@it-networker.at
sender = fail2ban@it-networker.at
Filter für NPM und Nextcloud erstellen
Wir wechseln am Host in das Verzeichnis /var/lib/docker/volumes/fail2banconfig/_data/fail2ban/filter.d
Dort erstellen wir eine Datei mit Namen: npm.local
Inhalt des NPM Filters (npm.local)
[INCLUDES]
before = common.conf
[Definition]
failregex = ^\s*(?:\[\]\s+)?- 401 \d+ - [A-Z]+ \w+ \S+ "[^"]+" \[Client <ADDR>\]
^<HOST> -.*"(GET|POST|HEAD).*HTTP.*" 403
^<HOST> -.*"(GET|POST|HEAD).*HTTP.*" 404
^<HOST> -.*"(GET|POST|HEAD).*HTTP.*" 444
Weiters erstellen wir eine Datei für Nextcloud mit Namen nextcloud.local
Inhalt des Nextcloud Filters (nextcloud.local)
[Definition]
_groupsre = (?:(?:,?\s*"\w+":(?:"[^"]+"|\w+))*)
failregex = ^\{%(_groupsre)s,?\s*"remoteAddr":"<HOST>"%(_groupsre)s,?\s*"messag>
^\{%(_groupsre)s,?\s*"remoteAddr":"<HOST>"%(_groupsre)s,?\s*"messag>
datepattern = ,?\s*"time"\s*:\s*"%%Y-%%m-%%d[T ]%%H:%%M:%%S(%%z)?"
Jail für SSH (des Hosts) NPM und Nextcloud erstellen
Ganz wichtig ist bezüglich „JAILS“ der Parameter chain =
- Ist es ein Dockercontainer, den wir schützen wollen, müssen wir bei chain = DOCKER-USER verwenden!
- Ist es der Host, den wir schützen wollen, müssen wir bei chain = INPUT verwenden!
Für die Anpassungen müssen wir (wieder am Host) in das Verzeichnis:
/var/lib/docker/volumes/fail2banconfig/_data/fail2ban/jail.d
wechseln.
Jail für Nextcloud (nextcloud.local)
Via nano nextcloud.local
erstellen wir eine Datei, mit Folgendem Inhalt.
[nextcloud]
backend = auto
enabled =
port = 80,443
chain = docker-user
protocol = tcp
filter = nextcloud
logpath = /remotelogs/nextcloud/nextcloud.log
action = %(known/action)s
Jail für Nextcloud-auth (nextcloud-auth.local)
Via nano nextcloud-auth.local
erstellen wir eine Datei, mit Folgendem Inhalt.
[nextcloud-auth]
enabled = true
chain = docker-user
port = http,https
logpath = %(remote_logs_path)s/nextcloud/nextcloud.log
destemail = admin@it-networker.at
sender = fail2ban@it-networker.at
sendername = Fail2Ban
Jail für den NPM (npm.local)
Via nano npm.local
erstellen wir eine Datei, mit Folgendem Inhalt.
[npm]
enabled = true
chain = docker-user
logpath = /remotelogs/npm/fallback_error.log
/remotelogs/npm/default-host_access.log
/remotelogs/npm/proxy-host-*_error.log
/remotelogs/npm/default-host_error.log
/remotelogs/npm/fallback_access.log
destemail = admin@it-networker.at
sender = fail2ban@it-networker.at
sendername = Fail2Ban
Jail für SSH des Hosts (sshd.local)
Via nano sshd.local
erstellen wir eine Datei, mit Folgendem Inhalt.
[sshd]
enabled=true
chain = INPUT
logpath = /remotelogs/authloghost/auth.log
backend = %(sshd_backend)s
destemail = admin@it-networker.at
sender = fail2ban@it-networker.at
sendername = Fail2Ban
Restart von Fail2Ban bzw. des Containers
Fail2ban kann mit dem Befehlt fail2ban-client restart
neu gestartet werden. Hier hat es bei mir allerdings immer wieder ein wenig „gehakelt“.
Am Besten ist es, einfach den Fail2Ban-Container neu zu starten. Nach einem Neustart des Containers, sollte nun auch Fail2Ban ordnungsgemäß funktionieren und sowohl Host, als auch Container schützen.
Beobachten kann man das Verhalten im Fail2Ban – Log. Das Logging findet allerdings im Container statt. Entweder verwendet ihr die Shell, die via Portainer erreichbar ist, oder greift einfach über die Konsole des Hosts darauf zu.
Der Zugriff auf die Container-Konsole gelingt mit:
docker exec -it fail2ban bash
fail2ban = hierbei der Name des Containers.
Das Prompt sieht so aus (bis auf das was vor dem : steht:
root@vps2348723:/# docker exec -it fail2ban bash
root@8ddbafffbff4:/#
Das Logverzeichnis befindet sich hier: /config/log/fail2ban
Die Datei heißt: fail2ban.log
Am Besten ist es ihr lasst mittels tail -f /config/log/fail2ban/fail2ban.log
das Log live mitlaufen und gebt bei den übewachten Diensten zb. mehrfach ein falsches Passwort ein. Das Log sollte darauf reagieren. (Bitte drauf achten, dass ihr euch nicht selbst aussperrt!)