Es gibt nur wenige kleine Skripte, die sich so fundamental auf den Betrieb eines Servers auswirken wie Fail2ban. Deshalb haben vermutlich auch die meisten schon einmal davon gehört. Wer Fail2ban nicht kennt, beschäftigt sich vermutlich eher mit anderen Bereichen der Systemadministration oder ist ein relativer Neueinsteiger.
Die Skriptsammlung arbeitet mit den üblichen Firewall-Paketen zusammen und sperrt IP-Adressen nach einigen gescheiterten Login-Versuchen aus. Das klingt vielleicht nicht besonders aufregend, aber die Wunder dieses leistungsfähigen Tools stecken im Detail.
Ich selbst habe Fail2ban vorwiegend für fehlgeschlagene SSH-Logins verwendet, was vermutlich die häufigste Anwendung ist, bevor ich davon genervt war, dass die Webserver-Logfiles voll mit den Spuren von Angriffsversuchen waren. Überall fanden sich Spuren davon, versteckte Verzeichnisse oder verwundbare Content-Management-Systeme zu finden. Außerdem hatte ich einige Mailserver, die das Relaying mit SASL-Passwort-Authentifizierung [1] gegen Benutzer-Accounts per PAM erlaubten. Die SASL-Accounts waren so eingerichtet, dass man sich damit nicht auf dem System einloggen konnte, aber trotzdem barg die Authentifizierung noch ein Restrisiko. Mit Fail2ban konnte ich einfach die betreffende IP-Adresse sperren, wenn ein Username dreimal das falsche Passwort verwendete.
Wie Fail2ban [2] arbeitet, ist leicht erklärt. Es beobachtet die Logdateien und führt eine vordefinierte Aktion aus, wenn es ein bestimmtes Muster findet. Wie man diese Filter und Aktionen definiert, wird schnell klar, wenn Fail2bain installiert ist.
Der erwähnte Einsatz von Fail2ban, Brute-Force-Attacken auf SSG zu stoppen, ist auf jeden Fall sehr sinnvoll. Er reduziert nicht nur das Rauschen in den Log-Dateien, es ist auch ein Sicherheitsrisiko, beliebig viele Versuche bei einem solchen Login zu erlauben. Viele Angriffe durch Bots lassen sich zusätzlich verhindern, wenn man den Port ändert, auf dem SSH läuft. Wer es sich erlauben kann, etwa weil Anwender immer dieselben IP-Adressen verwenden, sichert SSH zusätzlich ab, indem er das Login per TCP-Wrapper auf bestimmte IP-Adressen beschränkt [3]. Man sollte daran denken, dass automatisierte Angriffe äußerst effizient ablaufen und einige Male pro Sekunde ablaufen können. Damit können Angreifer in wenigen Minuten eine ganze Menge populärer Passwörter ausprobieren. Abbildung 1 zeigt eine Logdatei, die fehlgeschlagene Logins wiedergibt.
Glücklicherweise gibt es bereits einigen nützliche Skripts, die bei der Installation von Fail2ban auf der Festplatte landen. Dabei gibt es einige Abkürzungen, sogenannte Tags, die man in eigenen Skripts verwenden kann, zum Beispiel »HOST
«
. Das folgende Fragment trifft auf ein fehlgeschlagenes SSH-Login zu und findet sich auf einem Debian-Rechner in »/etc/fail2ban/filter.d/sshd.conf
«
:
failregex = ^%(__prefix_line)sFailed (?:password|publickey) for .* from <HOST>(?: port \d*)?(?: ssh\d*)?$
Die Regular Expression trifft auf Zeilen zu, wie sie in Abbildung 1 zu sehen sind und passt gleichermaßen auf fehlgeschlagene Logins per Username/Passwort und Public/Private Key. Die dritte Zeile macht von dem erwähnten Host-Tag Gebrauch.
Was die Logfile-Einträge betrifft, die sich von System zu System zum Teil erheblich unterscheiden, ist Fail2ban recht flexibel. Selbst in der Standard-Konfigurationsdatei für SSH haben die Fail2ban-Entwickler eine ganze Reihe von Formulierungen für die »failregex
«
vorgesehen, von denen eine für den jeweiligen Einsatzort passen sollte. Die Beispiel in Listing 1 sind normalerweise auskommentiert.
Listing 1
Failregex-Beispiele
Wie erwähnt, kann Fail2ban auch Angriffe auf den Mailserver abwehren, etwa Login-Versuchen per SASL. Die Failregex dafür in »/etc/fail2ban/filter.d/sasl.conf
«
sieht etwa so aus:
failregex = (?i): warning: [-._\w]+\[<HOST>\]: SASL (?:LOGIN|PLAIN|(?:CRAM|DIGEST)-MD5) authentication failed: authentication failure
Diese Regular Expression trifft auf die fehlgeschlagenen SASL-Logins zu, die im Logfile »/var/log/mail.log
«
so auftauchen. Der Ausdruck »(?i)
«
weist Fail2ban an, nicht auf die Groß- und Kleinschreibung der Strings zu achten (case insensitive). Die Syntax gehorcht den Regeln der Python Regular Expressions.