Home.

Technik-Blog

Willkommen auf meinem
Notiz - Blog
Blog

Kmoser's Tech-Blog

Sonntag
31
Januar 2016

Ubuntu 14.04 - fail2ban

Das Paket fail2ban ist ein in der Sparche Python geschriebes Intrusion Prevention Framework mit dem man Dienste wie z.B. SSH, FTP, Apache, etc. vor Brute-Force oder DDOS Angriffen schützen kann indem es temporäre Firewall Regeln anlegt, die potenzielle Angreifer den Zugang zum Server verweigert. Es scannt permanent Logfiles und führt definierte Aktionen aus sobald ein oder mehrere, per regular Expression definierbare Ereignisse, innerhalb eines bestimmten Zeitraumes, eintreten.

Installation

Installiert wird fail2ban mit

sudo apt-get install fail2ban

Konfiguration

Die Standardkonfiguration befindet sich in der Datei /etc/fail2ban/jail.conf. Diese Datei scheint allerdings bei Updates des Paketes überschrieben werden zu können. Deshalb muss man sich eine lokale Kopie der Datei anlegen, in der man nun seine Änderungen eintragen kann.

sudo cp /etc/fail2ban/jail.conf /etc/fail2ban/jail.local

In Ubuntu 16.04 gibt es den Unterordner /etc/fail2ban/jail.d/ in dem man Änderungen an der Standardkonfiguration vornehmen kann.

Als erstes legen wir mittels ignoreip die IPs fest, die fail2ban niemals sperren soll. Diese Einstellung befindet sich in der Sektion [DEFAULT]. Es können dabei IP-Adressen, DNS Hostnamen oder CIDR Bereiche sein.

ignoreip = 127.0.0.1/8 123.123.123.123/32 me.mydomain.de

Des weiteren kann man mittels bantime einstellen wie lange ein potenzieller Angreifer geblockt bleiben soll. Die Zeitspanne wird in Sekunden angegeben. Ein Wert von 600 entspricht also 10 Minuten.

bantime = 600

Ein Client wird als Angreifer eingestuft, wenn er innerhalb der in findtime definierten Zeitspanne maxretry Fehlversuche verursacht.

Die nächste Einstellung die wir tätigen müssen ist die E-Mail Adresse, an die die Warnungen gesendet werden sollen

destemail = me@mydomain.de

sowie den Absendernamen um den entsprechenden Server leichter identifizieren zu können

sendername = WWW01 Fail2Ban

Der Wert für mta kann entweder sendmail oder mail sein. Hat man postfix installiert setzt man den Wert auf sendmail.

mta = sendmail

Mit dem Parameter action kann man jetzt noch festlegen, was passieren soll wenn ein Client geblockt wurde. Es gibt in der Standardkonfiguration drei mögliche Werte, die oberhalb des action Parameter definiert sind.

Wert Erklärung
action_ Sperrt die IP
action_mw Sperrt die IP und schickt eine E-Mail mit einem Whois-Report an destemail
action_mwl Sperrt die IP und schickt eine E-Mail mit einem Whois-Report und den betreffenden Log-Zeilen an destemail.

Jails

Der Rest der Konfigurationsdatei ist in Sektionen eingeteilt, welche die Jails definieren. Fail2ban kommt von Hause aus mit einigen vordefinierten Jails, die man bei Bedarf einfach nur aktivieren muss. Eine Jail Definition sieht z.B. so aus:

[apache]

enabled = true
port = http,https
filter = apache-auth
logpath = /var/www/vhosts/*/log/access.log*
maxretry = 3
findtime = 300
bantime  = 1800

Der Name der Jail Definition steht in eckigen Klammern und alle folgenden Optionen gehören zu dieser Jail Definition, solange bis wieder ein Name in eckigen Klammern kommt und eine neue Jail Definition einleitet oder das Dateiende erreicht ist.

Option Erklärung
enabled Der Wert true aktiviert und der Wert false deaktiviert ein Jail
port Hier wird der zu überwachende Service definiert
filter Hier wird eine Datei referenziert, die unter /etc/fail2ban/filter.d liegt.
logpath Pfad zu der Log Datei. Es kann der * als Wirdcard für Zeichen und Unterverzeichnisse verwendet werden.
findtime Überschreiben des Wertes findtime aus der [GLOBAL] Sektion
maxretry Überschreiben des Wertes maxretry aus der [GLOBAL] Sektion
bantime Überschreiben des Wertes bantime aus der [GLOBAL] Sektion

Betreibt man einen Webserver kann man z.B. folgende Jails aktivieren:

ssh, apache, apache-noscript, apache-overflows, php-url-fopen

Betreibt man zusätzlich einen Mailserver wie ich ihn hier auch schon beschrieben habe, kann man auch noch folgende Jails aktivieren:

postfix, sasl, dovecot

Weitere Jails kann man definieren indem man eigene Filter schreibt.

Den Status eines Jails, in diesem Beispiel des ssh Jails, kann man abfragen mit:

Bash
fail2ban-client status ssh

[SSH] Jail Erweiterung

Für den SSH Jail habe ich, wie bei fail2ban.org beschrieben eine weitere failregex Zeile hinzugefügt um auch diese Zeilen zu erwischen:

Feb 9 06:53:05 www sshd[16660]: reverse mapping checking getaddrinfo for sd-41861.webserver.eu.com [195.154.65.98] failed - POSSIBLE BREAK-IN ATTEMPT!

Dazu bearbeitet man die Datei /etc/fail2ban/filter.d/sshd.conf

sudo nano /etc/fail2ban/filter.d/sshd.conf

und fügt die folgende Zeile bei den anderen Zeilen der failregex Variablen ein

^%(__prefix_line)sreverse mapping checking getaddrinfo .* \[<host>\] failed - POSSIBLE BREAK-IN ATTEMPT!\s*$</host>

Analyse

Die Log-Datei befindet sich unter /var/log/fail2ban.log. Hier findet man Informationen über das Sperren und Entsperren von IP-Adressen und dessen Jail Name. Ausserdem finden sich hier Informationen ob sich Jail Einstellungen geändert haben bzw. ob ein neuer Jail gestartet wurde.

Mitfolgendem Befehl kann man sich eine Liste vn IP-Adressen ausgeben lassen, welche gesperrt wurden sowie dessen Häufigkeit.

awk '($(NF-1) = /Ban/){print $NF}' /var/log/fail2ban.log | sort | uniq -c | sort -nr

Die Ausgabe sieht etwa so aus:

22 115.231.222.176
18 88.80.187.139
 6 61.174.49.106
 2 41.231.53.25
 1 217.64.98.42

Um diese Auswertung über über alle Logdateien zu machen führt man folgenden Bfehl aus:

zgrep -h "Ban " /var/log/fail2ban.log* | awk '{print $NF}' | sort | uniq -c

Möchte man die Liste auch noch nach Angriffspunkt sortieren geht das so

zgrep -h "Ban " /var/log/fail2ban.log* | awk -F[\ \:] '{print $10,$8}' | sort | uniq -c | sort -nr

Das ergibt eine Liste wie die folgende:

22 115.231.222.176 [ssh]
18 88.80.187.139 [ssh]
 6 61.174.49.106 [ssh]
 1 41.231.53.25 [ssh]

Da Angriffe meißtens nicht nur von einem Rechner kommen, sondern mehrere Rechner zum Einsatz kommen, kann man sich die Adressen auch nach einem Teilnetzbereich ausgeben lassen

zgrep -h "Ban " /var/log/fail2ban.log* | awk '{print $NF}' | awk -F\. '{print $1"."$2"."}' | sort | uniq -c | sort -rn

Das ergibt folgende Ausgabe:

26 115.239.
22 115.231.
18 88.80.
 6 61.174.
 1 41.231.

Wenn man nun genauer wissen möchte was eine IP bzw. Netzbereich so angestellt hat, kann man sich so die Zeilen des Logs anzeigen lassen:

zgrep 115.239. /var/log/fail2ban.log

Das ergibt dann z.B. folgende Ausgabe

2015-02-11 22:55:42,757 fail2ban.actions: WARNING [ssh] Ban 115.239.228.15
2015-02-11 23:23:47,000 fail2ban.actions: WARNING [ssh] Ban 115.239.228.34
2015-02-11 23:25:43,269 fail2ban.actions: WARNING [ssh] Unban 115.239.228.15
2015-02-11 23:53:47,388 fail2ban.actions: WARNING [ssh] Unban 115.239.228.34
2015-02-12 00:19:19,141 fail2ban.actions: WARNING [ssh] Ban 115.239.228.4
2015-02-12 00:47:09,186 fail2ban.actions: WARNING [ssh] Ban 115.239.228.11
2015-02-12 00:49:19,493 fail2ban.actions: WARNING [ssh] Unban 115.239.228.4
2015-02-12 01:17:09,405 fail2ban.actions: WARNING [ssh] Unban 115.239.228.11

Eigene Jails

Zusätzlich zu den mitgelieferten Jails kann man auch eigene Jails definieren.

Fail2ban Jail

Da bei mir sehr viele Angriffe auf den SSH Port gehen und die Angreifer durch die kurze Sperrdauer auch immer wieder kommen, habe ich mir einen eigenen Filter eingerichtet, der das fail2ban Logfile im Auge behält. Wird eine IP-Adresse häufig gesperrt, bekommt diese zur Belohnung eine längere Sperrdauer.

Dazu fügt man in der Datei /etc/fail2ban/jail.local eine neue Jail-Definition ein:

[fail2ban-ssh]
enabled  = true
port     = ssh
filter   = fail2ban-ssh
logpath  = /var/log/fail2ban.log
maxretry = 3
findtime = 21600
bantime  = 86400

Entsprechend dem was man unter filter eingetragen hat, muss man jetzt noch einen Filter unter /etc/fail2ban/filter.d/ anlegen, in diesem Fall heißt die Datei fail2ban-ssh.conf.

sudo nano /etc/fail2ban/filter.d/fail2ban-ssh.conf

In die Datei kommt folgender Inhalt:

# Fail2Ban filter for fail2ban log
#
failregex = \[ssh\] Ban <HOST>
ignoreregex =

Zum Abschluss muss der Filter noch aktiviert werden mit:

fail2ban-client add fail2ban-ssh
fail2ban-client start fail2ban-ssh

Damit ist der Filter erstellt und aktiv.

Typo3 Login Jail

Um Brute Force Attacken auf das Backend-Login von Typo3 zu verhinden kann man ebenfalls ein Jail anlegen:

Apache Scanners Jail

Wenn man die Access Logs des Apaches betrachtet findet man immer wieder Versuche Login-Seiten von CMS-System oder Administrationswerkzeugen wie phpmyadmin oder plesk zu finden. Diese Scanner können wir ebenfalls von unserer Seite ausschlißen in dem wir ein neues Jail anlegen.

Dazu fügt man in der Datei /etc/fail2ban/jail.local eine neue Jail-Definition ein:

[apache-noscanners]
enabled  = true
port     = http,https
filter   = apache-noscanners
logpath  = /var/log/apache*/*access.log
maxretry = 1

Jetzt legt man den entsprechenden Filter in /etc/fail2ban/filter.d/apache-noscanners.conf mit folgendem Inhalt an:

# Fail2Ban configuration file

[Definition]
failregex = ^<HOST> .*"GET .*w00tw00t
# try to access to admin directory
            ^<HOST> .*"GET .*admin.* 403
            ^<HOST> .*"GET .*admin.* 404
# try to access to install directory
            ^<HOST> .*"GET .*install.* 404
# try to access to phpmyadmin
            ^<HOST> .*"GET .*dbadmin.* 404
            ^<HOST> .*"GET .*myadmin.* 404
            ^<HOST> .*"GET .*MyAdmin.* 404
            ^<HOST> .*"GET .*mysql.* 404
            ^<HOST> .*"GET .*websql.* 404
            ^<HOST> .*"GET \/pma\/.* 404
# try to access to wordpress (we use another CMS)
            ^<HOST> .*"GET .*wp-content.* 404
            ^<HOST> .*"GET .*wp-login.* 404
# try to access to typo3 (we use another CMS)
            ^<HOST> .*"GET .*typo3.* 404
# try to access to tomcat (we do not use it)
            ^<HOST> .*"HEAD .*manager.* 404
# try to access various strange scripts and malwares
            ^<HOST> .*"HEAD .*blackcat.* 404
            ^<HOST> .*"HEAD .*sprawdza.php.* 404
            ^<HOST> .*"HEAD .*mocfilemanager.* 404
ignoreregex =

Um den Filter zu aktivieren folgende Befehle ausführen.

fail2ban-client add apache-noscanners
fail2ban-client start apache-noscanners

Solche Scanner Tools die nach Sicherheitslücken suchen gibt es z.B. bei sectools.org.

Apache SQL Injection Jail

Um SQL Injections zu unterbinden kann man ebenfall ein Jail einrichten. Ein schönes Beispiel gibt es auf GitHub (Forks beachten!!).

Um den Filter einzurichten eine Datei /etc/fail2ban/filter.d/apache-sqlinject.conf mit dem entsprechenden Inhalt aus dem GitHub Repository anlegen, dann in der Datei /etc/fail2ban/jail.d/020-apache2.conf folgende Passage hinzufügen:

020-apache2.conf
[apache-sqlinject]

enabled  = true
port     = http,https
filter   = apache-sqlinject
logpath  = /var/www/vhosts/*/log/access.log
#bantime  = 172800
maxretry = 2

Für den Fall das der Code mal nicht mehr vorhanden sein soll, hier eine gekürtze Fassung.

apache-sqlinject.conf
[Definition]

sqlfragments_generic = select.*from|delete.*from|update.*set|insert.*into|replace.*(value|set)
sqlfragments_havij = and(\+|%%20)ascii%%28substring|and(\+|%%20)Length|union(\+|%%20)all(\+|%%20)select|and(\+|%%20)1%%3C1|and(\+|%%20)1%%3D1|and(\+|%%20)1%%3E1|and(\+|%%20)%%27.%%27%%3D%%27|%%2F\*%%21[0-9]+((\+|%%20)[0-9]*)?\*%%2F

failregex = ^<HOST> -[^"]*"[A-Z]+\s+/[^"]*\?[^"]*(?i)(?:%(sqlfragments_generic)s|%(sqlfragments_havij)s)[^"]*HTTP[^"]*"

ignoreregex =

Fail2ban jail

Existiert das Fil2ban Logfile nicht, dann startet fail2ban nicht. Es muss also vorher angelegt werden. Dazu legt man ein neues Initscript /etc/init.d/fail2ban-tmpfs an das folgenden Inhalt hat:

#!/bin/bash
#
### BEGIN INIT INFO
# Provides:          fail2ban-tmpfs
# Default-Start:     2 3 4 5
# Default-Stop:      0 1 6
# Required-Start:
# Required-Stop:
# Short-Description: Create /var/log/fail2ban.log on tmpfs at startup
# Description:       Create /var/log/fail2ban.log needed by Apache.
### END INIT INFO
#
# main()
#
case "${1:-''}" in
  'start')
   # create the /var/log/fail2ban.log needed by fail2ban jail
   touch /var/log/fail2ban.log
   chmod 777 /var/log/fail2ban.log
   ;;
  'stop')
   ;;
  'restart')
   ;;
  'reload'|'force-reload')
   ;;
  'status')
   ;;
  *)
   echo "Usage: $SELF start"
   exit 1
   ;;
esac

Das Script ausführbar machen

sudo chmod a+x /etc/init.d/fail2ban-tmpfs

Dann das Script vor fail2ban starten

update-rc.d fail2ban-tmpfs defaults 90 10

Damit wird jetzt das Log-File vor dem Start von fail2ban angelegt und der Dienst kann wieder korrekt starten.

Probleme

Es kann sein, dass im Syslog sich wiederholende Meldungen wie folgt abgekürzt werden:

Feb 9 07:52:57 www sshd[19672]: message repeated 2 times: [ Failed password for root from 115.230.126.151 port 43913 ssh2]

wenn das passiert, stimmen der Zähler von fail2ban nicht mehr. Um diesen Wiederholungszähler zu deaktivieren muss man die Datei /etc/rsyslog.conf editieren und den Wert von RepeatedMsgReduction von on auf off stellen und danach rsyslog neu starten.

sudo service rsyslog restart

Jetzt kann fail2ban wieder die richtigen Werte ermtteln.