Diese Seite ist von der Webseite großteils kopiert http://crycode.de/wiki/Fail2Ban
====== Fail2Ban ======
Häufig kommt es vor, dass einzelne Benutzer oder automatisierte Scripts an einem Server verschiedene Kombinationen aus Benutzernamen und Passwörtern "ausprobieren" (das sogenannte [[wp>Burte-Force]]) mit dem Ziel einen funktionierenden Login zu finden. Dies wollen wir natürlich verhindern und die Verursacher wirkungsvoll aussperren, wobei uns das Tool //Fail2Ban// behilflich ist.
//Fail2Ban// ist ein kleines Programm auf [[wp>Python_(programming_language)|Python]]-Basis, welches die Logdateien der Server durchsucht und IP-Adressen die zu viele fehlgeschlagene Loginversuche haben blockiert. Das Blockieren der IP-Adressen geschieht dabei in der Regel über **Firewallregeln**, welche von //Fail2Ban// entsprechend angepasst werden.
In dieser Anleitung werden wir die, bei Linux üblichen, [[wp>Iptables]] verwenden. Weiterhin bringt //Fail2Ban// aber auch Unterstützung für z.B. Shorewall mit und lässt sich beliebig an die auf dem System eingesetzte Firewall anpassen.
Von Hause aus unterstützt die aktuelle Version von Fail2Ban nur IPv4-Adressen. Durch eine recht kleine Anpassung lässt es sich jedoch auch auf IPv6 erweitern.
===== Installation =====
Unter [[http://crycode.de/wiki/Debian|Debian]] und [[http://crycode.de/wiki/Ubuntu|Ubuntu]] Linux ist die Installation von Fail2Ban gewohnt einfach und ggf. fehlende Abhängigkeiten werden automatisch mit installiert:
root@meinserver:~# apt-get install fail2ban
Damit ist die Installation auch schon vollständig und Fail2Ban wurde bereits gestartet.
root@meinserver:~# /etc/init.d/fail2ban status
Status of authentication failure monitor:fail2ban is running.
===== Konfiguration =====
Die gesamten Einstellungen von Fail2Ban befindet sich im Verzeichnis ''/etc/fail2ban/''.
Die grundlegende Konfiguration erfolgt in der Datei ''jail.local'', welche eine Kopie der ''jail.conf'' darstellt. Anpassungen könnten auch in der ''jail.conf'' vorgenommen werden, jedoch wird diese bei einem Update eventuell überschrieben. Sobald die Datei ''jail.local'' vorhanden ist wird diese von Fail2Ban verwendet und unsere Konfiguration bleibt auch bei einem Update erhalten.
Zuerst müssen wir also die ''jail.conf'' als ''jail.local'' kopieren und anschließend passen wir die ''jail.local'' nach unsern Vorstellungen an.
root@meinserver:~# cp /etc/fail2ban/jail.conf /etc/fail2ban/jail.local
root@meinserver:~# nano /etc/fail2ban/jail.local
Die Konfigurationsdateien sind in verschiedene Sektionen unterteilt. Eine Sektion wird durch eckige Klammern gekennzeichnet (z.B. //[ssh]//).
Die //DEFAULT//-Sektion stellt dabei eine Besonderheit dar. Die hier vorgenommenen Einstellungen gelten für alle anderen Sektionen, sofern ein Wert nicht in einer Sektion erneut gesetzt wird. Ansonsten sind die Einstellungen nur für die jeweils aktuelle Sektion gültig.
==== Die DEFAULT-Sektion ====
Bei **ignoreip** können IP-Adressen angegeben werden die nie geblockt werden sollen. Es empfiehlt sich hier zumindest während der Konfiguration seine eigene IP hinzuzufügen.
Unter **bantime** wird die Bannzeit in Sekunden angegeben. Wir belassen es hier bei dem voreingestellten Wert von 600 (entspricht 10 Minuten).
**maxretry** gibt die Anzahl der Fehlversuche an, ab der er eine Aktion ausgelöst wird.
Bei **destemail** kann eine E-Mail Adresse angegeben werden, an die Benachrichtigungen gesendet werden, wenn Fail2Ban eine IP-Adresse blockiert.
**banaction** legt fest, welche Aktion zum Blockieren einer IP angewendet werden soll. Wir belassen diese bei iptables-multiport, da damit gleich mehrere Ports gesperrt werden können.
Den Eintag bei **action** ändern wir auf ''%(action_mwl)s'' damit wir beim Blockieren einer IP-Adresse eine E-Mail mit ein paar Informationen zugesendet bekommen.
==== Andere Sektionen, die sogenannten Jails ====
In jeder Sektion kann eine Einstellung aus der //DEFAULT//-Sektion (z.B. //bantime//) überschieben werden.
Nicht benötigte Jails sollten deaktiviert werden.
**Erforderlich sind in den Sektionen die folgenden Einstellungen:**\\
* **enabled** legt fest, ob die Sektion aktiviert ist oder nicht.\\
* **port** gibt den Port oder die Ports an die für die IP gesperrt werden sollen\\
* **filter** definiert den verwendeten Filter für diese Sektion. Alle verfügbaren Filter befinden sich im Verzeichnis ''/etc/fail2ban/filter.d/''.\\
* **logpath** legt die Logdatei fest, welche überwacht werden soll.\\
==== Beispiel einer jail.local ====
# Fail2Ban configuration file.
#
# This file was composed for Debian systems from the original one
# provided now under /usr/share/doc/fail2ban/examples/jail.conf
# for additional examples.
#
# To avoid merges during upgrades DO NOT MODIFY THIS FILE
# and rather provide your changes in /etc/fail2ban/jail.local
#
# Author: Yaroslav O. Halchenko
#
# $Revision: 281 $
#
# The DEFAULT allows a global definition of the options. They can be override
# in each jail afterwards.
[DEFAULT]
# "ignoreip" can be an IP address, a CIDR mask or a DNS host
ignoreip = 127.0.0.1
bantime = 900
findtime = 900
maxretry = 5
# "backend" specifies the backend used to get files modification. Available
# options are "gamin", "polling" and "auto".
# yoh: For some reason Debian shipped python-gamin didn't work as expected
# This issue left ToDo, so polling is default backend for now
backend = polling
#
# Destination email address used solely for the interpolations in
# jail.{conf,local} configuration files.
destemail = root@localhost
#
# ACTIONS
#
# Default banning action (e.g. iptables, iptables-new,
# iptables-multiport, shorewall, etc) It is used to define
# action_* variables. Can be overriden globally or per
# section within jail.local file
banaction = iptables-multiport
# email action. Since 0.8.1 upstream fail2ban uses sendmail
# MTA for the mailing. Change mta configuration parameter to mail
# if you want to revert to conventional 'mail'.
mta = sendmail
# Default protocol
protocol = tcp
#
# Action shortcuts. To be used to define action parameter
# The simplest action to take: ban only
action_ = %(banaction)s[name=%(__name__)s, port="%(port)s", protocol="%(protocol)s]
# ban & send an e-mail with whois report to the destemail.
action_mw = %(banaction)s[name=%(__name__)s, port="%(port)s", protocol="%(protocol)s]
%(mta)s-whois[name=%(__name__)s, dest="%(destemail)s", protocol="%(protocol)s]
# ban & send an e-mail with whois report and relevant log lines
# to the destemail.
action_mwl = %(banaction)s[name=%(__name__)s, port="%(port)s", protocol="%(protocol)s]
%(mta)s-whois-lines[name=%(__name__)s, dest="%(destemail)s", logpath=%(logpath)s]
# Choose default action. To change, just override value of 'action' with the
# interpolation to the chosen action shortcut (e.g. action_mw, action_mwl, etc) in jail.local
# globally (section [DEFAULT]) or per specific section
action = %(action_mwl)s
#
# JAILS
#
# Next jails corresponds to the standard configuration in Fail2ban 0.6 which
# was shipped in Debian. Enable any defined here jail by including
#
# [SECTION_NAME]
# enabled = true
#
# in /etc/fail2ban/jail.local.
#
# Optionally you may override any other parameter (e.g. banaction,
# action, port, logpath, etc) in that section within jail.local
[ssh]
enabled = true
#port = ssh
filter = sshd
banaction = iptables-allports
protocol = all
port = anyport
logpath = /var/log/auth.log
# findtime: 1 week
findtime = 604800
# bantime: 1 week
bantime = 604800
maxretry = 5
# Generic filter for pam. Has to be used with action which bans all ports
# such as iptables-allports, shorewall
[pam-generic]
enabled = false
# pam-generic filter can be customized to monitor specific subset of 'tty's
filter = pam-generic
# port actually must be irrelevant but lets leave it all for some possible uses
port = all
banaction = iptables-allports
port = anyport
logpath = /var/log/auth.log
maxretry = 6
[xinetd-fail]
enabled = false
filter = xinetd-fail
port = all
banaction = iptables-multiport-log
logpath = /var/log/daemon.log
maxretry = 2
[ssh-ddos]
enabled = true
port = ssh
filter = sshd-ddos
logpath = /var/log/auth.log
maxretry = 6
#
# HTTP servers
#
[apache]
enabled = true
port = http,https
filter = apache-auth
logpath = /var/log/apache*/*error.log
maxretry = 6
# default action is now multiport, so apache-multiport jail was left
# for compatibility with previous (<0.7.6-2) releases
[apache-multiport]
enabled = false
port = http,https
filter = apache-auth
logpath = /var/log/apache*/*error.log
maxretry = 6
[apache-noscript]
enabled = false
port = http,https
filter = apache-noscript
logpath = /var/log/apache*/*error.log
maxretry = 6
[apache-overflows]
enabled = false
port = http,https
filter = apache-overflows
logpath = /var/log/apache*/*error.log
maxretry = 2
#
# FTP servers
#
[vsftpd]
enabled = false
port = ftp,ftp-data,ftps,ftps-data
filter = vsftpd
logpath = /var/log/vsftpd.log
# or overwrite it in jails.local to be
# logpath = /var/log/auth.log
# if you want to rely on PAM failed login attempts
# vsftpd's failregex should match both of those formats
maxretry = 6
[proftpd]
enabled = false
port = ftp,ftp-data,ftps,ftps-data
filter = proftpd
logpath = /var/log/proftpd/proftpd.log
maxretry = 6
[wuftpd]
enabled = false
port = ftp,ftp-data,ftps,ftps-data
filter = wuftpd
logpath = /var/log/auth.log
maxretry = 6
#
# Mail servers
#
[postfix]
enabled = false
port = smtp,ssmtp
filter = postfix
logpath = /var/log/mail.log
[couriersmtp]
enabled = false
port = smtp,ssmtp
filter = couriersmtp
logpath = /var/log/mail.log
#
# Mail servers authenticators: might be used for smtp,ftp,imap servers, so
# all relevant ports get banned
#
[courierauth]
enabled = false
port = smtp,ssmtp,imap2,imap3,imaps,pop3,pop3s
filter = courierlogin
logpath = /var/log/mail.log
[sasl]
enabled = false
port = smtp,ssmtp,imap2,imap3,imaps,pop3,pop3s
filter = sasl
# You might consider monitoring /var/log/warn.log instead
# if you are running postfix. See http://bugs.debian.org/507990
logpath = /var/log/mail.log
==== Webmin überwachen lassen ====
Weiterhin können wir durch den folgenden Eintrag in der ''jail.local'' das Verwaltungstool Webmin überwachen lassen.
# Webmin
[webmin-auth]
enabled = true
port = 65432
filter = webmin-auth
logpath = /var/log/auth.log
maxretry = 5
==== Mehrfach geblockte Hosts längere Zeit aussperren ====
Sinnvoll ist es außerdem Hosts längere Zeit auszusperren nachdem sie mehrfach durch ein anderes Jail geblock wurden.
Hierfür tragen wir am Ende der ''jail.local'' folgendes ein:
# Fail2Ban
[fail2ban]
enabled = true
filter = fail2ban
banaction = iptables-allports
protocol = all
port = anyport
logpath = /var/log/fail2ban.log
# findtime: 1 week
findtime = 604800
# bantime: 1 week
bantime = 604800
maxretry = 5
Zusätzlich müssen wir noch die passenden Filterregeln in der Datei ''/etc/fail2ban/filter.d/fail2ban.conf'' erstellen:
[Definition]
failregex = fail2ban.actions: WARNING \[(.*)\] Ban
ignoreregex = fail2ban.actions: WARNING \[fail2ban\] Ban
==== Neustart von Fail2Ban ====
Zum Schluss starten wir Fail2Ban neu um alle Anpassungen zu aktivieren.
root@meinserver:~# /etc/init.d/fail2ban restart
Restarting authentication failure monitor: fail2ban.
Nun ist Fail2Ban aktiv und überwacht pausenlos die in der jail.local eingestellten Logdateien.
===== IPv6 =====
Von Hause aus unterstützt die aktuelle Version von Fail2Ban nur IPv4-Adressen. Durch eine recht kleine Anpassung lässt es sich jedoch auch auf IPv6 erweitern.
Im folgenden Abschnitt wird beschrieben welche Anpassungen vorgenommen werden müssen, damit Fail2Ban auch IPv6 Adressen erkennt und ggf. blockiert.
==== IPv4/IPv6 Weiche ====
Zuerst muss die Datei ''/usr/bin/ip64tables'' als Weiche zwischen IPv4 und IPv6 mit folgendem Inhalt erstellt werden:
#!/bin/bash
# iptables-Weiche
LINE=$*
RESULT=`echo $LINE | egrep " ([0-9]{1,3}\.){3}[0-9]{1,3}" | wc -l`
RESULT6=`echo $LINE | egrep "(::[A-Fa-f0-9])|((:[A-Fa-f0-9]{1,4}){2,})" | wc -l `
if [ $RESULT -eq "1" ]; then
# IPv4
iptables $LINE
ERRCODE=$?
elif [ $RESULT6 -eq "1" ]; then
# IPv6
ip6tables $LINE
ERRCODE=$?
else
# IPv4 und IPv6
iptables $LINE
ERRCODE=$?
ip6tables $LINE
if [ $? -ge "1" ]; then
ERRCODE=$?
fi
fi
exit $ERRCODE
Anschließend machen wir die Datei noch ausführbar:
root@meinserver~# chmod +x /usr/bin/ip64tables
==== Neue Aktionen bei Fail2Ban hinzufügen ====
Im Verzeichnis ''/etc/fail2ban/action.d/'' legen wir die drei Dateien mit folgendem Inhalt an:
[INCLUDES]
before = iptables-blocktype.conf
[Definition]
actionstart = ip64tables -N fail2ban-
ip64tables -A fail2ban- -j RETURN
ip64tables -I INPUT -p -m multiport --dports -j fail2ban-
actionstop = ip64tables -D INPUT -p -m multiport --dports -j fail2ban-
ip64tables -F fail2ban-
ip64tables -X fail2ban-
actioncheck = ip64tables -n -L INPUT | grep -q fail2ban-
actionban = ip64tables -I fail2ban- 1 -s -j
actionunban = ip64tables -D fail2ban- -s -j
[Init]
name = default
port = ssh
protocol = tcp
[INCLUDES]
before = iptables-blocktype.conf
[Definition]
actionstart = ip64tables -N fail2ban-
ip64tables -A fail2ban- -j RETURN
ip64tables -I INPUT -p -j fail2ban-
actionstop = ip64tables -D INPUT -p -j fail2ban-
ip64tables -F fail2ban-
ip64tables -X fail2ban-
actioncheck = ip64tables -n -L INPUT | grep -q fail2ban-
actionban = ip64tables -I fail2ban- 1 -s -j
actionunban = ip64tables -D fail2ban- -s -j
[Init]
name = default
protocol = tcp
# Fail2Ban configuration file
#
# Author: Daniel Black
#
# This is a included configuration file and includes the defination for the blocktype
# used in all iptables based actions by default.
#
# The user can override the default in iptables-blocktype.local
[Init]
# Option: blocktype
# Note: This is what the action does with rules. This can be any jump target
# as per the iptables man page (section 8). Common values are DROP
# REJECT, REJECT --reject-with icmp-port-unreachable
# Values: STRING
#
#--reject-with icmp-port-unreachable ist nicht moeglich, da ipv6 nicht damit funktioniert. diese option ist aber der standart von REJECT
blocktype = REJECT
==== Fail2Ban-Dateien Patchen ====
Damit Fail2Ban die IPv6-Adressen auch richtig erkennt müssen die beiden Dateien ''failregex.py'' und ''filter.py'' gepachtet werden. //Je nach Fail2Ban-Version sind dafür unterschiedliche Patches nötig.//
Die aktuell verwendete Version von Fail2Ban kann über den folgenden Befehl ermittelt werden:
benutzer@meinserver:~$ fail2ban-server -V
Fail2Ban v0.8.13
Copyright (c) 2004-2008 Cyril Jaquier, 2008- Fail2Ban Contributors
Copyright of modifications held by their respective authors.
Licensed under the GNU General Public License v2 (GPL).
Written by Cyril Jaquier .
Many contributions by Yaroslav O. Halchenko .
Abhängig von der Version legen wir zuerst die zwei patch-Dateien im Verzeichnis ''/tmp'' an:
=== für Fail2Ban v0.8.13 (Debian jessie, Ubuntu trusty/utopic) ===
# Fail2Ban IPv6 Patch for Fail2Ban v0.8.13
--- failregex.py.orig
+++ failregex.py
@@ -41,7 +41,7 @@
self._matchCache = None
# Perform shortcuts expansions.
# Replace "" with default regular expression for host.
- regex = regex.replace("", "(?:::f{4,6}:)?(?P[\w\-.^_]+)")
+ regex = regex.replace("", "(?:::f{4,6}:)?(?P[\w\-.^_:]+)")
if regex.lstrip() == '':
raise RegexException("Cannot add empty regex")
try:
# Fail2Ban IPv6 Patch for Fail2Ban v0.8.13
--- filter.py.orig
+++ filter.py
@@ -655,6 +655,7 @@
class DNSUtils:
IP_CRE = re.compile("^(?:\d{1,3}\.){3}\d{1,3}$")
+ IP_CRE6 = re.compile("^(?:[0-9:A-Fa-f]{3,})$")
#@staticmethod
def dnsToIp(dns):
@@ -678,19 +679,21 @@
if match:
return match
else:
- return None
+ match = DNSUtils.IP_CRE6.match(text)
+ if match:
+ """ Right Here, we faced to a ipv6
+ """
+ return match
+ else:
+ return None
searchIP = staticmethod(searchIP)
#@staticmethod
def isValidIP(string):
""" Return true if str is a valid IP
+ We Consider that logfiles didn't make errors ;)
"""
- s = string.split('/', 1)
- try:
- socket.inet_aton(s[0])
- return True
- except socket.error:
- return False
+ return True
isValidIP = staticmethod(isValidIP)
#@staticmethod
Anschließend wenden wir die beiden Patches noch an:
root@meinserver:~# patch -l -b /usr/share/fail2ban/server/failregex.py /tmp/failregex.patch
patching file /usr/share/fail2ban/server/failregex.py
root@meinserver:~# patch -l -b /usr/share/fail2ban/server/filter.py /tmp/filter.patch
patching file /usr/share/fail2ban/server/filter.py
Durch den Parameter ''-b'' wird beim Patchen jeweils ein Backup der Originaldatei (''failregex.py.orig'' bzw. ''filter.py.orig'' angelegt. Sollte etwas schief gehen kann damit jederzeit der Ausgangszustand wiederhergestellt werden.
Abschließend müssen die beiden Dateien noch neu compiled werden:
root@meinserver:~# pycompile /usr/share/fail2ban/server/failregex.py
root@meinserver:~# pycompile /usr/share/fail2ban/server/filter.py
==== Einstellungen in der Datei jail.local anpassen ====
Damit Fail2Ban die neuen Aktionen verwendet müssen alle **banaction**-Einträge in der ''jail.local'' angepasst werden.
Dabei ändern wir überall in der Datei ''iptables-multiport'' in ''ip64tables-multiport'' und ''iptables-allports'' in ''ip64tables-allports''. Sollten noch andere Aktionen im Einsatz sein, so müssen diese ggf. auch angepasst werden.
==== Fail2Ban neustarten und iptables sowie ip6tables kontrollieren ====
root@meinserver:~# service fail2ban restart
Nun kontrollieren wir noch die aktuellen iptables und ip6tables.
root@meinserver:~# iptables -L -n -v
root@meinserver:~# ip6tables -L -n -v
Wenn alles geklappt hat sind jetzt in den Ausgaben die Regeln und Ketten (Chain) von Fail2Ban zu sehen.