Verhindern von Brute Force Attacks 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 ein Tool, Login-Versuche in verschiedenen Systeme wie z.B. SSH, FTP, etc. überwacht. Wenn es fehlsgeschlagene Login-Versuche aufspürt, die immer wieder bei ein und derselben IP Adresse oder dem selben Host auftreten, stoppt BlockHosts weitere Login-Versuche dieser IP Adresse/Hosts. Standardmäßig unterstützt BlockHosts Dienste, die TCP_WRAPPERS verwenden, wie zum Beispiel SSH, das heißt Dienste, die /etc/hosts.allow oder /etc/hosts.deny verwenden, es blockiert aber auch andere Dienste mit iproute oder iptables.

Diese Anleitung ist ohne jegliche Gewähr! Ich übernehme keine Garantie, dass dies auch bei Dir funktioniert!

1 Vorbemerkung

Ich habe BlockHosts auf einem Debian Etch System getestet.

Ich werde zeigen, wie man BlockHosts mit einem Dienst verwendet, der /etc/hosts.allow oder /etc/hosts.deny (sshd) nutzt und mit einem Dienst, der keine TCP_WRAPPERS verwendet, z.B. Debians ProFTPd Paket. Dienste, die /etc/hosts.allow oder /etc/hosts.deny nicht verwenden, können von iproute oder iptables blockiert werden.

Ich gehe davon aus, dass OpenSSH und ProFTPd auf Deinem System richtig installiert sind und gut funktionieren.

2 Installation von BlockHosts

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

apt-get install python

Danach laden wir BlockHosts runter und installieren es 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 HOSTS_BLOCKFILE we können wir entweder /etc/hosts.allow oder /etc/hosts.deny festlegen. Es ist egal, welches wir wählen. Ich verwende hier /etc/hosts.allow. In der LOGFILES Zeile bestimmen wir die Login-Dateien, die sich BlockHosts ansehen soll. OpenSSH loggt fehlgeschlagenen Login-Versuche auf /var/log/auth.log, ProFTPd auf /var/log/proftpd/proftpd.log. COUNT_THRESHOLD bestimmt die Anzahl fehlgeschlagener Login-Versuche des gleichen Hosts nach der BlockHosts diesen Host blocken sollte. AGE_THRESHOLD ist die Anzahl der Stunden, nach denen geblockte Hosts nicht mehr geblockt werden. IPBLOCK legt fest, ob Du Hosts mit iptables oder iproute blocken möchtest, zusätzlich datzu, dass diese Hosts /etc/hosts.allow (oder /etc/hosts.deny) hinzugefügt werden.

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

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

Leere dann /etc/hosts.allow und füge etwas in der Art 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 # -------------------------------------------------------------------------
In den ersten Bereich fügst Du Hosts ein, die auf die Whitelist sollen (z.B. 127.0.0.1). Wenn das ganze 192.168.0 Subnezt auf die Whitelist soll, aktiviere diese Zeile.

Dann müssen wir diese Marker hinzufügen - BlockHosts wird geblockte Hosts dazwischen 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

Wenn nun jemand versucht, sicht mit SSH einzuloggen, startet /usr/bin/blockhosts.py, überprüft die Log-Dateien, die wir in /etc/blockhosts.cfg festgelegt haben und blockt alle Hosts mit mehr als COUNT_THRESHOLD fehlgeschlagenen Login-Versuchen indem es sie /etc/hosts.allow hinzufügt und indem es iptables (die diese Hosts vollkommen vom Zugriff auf Dein System blockieren) verwendet. Alle Vorgänge werden in /var/log/blockhosts.log geschrieben.

Nun müssen wir BlockHosts initialisieren. Zuerst nehmen wir das mit der --dry-run Option vor, um herauszufinden, ob 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 (abgesehen vom IPv6 Fehler, den Du ignorieren kannst), also können wir es mit der --dry-run Option ausführen:

blockhosts.py --verbose

Dies sollte wie folgt 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 bereit, fehlgeschlagene SSH Logins aufzuspüren, jedoch nicht fehlgeschlagene ProFTPd Logins, da Debians ProFTPd /etc/hosts.allow und /etc/hosts.deny nicht überprüft, was bedeutet, dass BlockHosts nicht aufgerufen wird, wenn jemand versucht sich in ProFTPd (wenn jemand COUNT_THRESHOLD oder mehr fehlgeschlagene Login-Versuche in ProFTPD hat und dann versucht sich in OpenSSH einzuloggen, wird er natürlich geblockt, da OpenSSH /etc/hosts.allow verwendet, was dann BlockHosts aufruft und die fehlgeschlagenen Login-Versuche in ProFTPd gefunden werden; wenn aber jemand versucht, sich nur in ProFTPd einzuloggen, können wir ihn mit dem derzeitigen Setup nicht aufspüren) einzuloggen. Um nicht-TCP_WRAPPERS Dienste zu blocken, werden wir einen Cron Job anlegen, der BlockHosts alle fünf Minuten startet (zum Beispiel).

3 Einen BlockHosts Cron Job für Nicht-TCP_WRAPPERS Dienste einrichten

Um Hosts von nicht-TCP_WRAPPERS Diensten wie Debians ProFTPd zu blocken, kannst Du Folgends in der Kommandozeile ausführen

blockhosts.py --iptables --verbose

Natürlich möchtest Du das nicht alle paar Minuten tun, daher legen wir einen Cron Job an.

Zuerst erstellen wir ein keines Wrapper Skript 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
Der Zweck dieses Wrapper Skripts ist, den richtigen PATH an das /usr/bin/blockhosts.py Skript weiter zu leiten; wenn wir /usr/bin/blockhosts.py direkt im Cron Job verwenden, erhalten wir Fehlermeldungen, 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 Test

Nun kannst Du versuchen, Dich auf Deinem Server mittels SSH und FTP einzuloggen, unter Verwendung eines falschen Benutzernamens/Passwortes. Nach einiger Zeit solltest Du nicht mehr in der Lage sein, Dich mit Deinem Server in Verbindung zu setzen, was bedeutet, dass Du beblockt wurdest. Ändere die IP Adresse Deines Clients und melde Dich wieder in der Kommandozeile Deines Servers an.

Führe dies aus

iptables -L

In der Ausgabe siehst Du, 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 /etc/hosts.allow an. Die gleichen IP Adressen sollten dem #---- BlockHosts Additions Bereich 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 [...]
Letztendlich kannst Du Dir noch /var/log/blockhosts.log ansehen:

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

0 Kommentar(e)

Zum Posten von Kommentaren bitte