Es gibt verschiedene Methoden wie man sich gegen einen SSH-Brute-Force-Angriff schützen kann. Hierzu zählen unter anderem die Python-Skripte DenyHosts und fail2ban, welche die Logdatei /var/log/auth.log nach fehlgeschlagenen Anmeldeversuchen durchsuchen und die IP-Adresse des Angreifers in die Datei /etc/hosts.deny eintragen beziehungsweise bei fail2ban eine Firewall-Regel erstellen um den Angreifer zu blockieren.
Eine andere Methode sich vor SSH-Brute-Force-Angriffen zu schützen bietet das iptables-Modul recent welches Bestandteil des Linux-Kernels ist und zur Laufzeit geladen wird. Damit können Verbindungsversuche von einer IP-Adresse zu einem bestimmten Service mitgezählt und beim Überschreiten einer gewissen Anzahl geblockt werden.
Weil das iptables-Modul recent auf der Paketebene arbeitet, kann es nicht zwischen erfolgreichen und fehlgeschlagenen Anmeldeversuchen unterscheiden. Dies kann eventuell zu einem Problem führen, wenn von einem System mehrere SSH-Sitzungen in einem kurzen Zeitraum aufgebaut werden. Das Problem lässt sich aber durch einen sorgfälltig gewählten Schwellwert vermeiden. Als Schwellwert wird die maximale Anzahl von Verbindungsversuchen in einem festgelegten Zeitintervall festgelegt.
Für die folgende Anleitung wird vorausgesetzt, dass Sie auf Ihrem Raspberry Pi das momentan aktuelle Raspbian Image vom 09.02.2013 (2013-02-09-wheezy-raspbian.zip) einsetzen und iptables bereits wie in der Anleitung Linux-Firewall iptables unter Raspbian konfigurieren beschrieben konfiguriert wurde.
Im folgenden Beispiel sollen innerhalb von zehn Minuten maximal fünf Verbindungsversuche zum SSH-Daemon zugelassen werden. Weiterhin soll eine sogenannte Whitelist angelegt werden, in welcher einzelne Clients oder ganze Netzbereiche eingetragen werden, welche dieser Beschränkung nicht unterliegen sollen.
Zuerst erstellen Sie für die SSH-Firewall-Regeln und die SSH-Whitelist jeweils eine eigene Firewall-Chain.
pi@raspberrypi ~ $ sudo iptables -N SSH-BruteForce
pi@raspberrypi ~ $ sudo iptables -N SSH-Whitelist
Die erste Regel welche wir der Firewall-Chain SSH-BruteForce hinzufügen, schreibt bei einem neuen Verbindungsaufbau mit dem TCP-Port 22 die IP-Adresse des Clients mit einem Zeitstempel in die Datei /proc/net/xt_recent/ssh.
pi@raspberrypi ~ $ sudo iptables -A SSH-BruteForce -p tcp --dport 22 -m state --state NEW -m recent --set --name ssh
Durch die zweite Regel wird die Whitelist eingebunden. Sollte dort eine Regel für die IP-Adresse des Clients existieren, wird diesem Zugang gewährt.
pi@raspberrypi ~ $ sudo iptables -A SSH-BruteForce -p tcp --dport 22 -m state --state NEW -j SSH-Whitelist
Wenn ein weiterer SSH-Verbindungsaufbau von einem Client eingeht, welcher nicht in der Whitelist aufgeführt ist, fügt die dritte Regel einen weiteren Zeitstempel in die Datei /proc/net/xt_recent/ssh ein (--update) und überprüft, ob die maximale Anzahl von Verbindungsversuchen (--hitcount) innerhalb des definierten Intervalls (--seconds) erreicht wurde. Sollte der Schwellwert erreicht worden sein, werden alle weiteren Pakete des Clients an den TCP-Port 22 ohne Rückmeldung verworfen.
pi@raspberrypi ~ $ sudo iptables -A SSH-BruteForce -p tcp --dport 22 -m state --state NEW -m recent --update --seconds 600 --hitcount 6 --rttl --name ssh -j DROP
Damit die Firewall-Chain SSH-BruteForce aktiv wird, müssen Sie diese in die Firewall-Chain INPUT einbinden. Beachten Sie hierbei bitte unbedingt die Reihenfolge der einzelnen Regeln. Sollte bereits eine vorhergehende Regel alle Pakete an den TCP-Port 22 erlauben, wird der gewünschte Effekt ausbleiben.
Wenn Sie einem Client den unbeschränkten Zugang auf den SSH-Server gewähren wollen, fügen Sie für diesen die folgende Regel in die Firewall-Chain SSH-Whitelist ein. Die IP-Adresse des Clients wird dabei mit dem Parameter -s angegeben.
pi@raspberrypi ~ $ sudo iptables -A SSH-Whitelist -s 192.168.10.189 -m recent --remove --name ssh -j ACCEPT
Soll ein ganzer Netzwerkbereich uneingeschränkt auf den SSH_Server zugreifen können, geben Sie anstelle der IP-Adresse den Adressbereich beim Parameter -s an.
pi@raspberrypi ~ $ sudo iptables -A SSH-Whitelist -s 192.168.10.0/24 -m recent --remove --name ssh -j ACCEPT
Nachdem Sie alle Firewall-Regeln konfiguriert haben, können Sie sich diese mit dem folgenden Befehl anzeigen lassen und nochmals überprüfen.
pi@raspberrypi ~ $ sudo iptables -L
Chain INPUT (policy DROP)
target prot opt source destination
SSH-BruteForce all -- anywhere anywhere
ACCEPT all -- anywhere anywhere
ACCEPT icmp -- anywhere anywhere
ACCEPT all -- anywhere anywhere state RELATED,ESTABLISHED
ACCEPT tcp -- anywhere anywhere state NEW tcp dpt:ssh
REJECT all -- anywhere anywhere reject-with icmp-host-prohibited
Chain FORWARD (policy ACCEPT)
target prot opt source destination
Chain OUTPUT (policy ACCEPT)
target prot opt source destination
Chain SSH-BruteForce (1 references)
target prot opt source destination
tcp -- anywhere anywhere tcp dpt:ssh state NEW recent: SET name: ssh side: source
SSH-Whitelist tcp -- anywhere anywhere tcp dpt:ssh state NEW
DROP tcp -- anywhere anywhere tcp dpt:ssh state NEW recent: UPDATE seconds: 600 hit_count: 6 TTL-Match name: ssh side: source
Chain SSH-Whitelist (1 references)
target prot opt source destination
ACCEPT all -- client.home.lan anywhere recent: REMOVE name: ssh side: source
Alles anzeigen
Die Einträge in der Datei /proc/net/xt_recent/ssh sehen wie folgt aus.
pi@raspberrypi ~ $ sudo cat /proc/net/xt_recent/ssh
src=192.168.10.52 ttl: 64 last_seen: 236562 oldest_pkt: 9 236494, 236498, 236498, 236558, 236558, 236558, 236558, 236562, 236562, 236098, 236098, 236110, 236110, 236110, 236110, 236110, 236110, 236110, 236110, 236494
Der folgende Befehl löscht die gesamte Liste mit den IP-Adressen und den gespeicherten Zeitstempeln.
Eine einzelne IP-Adresse und die dazugehörigen Zeitstempel löschen Sie wie folgt aus der Liste.
Bevor Sie mit dem nächsten Schritt fortfahren, sollten Sie sicherstellen, dass der Zugriff über SSH wie gewünscht funktioniert.
Damit die Firewall-Regeln bei einem Neustart des Systems oder des Netzwerkdienstes automatisch geladen werden, müssen Sie diese in die /etc/network/iptables speichern. Dazu rufen Sie einfach den folgenden Befehl auf.
Hinweis: Dieses und viele weitere Tutorials finden Sie auf meiner Webseite.