Inhaltsverzeichnis

Server Dienst Zugangskontrolle: BlockHosts Skript

Wer zB einen öffentlich zugänglichen FTP-Server betreibt, kennt das Szenario: Beim checken der Server Logs wird das Logfiles mit zahlreichen fehlgeschlagenen Anmeldeversuchen förmlich zugespammt. Ich konnte zB auf unseren Servern in Spitzenzeiten mehrere Hunderttausend fehlgeschlagener Anmeldeversuche in einer Nacht feststellen. Meist harmlos, weil da einfach mittels Brute Force1) versucht wird das Passwort zu knacken. IdR ist dies ein Zeichen dafür, dass harmlose Script Kiddies ihr Unwesen treiben. Der unangenehme Nebeneffekt dieser Aktionen besteht allerdings darin, dass das Logfile nicht mehr vernünftig ausgewertet werden kann und die Gefahr steigt, zwischen den endlosen Zeilen doch mal eine wichtige Meldung zu übersehen. Dazu gesellt sich noch die nicht zu unterschätzende Last am Server und der meist begrenzten Internet Bandbreite.

Man kann diese Art eines Angriffs abwehren, in dem man bei jedem Anmeldeversuch die Logfiles der zu schützenden Dienste nach fehlerhaften Anmeldeversuchen durchsucht und bei einer bestimmten Anzahl fehlerhaften Anmeldeversuche die IP-Adresse des Angreifers für einen bestimmten Zeitraum blockiert. Eine mögliche Variante für dieses Szenario ist das Phyton Script BlockHosts2). Die IP Adresse des Angreifers wird nach Erreichen einer bestimmten Anzahl fehlerhaften Anmeldeversuche entweder vorübergehend in die Datei /etc/hosts.allow3) mit dem deny-Flag eingetragen oder die Systemfirewall iptables wird mit einer Drop Regel konfiguriert bzw. es kann ein Null-Routing konfiguriert werden, um die TCP-Pakete des Angreifers im Nirvana verschwinden zu lassen. Dieses Tutorial beschränkt sich auf die hosts.allow Variante in Verbindung mit dem freien FTP-Server »vsftpd«4).

Vorraussetzungen:

Überprüfen Sie ob »Python« auf dem System vorhanden ist:

vmdebian3:/etc/# which python
/usr/bin/python
vmdebian3:/etc/# python --version
Python 2.5.2

Installation:

Laden Sie sich den Quellcode des BlockHost Skripts von der Webseite herunter und entpacken es:

vmdebian3:/etc# cd /tmp/
vmdebian3:/tmp# wget http://www.aczoom.com/tools/blockhosts/BlockHosts-2.4.0.tar.gz
vmdebian3:/tmp# tar -xvf BlockHosts-2.4.0.tar.gz
vmdebian3:/tmp# ls -l
insgesamt 76
drwxr-xr-x 5  500 users  4096 18. Mai 2008  BlockHosts-2.4.0
-rw-r--r-- 1 root root  57467 18. Mai 2008  BlockHosts-2.4.0.tar.gz
vmdebian3:/tmp# cd BlockHosts-2.4.0
vmdebian3:/tmp/BlockHosts-2.4.0# ls
bhrss.html  blockhosts.cfg   blockhosts.py  INSTALL  logrotate.d  MANIFEST  README  setup.py  test_data
bhrss.py    blockhosts.html  CHANGES	    LICENSE  logwatch	  PKG-INFO  setup.cfg  test_blockhosts.py



Führen Sie für eine Neuinstallation das Python Skript setup.py aus. Für detaillierte Information lesen Sie bitte das INSTALL File im BlockHosts Verzeichnis:

vmdebian3:/tmp/BlockHosts-2.4.0# python setup.py install --force
running install
running build
running build_scripts
creating build
creating build/scripts-2.5
copying and adjusting blockhosts.py -> build/scripts-2.5
copying and adjusting bhrss.py -> build/scripts-2.5
changing mode of build/scripts-2.5/blockhosts.py from 644 to 755
changing mode of build/scripts-2.5/bhrss.py from 644 to 755
running install_scripts
copying build/scripts-2.5/bhrss.py -> /usr/bin
copying build/scripts-2.5/blockhosts.py -> /usr/bin
changing mode of /usr/bin/bhrss.py to 755
changing mode of /usr/bin/blockhosts.py to 755
running install_data
copying blockhosts.cfg -> /etc
copying logrotate.d/blockhosts -> /etc/logrotate.d
running install_egg_info
Writing /usr/lib/python2.5/site-packages/BlockHosts-2.4.0.egg-info
vmdebian3:/tmp/BlockHosts-2.4.0#

Konfiguration

Die zentrale Konfigurations-Datei von BlockHosts ist /etc/blockhosts.cfg. Hier werden wir das Skript unseren Bedürfnissen anpassen. Des Weiteren ist die /etc/hosts.allow das zentrale Blockhost File. Hier ist es sinnvoll auch eine Whitelist anzulegen, um zu verhindern, dass wichtige Kunden oder möglicherweise sogar Sie selbst versehentlich ausgesperrt werden. Letzteres wäre vor allem bei SSH peinlich. Da der TCP-Wrapper bei jedem Aufruf eines Dienstes diese Datei auswertet, wird auch hier der Aufruf des BlockHosts Skripts platziert. So wird sichergestellt, dass das Skript bei jedem Aufruf eines Dienstes die Logfiles der konfigurierten Dienste überprüft werden und ggf die Sperrliste aktualisiert wird.

Kommentieren Sie in der Datei /etc/blockhosts.cfg folgende Zeilen aus:

/etc/blockhosts.cfg

HOSTS_BLOCKFILE = "/etc/hosts.allow"
HOST_BLOCKLINE = ["ALL: ", " : deny"]
COUNT_THRESHOLD = 7
AGE_THRESHOLD = 12
LOGFILES = [ "/var/log/vsftpd.log", ]

Fügen Sie in der Datei /etc/hosts.allow folgende Zeilen am Ende ein:

/etc/hosts.allow

#---- BlockHosts Additions
#---- BlockHosts Additions
 
vsftpd: ALL: spawn (/usr/bin/blockhosts.py --verbose --echo "%c-%s" >> /var/log/blockhosts.log 2>&1 )& : allow

Führen Sie das Script blockhosts.py --verbose im entpackten BlockHosts Paket aus. Dadurch werden die konfigurierten Logfiles das erste mal ausgewertet und der Offset festgelegt, ab wann das Logfile gelesen werden soll. Dadurch wird verhindert, dass bei bereits laufenden Servern beim ersten produktiven Lauf sämtliche FAIL LOGIN Einträge auswertet und alle bislang bestehenden Hosts mit fehlerhaften Logins auf einmal gesperrt werden. Des Weiteren werden weitere Tags in die Datei /etc/hosts.allow eingefügt.

vmdebian3:~# cd /tmp/BlockHosts-2.4.0/
vmdebian3:/tmp/BlockHosts-2.4.0# blockhosts.py --verbose
blockhosts 2.4.0 started: 2010-04-25 02:02:07 CEST
 ... loaded /etc/hosts.allow, starting counts: blocked 0, watched 0
 ... loading log file /var/log/secure, offset: 0
 ... loading log file /var/log/vsftpd.log, offset: 4621
 ... discarding all host entries older than  2010-04-24 14:02:07 CEST
 ... final counts: blocked 0, watched 0

Fertig

Testen der Konfiguration

Eine Blockhosts konfigurierte /etc/hosts.allow ohne bisher fehlerhaften Anmeldung sieht folgendermaßen aus:

/etc/hosts.allow

#---- BlockHosts Additions
 
#bh: logfile: /var/log/vsftpd.log
#bh: offset: 4621
#bh: first line:Sat Apr 24 21:42:16 2010 [pid 3363] CONNECT: Client "127.0.0.1"
 
#---- BlockHosts Additions
 
vsftpd: ALL: spawn (/usr/bin/blockhosts.py --verbose --echo "%c-%s" >> /var/log/blockhosts.log 2>&1 )& : allow

Beim ersten fehlerhaften Anmeldeversuch eines Clients wird dem Blockhost Abschnitt folgender Eintrag hinzugefügt:

/etc/hosts.allow

#---- BlockHosts Additions
#bh: ip:   192.168.172.1 :   1 : 2010-04-25 02:19:55 CEST
 
#bh: logfile: /var/log/secure
#bh: offset: 0
#bh: first line:
 
#bh: logfile: /var/log/vsftpd.log
#bh: offset: 4837
#bh: first line:Sat Apr 24 21:42:16 2010 [pid 3363] CONNECT: Client "127.0.0.1"
 
#---- BlockHosts Additions
 
vsftpd: ALL: spawn (/usr/bin/blockhosts.py --verbose --echo "%c-%s" >> /var/log/blockhosts.log 2>&1 )& : allow

Beachten Sie, dass die Datei /etc/hosts.allow immer nur beim Aufruf eines Dienstes ausgewertet wird. Ist dem FTP-Server in seiner Konfiguration kein Limit bei den fehlerhaften Logins gesetzt, laufen alle Login Versuche in einer Session ab. Solange der Angreifer seinen Versuch nicht abbricht, wird BlockHosts diesen Angriff nicht abwehren können. Konsultieren Sie hierfür die Konfigurations-Datei Ihres FTP-Servers. Ein Beispiel finden Sie hier: -> vsftpd Konfiguration

Wird die konfigurierte Anzahl der fehlerhaften Anmeldeversuche - in unserem Beispiel 7 (+1) weil die Auswertung des Skripts immer einen Anmeldeversuch hinterher hinkt - erreicht, die sich idR noch mit der in der FTP-Server Konfiguration eingestellten Anzahl fehlerhaften Anmeldungen - in meiner vsftpd.conf sind das 3 - multipliziert, wird nach spätestens 24 fehlerhaften Logins für den Client der Zugang zu allen Diensten (ALL:) für die in der blockhosts.cfg konfigurierten Zeit (hier 12 Std.) untersagt. Es ist nicht sinnvoll eine längere Zeit einzustellen oder weniger FAIL LOGINs zu konfigurieren, da meiner Erfahrung nach Angriffe sehr schnell wieder aufgegeben werden, wenn solche Schutzmechanismen festgestellt werden und weiterhin noch immer noch genügend Kunden geblockt werden. Der Eintrag in der /etc/hosts.allow sieht bei einem geblockten Host wie folgt aus:

/etc/hosts.allow

ALL:   192.168.172.1 : deny
 
#bh: ip:   192.168.172.1 :   8 : 2010-04-25 02:29:46 CEST
 
#bh: logfile: /var/log/secure
#bh: offset: 0
#bh: first line:
 
#bh: logfile: /var/log/vsftpd.log
#bh: offset: 5423
#bh: first line:Sat Apr 24 21:42:16 2010 [pid 3363] CONNECT: Client "127.0.0.1"
 
#---- BlockHosts Additions
 
vsftpd: ALL: spawn (/usr/bin/blockhosts.py --verbose --echo "%c-%s" >> /var/log/blockhosts.log 2>&1 )& : allow

Der Login am Server sieht für den Angreifer dann wie folgt aus:

$ ftp 192.168.172.132
Connected to 192.168.172.132.
421 Service not available, remote server has closed connection.

Note: Testen Sie Ihre Konfiguration nicht auf der lokalen Maschine, weil der localhost in einer Whitelist steht und nicht vom BlockHosts Skript berücksichtigt wird!

false positive

Häufig genug kommt es vor, dass auch Kunden oder gar Mitarbeiter in der /etc/hosts.allow geparkt werden. Das bekommen Sie relativ rasch mit, wenn sich Support Anfragen in dieser Richtung häufen. Es reicht dann aus die beiden dazugehörigen Zeilen (hier mit # ← DELETE) aus der /etc/hosts.allow zu löschen:

/etc/hosts.allow

#---- BlockHosts Additions
ALL:   192.168.172.1 : deny # ← DELETE
 
#bh: ip:   192.168.172.1 :   8 : 2010-04-25 02:29:46 CEST # ← DELETE
 
#bh: logfile: /var/log/secure
#bh: offset: 0
#bh: first line:
 
#bh: logfile: /var/log/vsftpd.log
#bh: offset: 5423
#bh: first line:Sat Apr 24 21:42:16 2010 [pid 3363] CONNECT: Client "127.0.0.1"
 
#---- BlockHosts Additions
 
vsftpd: ALL: spawn (/usr/bin/blockhosts.py --verbose --echo "%c-%s" >> /var/log/blockhosts.log 2>&1 )& : allow

Sie können auch hergehen und bekannte Kunden mit zB fester IP Adresse direkt whitelisten, diese werden vom BlockHosts Skript dann ignoriert. Fügen Sie dazu in der Datei /etc/hosts.allow vor dem BlockHosts Abschnitte einfach die IP Adresse ($Customer_IP) nach folgenden Muster ein:

/etc/hosts.allow

$Customer_IP : allow
#---- BlockHosts Additions
#---- BlockHosts Additions

Probleme

Die deny-Anweisung für ALL:, was alle Services betrifft, kann uU von einem Angreifer missbraucht werden, um Sie selbst oder Ihr ganzes Unternehmen zu blockieren. Stellen Sie sich folgendes Szenario vor: Sie betreiben einen eigenen DNS-Server, der von den Clients Ihres Unternehmens zur Auflösung der Internet URL Anfragen verwendet wird. Auf diesen Server betreiben Sie zur Absicherung des SSH Zugangs das Blockhost Script, mit einer finalen ALL: IP: deny Regel. Der Angreifer könnte jetzt hergehen und Ihre öffentliche IP Adresse Ihres Unternehmens spoofen (d.h. Ihre IP Adresse als eigene Absender Adresse zu verwenden) und solange mit dieser IP Adresse Ihr BlockHost Skript auf den DNS-Server mit fehlgeschlagenen Anmeldeversuchen zu provozieren, bis seine (bzw. Ihre) IP-Adresse von Ihrem DNS-Server geblockt wird. Und mit der ALL: Anweisung für jeden Dienst, was auch DNS bedeutet. Das Ende der Aktion ist, dass Sie Ihr eigener DNS Server blockiert, was zur Folge hat, dass Sie das Internet nicht mehr benutzen können und für die konfigurierte Zeit auch nicht mehr per SSH auf den DNS Server kommen um, das Problem zu beseitigen. Sie werden aber vermutlich schon die Halbe Zeit mit der Fehlersuche verbringen. Die Lösung für dieses Szenario wäre in der Datei /etc/hosts.allow nur die Dienste zu blockieren, die angegriffen werden. Nur mal so im Hinterkopf behalten…

have fun and enjoy


Verwandte Artikel:
-> Server Zugangskontrolle: fail2ban
-> VSFTP Installation und Konfiguration
-> FTP Session automatisieren
-> E-Mail vs FTP

pronto 2010/04/25 02:33