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.