Absicherung des SSH-Zugangs

User „root“ deaktivieren

Standardmäßig ist es dem privilegierten Benutzer root erlaubt, sich über SSH anzumelden. Da dies die Standardeinstellung ist, liegt es nahe, dass Bruteforce-Angriffe auf den SSH-Zugang auch gerne mit diesem Benutzernamen durchgeführt werden. Ein Blick in das Server-Log (bei Ubuntu ist dies /var/log/auth.log) zeigt, dass fast alle fehlgeschlagenen Logins auf root zielen. Es liegt also nahe, einen nicht privilegierten Benutzer einzurichten und dem Benutzer root die Möglichkeit zur Anmeldung zu entziehen.

Um einem Benutzer die Möglichkeit zu geben, administrative Aufgaben, die sonst root vorbehalten sind, durchzuführen, fügt man ihn der Gruppe sudo hinzu. Das sudo Kommando ist bei Ubuntu 16.04 LTS schon so eingestellt, dass es allen Benutzern dieser Gruppe die Ausführung aller Befehle mit root Rechten erlaubt. Warum die Nutzung von sudo sinnvoll ist, behandeln andere Sites ausgiebig. Allerdings ist es dazu notwendig, die von den betreffenden Benutzern ausführbaren Befehle feingranularer zu definieren. Da hier allerdings der root Benutzer „ersetzt“ werden soll, ist ein weiteres Einschränken der Rechte nicht sinnvoll. Generell kann man sudo aber zur Erhöhung der Sicherheit einsetzen, wenn man Benutzern nur die Kommandos erlaubt, die sie zur Ausübung ihrer Tätigkeit brauchen (principle of least privilege).

Einen neuen Benutzer <user> samt Home-Verzeichnis, der bash als Shell legt man einfach wie folgt an und fügt ihn der sudo Gruppe hinzu:

$ useradd -m -s /bin/bash -p <password> <user>
$ usermod -aG sudo <user>

Die Einrichtung des Benutzers ist nun abgeschlossen und ein Probe-Login über SSH empfehlenswert. Kann man sich erfolgreich mit dem angelegten Benutzer einloggen, testet folgendes, ob sudo funktioniert:

$ sudo whoami
root

Jetzt kann das Login für den root Benutzer deaktiviert werden. Dazu ändert man in /etc/ssh/sshd_config folgende Zeile:

PermitRootLogin no

Nach dem Neustart von sshd ist die Änderung aktiv:

$ systemctl restart sshd

Rate Limiting

Die Absicherung des SSH-Zugangs ist eine reine iptables Lösung. Pro IP ist nur eine SSH-Verbindung pro Minute erlaubt, in der bis zu drei Login-Versuche getätigt werden können. Um hartnäckiges Ausprobieren von Passwörtern im Minutentakt zu unterbinden, sind pro Tag nicht mehr als 30 SSH-Verbindungen erlaubt. Die Inspiration dazu lieferte Heise mit einem Artikel zum Thema.

Zuerst muss man sshd so einstellen, dass es nach drei Login-Versuchen die Verbindung trennt. Das geschieht in der Konfigurationdatei /etc/ssh/sshd_config durch Hinzufügen/Ändern des MaxAuthTries Parameters:

MaxAuthTries 3

Die restlichen Anforderungen lassen sich mit iptables wie folgt lösen. Das Netzwerkinterface auf dem Server ens3 ist, bitte bei Bedarf anpassen:

  # IPv4
$ iptables -A INPUT -p tcp --dport 22 -i ens3 -m state --state NEW         -m recent --name v4-ssh-min --set
$ iptables -A INPUT -p tcp --dport 22 -i ens3 -m state --state NEW         -m recent --name v4-ssh-day --set
$ iptables -A INPUT -p tcp --dport 22 -i ens3 -m state --state ESTABLISHED -m recent --name v4-ssh-min --update --seconds 60    --hitcount 2  -j REJECT --reject-with tcp-reset
$ iptables -A INPUT -p tcp --dport 22 -i ens3 -m state --state ESTABLISHED -m recent --name v4-ssh-day --update --seconds 86400 --hitcount 31 -j REJECT --reject-with tcp-reset

  # IPv6
$ ip6tables -A INPUT -p tcp --dport 22 -i ens3 -m state --state NEW         -m recent --name v6-ssh-min --set
$ ip6tables -A INPUT -p tcp --dport 22 -i ens3 -m state --state NEW         -m recent --name v6-ssh-day --set
$ ip6tables -A INPUT -p tcp --dport 22 -i ens3 -m state --state ESTABLISHED -m recent --name v6-ssh-min --update --seconds 60    --hitcount 2 -j REJECT --reject-with tcp-reset
$ ip6tables -A INPUT -p tcp --dport 22 -i ens3 -m state --state ESTABLISHED -m recent --name v6-ssh-day --update --seconds 86400 --hitcount 31 -j REJECT --reject-with tcp-reset

Die ersten beiden Regeln schreiben mit der Option –set die IP-Adresse einer neuen Verbindung auf Port 22 nebst Zeitstempel in die Proc-Dateien /proc/net/xt_recent/[v4|v6]-ssh-[min|day]. Die dritte und die vierte Regel fügt mit –update einen weiteren Zeitstempel ein und prüft, ob zwei Zeitstempel innerhalb der letzten 60 Sekunden liegen bzw. innerhalb der letzten 86400 Sekunden (= 1 Tag). Ist dies der Fall, wird die Verbindung zurückgesetzt. Erst nach Ablauf einer Minute ist wieder eine Verbindung zum SSH-Server und drei weitere Login-Versuche möglich. Die vierte Regel limitiert analog dazu die Anzahl der Verbindungen auf 30 pro Tag.

Die Kombination von NEW und ESTABLISHED verringert die Gefahr von Spoofing-Angriffen, bei denen ein Spaßvogel mit gefälschten IP-Absender-Adresse die Recent-Liste füllt und somit unter Umständen legitime Adressen darin landen und die Firewall sie blockiert. Anzumerken ist allerdings auch, dass bestehende Verbindungen getrennt werden, wenn man den Schutz auslöst. Das lässt sich leider auch nicht so leicht lösen, da der ESTABLISHED Status einer Verbindung Teil des Schutzmechanismus‘ ist.

Um Herauszufinden, was das recent Modul „weiß“, gibt  es einige einfache Möglichkeiten zur Abfrage des Status. Welche Adresse die Firewall wie oft gesehen hat, lässt sich mit …

$ cat /proc/net/xt_recent/[v4|v6]-ssh-[min|day]

… abfragen. Die gesamte Liste lässt sich mit…

$ echo clear > proc/net/xt_recent/[v4|v6]-ssh-[min|day]

löschen. Einzelne Adressen kann man wie folgt löschen vor (bitte das Minus vor der IP-Adresse beachten):

$ echo -IPv4-Adresse > proc/net/xt_recent/v4-ssh-[min|day]
$ echo -IPv6-Adresse > proc/net/xt_recent/v6-ssh-[min|day]

 

Schreibe einen Kommentar