Fail2Ban zentralisieren

Fail2Ban zentralisieren

Im Folgenden werden wir euch erklären, wie Ihr Fail2Ban zentralisiert einsetzt, und somit euren Serververbund gegenüber multiplen Login versuchen schützen könnt.

Der Aufbau sieht wie folgt aus:

Fail2Ban Netzwerk Übersicht
Wir haben einen zentralen Server auf dem unsere Datenbank für die Speicherung der IP’s läuft. Jeder Server der nun von dieser IP-Adressenverteilung profitieren soll ist damit verbunden.

Grundsätzlich ist Fail2Ban ein Programm, welches die Logfiles nach mehrfach fehlgeschlagenen Login versuchen untersucht um ggf. IP-Adressen zu blockieren.

Da Fail2Ban nicht für den Betrieb in Kommunikation mit mehreren Server ausgelegt ist, benötigen wir noch eine MySQL Datenbank um die IP-Adressen zu verteilen. Insgesamt verteilen wir die IP Adressen über zwei Skripte und eine MySQL Datenbank.

Installation von Fail2Ban

Zunächst installieren wir die für unser vorhaben benötigten Pakete. (PHP5, PHP5-MySQL, Fail2Ban, iptables)

root@test:~# sudo apt-get install php5 php5-mysql fail2ban iptables

 

MySQL Datenbank einrichten

Wie oben schon erwähnt benötigen wir eine Datenbank. Wir haben dies mittels MySQL umgesetzt. Wir erstellen hierzu für Fail2Ban eine eigene Datenbank mit dem Namen “fail2ban”

root@test:~# mysql –u root –p
mysql> CREATE DATABASE fail2ban ;

In unser neu erstellten Datenbank, erstellen wir nun eine neue Tabelle, in der unsere gesammelten IP-Adressen gespeichert werden. Die Tabelle hat dabei folgende Felder: ID, Hostname, Erstellt, Name, Protokoll, Port, IP

Mysql> use fail2ban ;
mysql> CREATE TABLE IF NOT EXISTS `erp_core_fail2ban` (
`id` bigint(20) unsigned NOT NULL AUTO_INCREMENT,
`hostname` varchar(255) COLLATE utf8_unicode_ci DEFAULT NULL,
`created` datetime NOT NULL,  `name` text COLLATE utf8_unicode_ci NOT NULL,
`protocol` varchar(16) COLLATE utf8_unicode_ci NOT NULL,
`port` varchar(32) COLLATE utf8_unicode_ci NOT NULL,
`ip` varchar(64) COLLATE utf8_unicode_ci NOT NULL,
PRIMARY KEY (`id`),
KEY `hostname` (`hostname`,`ip`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;

 

Eintragen der IP’s in unsere Datenbank

Damit wir nun unsere durch fail2ban gebannten IP’s in unsere Datenbank eingetragen werden, legen wir ein neues Skript, welches wir dann auch ausführbar machen an.

root@test:~# cd /root && touch fail2ban.php && chmod +x fail2ban.php

Als nächstes Füllen wir das Skript mit folgendem Inhalt:

#!/usr/bin/php -n
#!/usr/bin/php
$protocol = $_SERVER["argv"][2];
$port = $_SERVER["argv"][3];
if (!preg_match('/^\d{1,5}$/', $port))
$port = getservbyname($_SERVER["argv"][3], $protocol);
$ip = $_SERVER["argv"][4];
$hostname = gethostname();
// connect to mysql by hostname, username and password
$link = mysql_connect('XXX.XXX.XXX.XXX', 'Username', 'Passwort') or die ('Could not connect: ' . mysql_error());
mysql_select_db('fail2ban') or die('Could not select database');
$query = 'INSERT INTO `erp_core_fail2ban` set hostname="' .
addslashes($hostname) . '", name="' . addslashes($name) . '", protocol="' .
addslashes($protocol) . '", port="' . addslashes($port) . '", ip="' .
addslashes($ip) . '", created=NOW()';
$result = mysql_query($query) or die('Query failed: ' . mysql_error());
mysql_close($link);
exit;

Hierbei muss noch unter mysql_connect die IP-Adresse, Username sowie das Passwort eingetragen werden.

 

Testen des Scriptes

Nun können wir mir folgendem Befehl testen, ob unser Script fehlerfrei funktioniert.

root@test:~# ./fail2ban.php jailname ssh 22 123.123.123.123

Nun müsste in unserer Datenbank eine neuer Eintrag vorhanden sein. Ist dieser vorhanden funktioniert unser Skript.

 

Einbinden in Fail2Ban

Damit nun das Eintragen der IP’s in unsere Datenbank automatisch passiert, müssen wir die Jail.conf in der Fail2Ban Konfirguration anpassen.

root@test:~# nano /etc/fail2ban/jail.conf

Hier suchen wir nun nach der Filterregel für SSH, wo wir dann folgendes finden:

[ssh]
enabled = true
port    = ssh
filter  = sshd
banaction = iptables-multiport
logpath  = /var/log/auth.log
maxretry = 1

 

Hier können wir nun schnell erkennen, welche Datei aufgerufen wird, sobald eine IP gebannt wird. In unserem falle ist dies “iptables-multiport”.

Nun öffnen wir diese Datei und ergänzen die Zeile actionban um den Aufruf unseres Skriptes:

root@test:~# nano /etc/fail2ban/action.d/iptables-multiport.conf
actionban = iptables -I fail2ban- 1 -s -j DROP
/usr/bin/php –f /root/fail2ban.php

Als nächstes starten wir den Fail2Ban Service neu. Ab jetzt wird jedesmal wenn eine IP über Fail2Ban gebannt wird, diese IP auch in unsere Datenbank geschrieben.

 

Zweiten Server verbinden

Der nächste Schritt ist nun das Auslesen und sperren der IP’s aus unserer Datenbank. Das folgenden Skript beinhaltet folgenden Ablauf:

  • Aufbauen einer Verbindung zur Datenbank
  • Auslesen der IP’s
  • Sperren der IP’s über IPTables
  • Löschen älterer IP’s dessen Bantime abgelaufen ist

 

#!/bin/bash
#Autor: 4its GmbH
while [ true ]; do
#Löschen der älteren Einträge nach Ablauf der Bantime
mysql -uUSERNAME -pPASSWORT -h XXX.XXX.XXX.XXX -e 'use fail2ban; DELETE FROM erp_core_fail2ban WHERE DATE_SUB(CURRENT_TIMESTAMP(), INTERVAL 720 MINUTE) > created;'
#doppelte einträge ausschließen
touch /scripts/doppelte
doppelteip=`iptables -L fail2ban-ssh -n | grep -E -o "(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)"`
for IP in $doppelteip
do
echo "$IP" >> /scripts/doppelte
done
#Auslesen der DB und speeren der IP's über fail2ban
test=`mysql -uUSERNAME -pPASSWORT -h XXX.XXX.XXX.XXX -e 'use fail2ban; SELECT DISTINCT ip FROM erp_core_fail2ban;'`
for IP in $test
do
if [[ `grep -c $IP /scripts/doppelte` == 0 ]]
then
iptables -I fail2ban-ssh -s $IP -j DROP
else
echo "vorhanden"
fi
done
rm -R /scripts/doppelte
#######
touch /scripts/blacklist
datenbank=`mysql -uUSERNAME -pPASSWORT -h XXX.XXX.XXX.XXX -e 'use fail2ban; SELECT DISTINCT ip FROM erp_core_fail2ban;'`
for IP in $datenbank
do
echo "$IP" >> /scripts/blacklist
done
ipaustable=`iptables -L fail2ban-ssh -n | grep -E -o "(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)"`
for IP in $ipaustable
do
if [[ `grep -c $IP /scripts/blacklist` == 0 ]]
then
iptables -D fail2ban-ssh -s $IP -j DROP
else
echo "vorhanden"
fi
done
rm -R /scripts/blacklist
sleep 300
done

Hierbei müsst ihr wieder dran denken, die mysql_connect Daten wie IP-Adresse, Username sowie das Passwort ein zutragen.

Nun läuft alles automatisiert ab. Das Skript für das auslesen der Datenbank wird aktuell im Abschnitt von 5 Minuten ausgeführt. Diese Zeit kann über die Sleeptime verändert werden.

Damit nun ein reibungsloser Ablauf vorausgesetzt werden kann, empfehlen wir, das dieses Skript täglich neugestartet wird. Dies lässt sich entweder über ein Crontab erledigen oder über ein weiteres Skript.

 

Anbei noch ein paar wichtige Kommandos die benötigt werden könnten:

Kommando Funktion
./fail2ban.php jailname ssh 22 IP IP manuell zur DB hinzufügen
iptables -I fail2ban-ssh -s $IP -j DROP IP manuell sperren
iptables -D fail2ban-ssh -s $IP -j DROP IP manuell entsperren
Select * From erp_core_fail2ban DB auslesen
Erp_core_fail2ban oder iptables -L Gesperrte IP’s sehen

Share this post

Comments (4)

  • C.P Reply

    Hallo zusammen. Danke für das bereitstellen der Scripte zum zentralen steuern von fail2ban über mehrere Server. Was ich dort vermisse… wird die Datenbank auch mal bereinigt. Also alte IPs von vor ein paar Tagen die schon längst wieder “unbanned” sind, das die Datenbank nicht ins unendliche wächst?
    Kann das irgendwie nicht finden… habt ihr da noch einen tipp..?

    2016-06-12 at 11:53
    • fouritsweb Reply

      Hallo,

      damit die Datenbank nicht ins unendliche wächst, werden alte Einträge durch ein “Delete” im Skript gelöscht.

      Auszug aus dem letzten Skript (Zweiten Server verbinden):
      mysql -uUSERNAME -pPASSWORT -h XXX.XXX.XXX.XXX -e ‘use fail2ban; DELETE FROM erp_core_fail2ban WHERE DATE_SUB(CURRENT_TIMESTAMP(), INTERVAL 720 MINUTE) > created;

      durch dieses “Delete” werden alle IPs aus der Datenbank entfernt, die älter sind als 720 Minuten. Diese Zeit kann natürlich entsprechend angepasst werden.

      2016-06-13 at 15:45
  • C.P Reply

    Vielen Dank für den Hinweis mit der “Delete” Stelle. Und vor allem: Toll das ihr Euer wissen wie man fail2ban noch besser in einem Rechnerverbund nutzen kann und ein Stück weit besser absichert!

    Gruss C.P

    2016-06-14 at 19:56
  • Jürgen Reply

    Hi,

    wunderbare Anleitung.

    Im Code habe ich noch hinzugefügt, damit der Code nicht einfach durchläuft sondern ausgeführt wird.

    Ich bin leider auf einem System mit engen restriktionen, bekomme somit “Fatal error: Call to undefined function mysql_connect() in /root/fail2ban.php on line 14” – gibt es eine Möglichkeit das ganze auch mit einem Bash Script auszuführen?

    Grüße, Jürgen

    2017-03-11 at 11:04

Leave a Reply

Your email address will not be published.


Diese Website nutzt Google Analytics. Möchtest du nicht weiter getrackt werden. Klicke hier.