Verhindern von Brute Force Attacken mit BlockHosts auf Debian Etch

Version 1.0
Author: Falko Timme


Diese Anleitung veranschaulicht, wie man BlockHosts auf einem Debian Etch System installiert und konfiguriert. BlockHosts ist eine in Python geschriebene Anwendung, die Login-Versuche auf verschiedene Dienste wie z.B. SSH, FTP, etc. überwacht. Wenn das Programm mehrere fehlgeschlagene Login-Versuche der gleichen IP Adresse oder des gleichen Hosts aufspürt, stoppt es weitere Login-Versuche dieser IP Adresse/dieses Hosts. BlockHosts unterstützt standardmäßig Dienste die TCP_WRAPPERS verwenden, wie zum Beispiel SSH, das heißt Dienste, die /etc/hosts.allow oder /etc/hosts.deny verwenden, es kann aber auch andere Dienste blocken, die iproute oder iptables verwenden.

Ich kann aber nicht garantieren, dass diese Lösung bei jedem funktioniert bzw. für jeden die richtige ist!

1 Vorbemerkung

Ich habe BlockHosts auf einem Debian Etch System getestet.

Ich werde Dir zeigen, wie Du es zum Einen mit einem Dienst anwendest, der /etc/hosts.allow or /etc/hosts.deny (sshd) verwendet und zum Anderen mit einem Dienst, der TCP_WRAPPERS nicht verwendet, z.B. Debian's ProFTPd Paket. Dienste, die /etc/hosts.allow oder /etc/hosts.deny nicht verwenden, können durch iproute oder iptables geblockt werden.

Ich setze voraus, dass OpenSSH und ProFTPd beide richitg installiert sind und auf Deinem System funktionieren.

2 Installation von BlockHosts

Da BlockHosts in Python geschrieben wurde, müssen wir Python jetzt installieren:

apt-get install python

Danach laden und installieren wie BlockHosts wie folgt:

cd /tmp
wget http://www.aczoom.com/tools/blockhosts/BlockHosts-2.0.5.tar.gz
tar xvfz BlockHosts-2.0.5.tar.gz
cd BlockHosts-2.0.5

python setup.py install --force

Nun müssen wir /etc/blockhosts.cfg bearbeiten. Bearbeite es wie folgt:

vi /etc/blockhosts.cfg
[...]
HOSTS_BLOCKFILE = "/etc/hosts.allow" [...] HOST_BLOCKLINE = ["ALL: ", " : deny"] [...] LOGFILES = [ "/var/log/auth.log", "/var/log/proftpd/proftpd.log", ] [...] COUNT_THRESHOLD = 3 [...] AGE_THRESHOLD = 12 [...] MAIL = True [...] NOTIFY_ADDRESS = 'root@localhost.localdomain' [...] SMTP_SERVER = "localhost" SENDER_ADDRESS = 'BlockHosts <blockhosts-do-not-reply@localhost.localdomain>' [...] IPBLOCK = "iptables" [...]
In der Zeile HOSTS_BLOCKFILE können wir entweder /etc/hosts.allow oder /etc/hosts.deny festlegen. Es ist egal, welches von beiden wir auswählen. Ich verwende /etc/hosts.allow . In der LOGFILES Zeile legen wir die Log-Dateien fest, die sich BlockHosts ansehen soll. OpenSSH speichert fehlgeschlagene Logins in der Datei /var/log/auth.log, ProFTPd in der Datei /var/log/proftpd/proftpd.log. COUNT_THRESHOLD gibt die Anzahl der fehlgeschlagenen Logins an, nachdem der Login gesperrt werden soll. AGE_THRESHOLD ist die Anzahl der Stunden, nach denen die Blockade aufgehoben werden soll. IPBLOCK gibt an, ob Du die Hosts auch mit iptables oder iproute blocken möchtest. Standardmäßig erfolgt das Blocking über /etc/hosts.allow (oder /etc/hosts.deny).

Als Nächstes müssen wir /etc/hosts.allow bearbeiten. Sichere zunächst /etc/hosts.allow:

cp /etc/hosts.allow /etc/hosts.allow_orig

Leere dann /etc/hosts.allow und gib etwas in derart ein:

cat /dev/null > /etc/hosts.allow
vi /etc/hosts.allow
#
# hosts.allow This file describes the names of the hosts which are # allowed to use the local INET services, as decided # by the '/usr/sbin/tcpd' server. # # ---- # see "man 5 hosts_access" for details of the format of IP addresses, #services, allow/deny options. Also see "man hosts_options" # # permanent whitelist addresses - this should always be allowed access ALL: 127.0.0.1 : allow # ALL: 192.168.0. : allow # permanent blacklist addresses - this should always be denied access # ALL: 10. : deny # ---------------------------------------- # next section is the blockhosts section - it will add/delete entries in # between the two marker lines (#---- BlockHosts Additions) #---- BlockHosts Additions #---- BlockHosts Additions # ---------------------------------------- # finally, the command to execute the blockhosts script, based on # connection to particular service or services: sshd: ALL: spawn /usr/bin/blockhosts.py --verbose --mail --iptables --echo "%c-%s" --check-ip "%h" >> /var/log/blockhosts.log 2>&1 & : allow #--- # add --iproute to enable null-routing, or add --iptables to enable packet # filtering, which blocks all network communication from blocked hosts #--- # remove >> /var/log/blockhosts.log 2>&1 if no logging to blockhosts.log # is needed - without this, it will still log to syslog (minimally) #sshd: ALL: spawn /usr/bin/blockhosts.py --verbose --echo "%c-%s" & : allow #--- # above commands will use default config file - /etc/blockhosts.cfg, edit # it as needed to specify local configuration options # See "man hosts.allow" for info on %c and %s identifiers # for non-verbose, with identification, to syslog only (/var/log/messages), # triggered on any service (using ALL as first word): #ALL: ALL: spawn /usr/bin/blockhosts.py --echo "%c-%s" & : allow #---- # To test hosts.allow, and to find out exact names of SSH/FTP services, # add this line to the beginning of hosts.allow, use ssh/ftp to connect # to your server, and then look at the log (/var/log/messages or # blockhosts.log) to see the name of the invoked service. # IMPORTANT: after your test is done, remove this line from hosts.allow! # Otherwise everyone will always have access. #ALL : ALL: spawn (/usr/bin/blockhosts.py --verbose --echo "%c-%s" >> /var/log/blockhosts.log 2>&1 )& : allow # -------------------------------------------------------------------------
Schreibe die Hosts, die in die Whitelist sollen, in die erste Sektion (In the first section you put hosts that you want to whitelist (e.g. 127.0.0.1). Wenn das gesamte 192.168.0 Subnet in die Whitelist soll, dann entferne die Raute am Anfang der Zeile.

Dann müssen wir diese Markierungen hinzufügen - BlockHosts wird geblockte Hosts zwischen ihnen einfügen:

#---- BlockHosts Additions
#---- BlockHosts Additions

Der wichtigste Teil ist dieser:

sshd: ALL: spawn /usr/bin/blockhosts.py --verbose --mail --iptables
--echo "%c-%s" --check-ip "%h" >> /var/log/blockhosts.log 2>&1 &
: allow

Wann immer jemand sicht mit SSH einzologgen versucht, wird usr/bin/blockhosts.py gestartet. Es überprüft die Log-Dateien, die wir in /etc/blockhosts.cfg festgelegt haben und blockiert alle Hosts, die mehr fehlgeschlagene Loginversuche haben, als wir als Limit eingestellt haben (COUNT_THRESHOLD) indem wir sie zu /etc/hosts.allow hinzufügen und wir iptables (welche diese Hosts völlig blockieren) verwenden. Alle Aktionen werden in dieser Datei aufgezeichnet /var/log/blockhosts.log.

Nun müssen wir BlockHosts initialisieren. Zuerst tun wir dies mit der --dry-run Option um zu sehen, ob auch keine Fehler auftreten:

blockhosts.py --dry-run --verbose

Die Ausgabe könnte wie folgt aussehen:

server2:/var/log# blockhosts.py --dry-run --verbose
blockhosts 2.0.5 started: 2007-09-05 16:31:10 CEST
... load blockfile: /etc/hosts.allow
... found both markers, count of hosts being watched: 0
no logoffsets found, will read from beginning in logfile: /var/log/auth.log
... loading log file, offset: /var/log/auth.log 0
no logoffsets found, will read from beginning in logfile: /var/log/proftpd/proftpd.log
... loading log file, offset: /var/log/proftpd/proftpd.log 0
... will discard all host entries older than 2007-09-05 04:31:10 CEST
... updates: counts: hosts to block: 0; hosts being watched: 0
#---- BlockHosts Additions
#bh: logfile: /var/log/auth.log
#bh: offset: 2643
#bh: first line:Jun 28 20:35:51 server2 login[2087]: (pam_unix) session opened for user root by (uid=0)

#bh: logfile: /var/log/proftpd/proftpd.log
#bh: offset: 1308
#bh: first line:Sep 05 16:04:34 server2.example.com proftpd[2355] server2.example.com: error setting IPV6_V6ONLY: Protocol not available

#---- BlockHosts Additions

# ----------------------------------------
# finally, the command to execute the blockhosts script, based on
# connection to particular service or services:

sshd, proftpd, vsftpd: ALL: spawn /usr/bin/blockhosts.py --verbose --mail
--echo "%c-%s" --check-ip "%h" >> /var/log/blockhosts.log 2>&1 &
: allow

#---
# add --iproute to enable null-routing, or add --iptables to enable packet
# filtering, which blocks all network communication from blocked hosts
#---
# remove >> /var/log/blockhosts.log 2>&1 if no logging to blockhosts.log
# is needed - without this, it will still log to syslog (minimally)
#sshd: ALL: spawn /usr/bin/blockhosts.py --verbose --echo "%c-%s" & : allow
#---
# above commands will use default config file - /etc/blockhosts.cfg, edit
# it as needed to specify local configuration options

# See "man hosts.allow" for info on %c and %s identifiers

# for non-verbose, with identification, to syslog only (/var/log/messages),
# triggered on any service (using ALL as first word):
#ALL: ALL: spawn /usr/bin/blockhosts.py --echo "%c-%s" & : allow
#----
# To test hosts.allow, and to find out exact names of SSH/FTP services,
# add this line to the beginning of hosts.allow, use ssh/ftp to connect
# to your server, and then look at the log (/var/log/messages or
# blockhosts.log) to see the name of the invoked service.
# IMPORTANT: after your test is done, remove this line from hosts.allow!
# Otherwise everyone will always have access.
#ALL : ALL: spawn (/usr/bin/blockhosts.py --verbose --echo "%c-%s" >> /var/log/blockhosts.log 2>&1 )& : allow

# -------------------------------------------------------------------------
Commands (tentative) to run for ip null-route blocking:
... no email to send.
server2:/var/log#

Sieht gut aus (vom IPv6 Error mal abgesehen, den Du ignorieren kannst), also können wir es ohne der --dry-run Option laufen lassen:

blockhosts.py --verbose

Dies sollte so aussehen:

server2:/var/log# blockhosts.py --verbose
blockhosts 2.0.5 started: 2007-09-05 16:33:24 CEST
... load blockfile: /etc/hosts.allow
... found both markers, count of hosts being watched: 0
... loading log file, offset: /var/log/auth.log 2643
... loading log file, offset: /var/log/proftpd/proftpd.log 1308
... will discard all host entries older than 2007-09-05 04:33:24 CEST
... updates: counts: hosts to block: 0; hosts being watched: 0
... created user-defined chain blockhosts
... creating jump from INPUT to blockhosts chain
... no email to send.
server2:/var/log#

BlockHosts ist nun konfiguriert um SSH Logins zu überwachen. Da ProFTPd nicht die Dateien /etc/hosts.allow und /etc/hosts.deny beachtet, müssen wir einen cron job anlegen, der BlockHosts alle 5 Minuten startet.

3 Einen BlockHosts Cron Job für Non-TCP_WRAPPERS Dienste erstellen

Um Hosts von non-TCP_WRAPPERS Diensten wie zum Beispiel Debian's ProFTPd zu blocken, kannst Du Folgendes in der Kommandozeile laufen lassen

blockhosts.py --iptables --verbose

Natürlich möchtst Du das nicht alle 5 Minuten machen, daher erstellen wir einen cron job.

Zuerst erstellen wir ein kleines Wrapper Script für /usr/bin/blockhosts.py:

vi /usr/local/sbin/blockhosts
#!/bin/bash
PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin /usr/bin/blockhosts.py --iptables --verbose >> /var/log/blockhosts.log 2>&1
Das Wrapper Script übergibt den richtigen PATH an das /usr/bin/blockhosts.py Script; wenn wir /usr/bin/blockhosts.py direkt im cron job verwenden, werden wir Fehlermeldungen erhalten, die uns mitteilen, dass iptables nicht gefunden werden konnte.

Natürlich müssen wir /usr/local/sbin/blockhosts ausführbar machen:

chmod 700 /usr/local/sbin/blockhosts

Dann erstellen wir einen cron job wie folgt:

crontab -e
*/5 * * * *  /usr/local/sbin/blockhosts &> /dev/null

4 Testen

Nun kannst Du versuchen Dich auf Deinem Server einzuloggen indem Du SSH und FTP mit falschem Nutzernamen/Passwort verwendest. Nach einiger Zeit müsstest Du Dich überhaupt nicht mehr einloggen können, was bedeutet, dass Du geblockt wurdest. Ändere die IP Adresse Deines Klienten und logge Dich wieder in der Kommandozeile des Servers ein.

Lass Folgendes laufen

iptables -L

In der Ausgabe kannst Du sehen, welche IP Adressen geblockt wurden:

server2:~# iptables -L
Chain INPUT (policy ACCEPT)
target prot opt source destination
blockhosts 0 -- anywhere anywhere

Chain FORWARD (policy ACCEPT)
target prot opt source destination

Chain OUTPUT (policy ACCEPT)
target prot opt source destination

Chain blockhosts (1 references)
target prot opt source destination
DROP 0 -- 192.168.0.93 anywhere
DROP 0 -- 192.168.0.92 anywhere
DROP 0 -- 192.168.0.91 anywhere
DROP 0 -- 192.168.0.94 anywhere
server2:~#

Sieh Dir mal /etc/hosts.allow an. Die gleiche IP Adresse sollte in der #---- BlockHosts Additions Sektion aufgelistet sein:

vi /etc/hosts.allow
[...]
#---- BlockHosts Additions ALL: 192.168.0.94 : deny ALL: 192.168.0.91 : deny ALL: 192.168.0.92 : deny ALL: 192.168.0.93 : deny #bh: ip: 192.168.0.94 : 4 : 2007-09-05 16:59:47 CEST #bh: ip: 192.168.0.91 : 4 : 2007-09-05 16:49:50 CEST #bh: ip: 192.168.0.92 : 8 : 2007-09-05 16:40:23 CEST #bh: ip: 192.168.0.93 : 4 : 2007-09-05 16:35:48 CEST #bh: logfile: /var/log/auth.log #bh: offset: 4563 #bh: first line:Jun 28 20:35:51 server2 login[2087]: (pam_unix) session opened for user root by (uid=0) #bh: logfile: /var/log/proftpd/proftpd.log #bh: offset: 15020 #bh: first line:Sep 05 16:04:34 server2.example.com proftpd[2355] server2.example.com: error setting IPV6_V6ONLY: Protocol not available #---- BlockHosts Additions [...]
Schließlich kannst Du Dir ebenfalls dies ansehen /var/log/blockhosts.log:

tail /var/log/blockhosts.log

[...]
blockhosts 2.0.5 started: 2007-09-05 16:52:25 CEST
... echo tag: ::ffff:192.168.0.94-sshd@::ffff:192.168.0.101
... load blockfile: /etc/hosts.allow
... found both markers, count of hosts being watched: 3
... loading log file, offset: /var/log/auth.log 4018
... loading log file, offset: /var/log/proftpd/proftpd.log 12305
... will discard all host entries older than 2007-09-05 04:52:25 CEST
... updates: counts: hosts to block: 3; hosts being watched: 3
... no email to send.

5 Links

2 Kommentar(e)

Zum Posten von Kommentaren bitte

Kommentare

Von: hahni

Mit Ubuntu 6.0.6 LTS funktioniert es leider nicht, obwohl die Pfade und auch der Rest relativ ähnlich sind. Im Thread "http://www.howtoforge.de/forum/showthread.php?goto=newpost&t=404" habe ich meine Probleme einmal etwas genauer beschrieben. Aber leider noch immer keine Lösung darauf!


Von: hahni

das problem scheint gelöst, seitdem ich das phyton 2.4-dev-paket auch installiert habe!

es treten nun keine fehlermeldungen mehr auf, allerdings werden keine hosts geblockt! im /var/log/blockhosts.log ist nix zu erkennen, woran es liegen könnte.

oder blockt ispconfig von haus aus weitere zugriffe über iptables?