System absichern mit fail2ban, Blocklist und Abuse

Um einen Server abzusichern nutzen viele fail2ban.

Wir können jedoch die Sicherheitnoch ein wenig erhöhen, indem wir auf den Dienst blocklist.de zurückgreifen um z.B. Abuse Mails an die jeweiligen Provider senden zu lassen und regelmäßig IP Sperrlisten abzurufen.

Anhand der Sperrlisten kann die Firewall (iptables) bereits Angreifer abwehren bevor diese den jewiligen Dienst angreifen können.

Die fail2ban Konfiguration wird hier am Beispiel von SSH vorgenommen und sollte von euch auf eure Dienste angepasst werden.

Als erstes solltet ihr euch einen Account auf blocklist.de erstellen und eure Server anlegen.

Bitte beachtet die eMailadresse die ihr für eure Server hinterlegt, diese müsst ihr auch in den Konfigurationen auf den Servern angeben.

Installation von ssmtp

Nachdem wir über einen externen Mailserver versenden wollen, installieren wir ssmtp.

ssmtp ist ein kleiner MTA der sich um die authentifizierte weitergabe von Emails an einen externen Mailserver kümmert.

apt-get install ssmtp
nano /etc/ssmtp/ssmtp.conf
root=eMailadresse
mailhub=Domain des Mailservers
AuthUser=Benutzername der eMailadresse
AuthPass=Passwort der eMailadresse
hostname=Hostname des Servers von dem gesendet wird

Installation von fail2ban

apt-get install fail2ban

Zum Überwachen des SSH Dienstes erstellen wir folgende Datei:

nano /etc/fail2ban/jail.local

[DEFAULT]
destemail = [email protected]
sendermail = eMailadresse
action = %(action_mwl)s

[ssh]
enabled = true
port    = 22
filter  = sshd
logpath  = /var/log/auth.log
maxretry = 6

Jetzt restarten wir fail2ban um die neuen Konfigurationen zu übernehmen.

/etc/init.d/fail2ban restart

Blockliste(n) installieren

Als nächstes installieren wir ein Script, welches angesteuert über einen Cronjob, die aktuellen Blocklisten von blocklist.de herunterlädt und in die iptables schiebt.

Im oberen Teil des Scripts könnt Ihr anpassen welche Listen ihr alles laden möchtet.

Theoretisch könnt ihr auch blocklist.de fremde Listen einbinden insofern diese pro Zeile nur eine IP Adresse besitzen.

Beachtet bitte das TO_DOWNLOAD ein Array ist und die Zahl dahinter fortgeführt werden muss.

Als erstes kopieren wir folgendes Script nach

/sbin/blocklist.de-update.sh

#!/bin/bash
## Configuration
# Files which should be downloaded
TO_DOWNLOAD[0]="http://lists.blocklist.de/lists/all.txt"
#TO_DOWNLOAD[0]="http://lists.blocklist.de/lists/ssh.txt"
#TO_DOWNLOAD[1]="http://lists.blocklist.de/lists/mail.txt"
#TO_DOWNLOAD[2]="http://lists.blocklist.de/lists/apache.txt"
#TO_DOWNLOAD[3]="http://lists.blocklist.de/lists/imap.txt"
#TO_DOWNLOAD[4]="http://lists.blocklist.de/lists/ftp.txt"
#TO_DOWNLOAD[5]="http://lists.blocklist.de/lists/sip.txt"
#TO_DOWNLOAD[6]="http://lists.blocklist.de/lists/bots.txt"
#TO_DOWNLOAD[7]="http://lists.blocklist.de/lists/strongips.txt"
#TO_DOWNLOAD[8]="http://lists.blocklist.de/lists/ircbot.txt"
#TO_DOWNLOAD[9]="http://lists.blocklist.de/lists/bruteforcelogin.txt"

# Other settings; Edit if necesarry
CHAINNAME="blocklist-de"
ACTION="REJECT" # Can be DROP
PRINT_REPORT=1

########## Do not edit anything below this line ##########
## Needed variables
cmd_iptables=`which iptables`
cmd_touch=`which touch`
cmd_rm=`which rm`
cmd_wget=`which wget`
cmd_grep=`which grep`
cmd_wc=`which wc`
cmd_cat=`which cat`
cmd_sort=`which sort`
cmd_uniq=`which uniq`
started=`date`
version="1.0.0"
amountDownloaded=0
amountAfterSortAndUnique=0
amountInserted=0
amountDeleted=-1

fileUnfiltered="/tmp/blocklist-ips-unfiltered.txt"
fileFiltered="/tmp/blocklist-ips-filtered.txt"

$cmd_touch $fileUnfiltered
$cmd_touch $fileFiltered

## Download every file and concat to one file
for currentFile in "${TO_DOWNLOAD[@]}"
do
    $cmd_wget -qO - $currentFile >> $fileUnfiltered
done

## Sort and filter
$cmd_cat $fileUnfiltered | $cmd_sort | $cmd_uniq > $fileFiltered

amountDownloaded=`$cmd_cat $fileUnfiltered | $cmd_wc -l`
amountAfterSortAndUnique=`$cmd_cat $fileFiltered | $cmd_wc -l`

## Create chain if it does not exist
$cmd_iptables --new-chain $CHAINNAME >/dev/null 2>&1

# Insert rule (if necesarry) into INPUT chain so the chain above will also be used
if [ `$cmd_iptables -L INPUT | $cmd_grep $CHAINNAME | $cmd_wc -l` -eq 0 ]
then
    # Insert rule because it is not present
    $cmd_iptables -I INPUT -j $CHAINNAME
fi

## Insert all IPs from the downloaded list if there is no rule stored
while read currentIP
do
    # Check via command
    $cmd_iptables -C $CHAINNAME -s $currentIP -j $ACTION >/dev/null 2>&1

    # Now we have to check the exit code of iptables via $?
    # 0 = rule exists and don't has to be stored again
    # 1 = rule does not exist and has to be stored

    if [ $? -eq 1 ]
    then
        # Append the IP
        $cmd_iptables -A $CHAINNAME -s $currentIP -j $ACTION >/dev/null 2>&1

        # Increment the counter
        amountInserted=$((amountInserted + 1))
    fi
done < $fileFiltered

## Now we delete the IPs which are stored in iptables but not anymore in the list
while read currentIP
do
    # Check if the ip is in the downloaded list
    if [ `$cmd_cat $fileFiltered | $cmd_grep $currentIP | $cmd_wc -l` -eq 0 ]
    then
        # Delete the rule by its rulenumber
        # Because changing the action would result in errors
        $cmd_iptables -D $CHAINNAME -s $currentIP -j $ACTION >/dev/null 2>&1

        # Increment the counter
        amountDeleted=$((amountDeleted + 1))
    fi
done <<< "`$cmd_iptables -n -L blocklist-de | awk '{print $4}'`"

## Print report
if [ $PRINT_REPORT -eq 1 ]
then
    echo "--- Blockliste.de :: Update-Report"
    echo ""
    echo "Script Version:     $version"
    echo "Started:            $started"
    echo "Finished:           `date`"
    echo ""
    echo "--> Downloaded IPs: $amountDownloaded"
    echo "--> Unique IPs:     $amountAfterSortAndUnique"
    echo "--> Inserted:       $amountInserted"
    echo "--> Deleted:        $amountDeleted"
fi

## Cleanup
$cmd_rm -f $fileUnfiltered
$cmd_rm -f $fileFiltered</pre>

Das Script stammt im Original von veloc1ty und steht unter der Lizenz GPL v3.

und machen es ausführbar

chmod +x /sbin/blocklist.de-update.sh

Zum testen einmal per Hand ausführen und schauen ob eine Ausgabe kommt (Update-Report).

Falls alles gut durchgelaufen ist, setzen wir die Variable PRINT_REPORT auf 0 damit wir nicht ständig eMails erhalten und legen einen Cronjob dafür an:

crontab -e

0,20,40 * * * * /sbin/blocklist.de-update.sh

Ab jetzt solltet ihr ein wenig sicherer vor Angreifern sein.