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:
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 |
Comments (4)
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..?
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.
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
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