SSH-Server auf dem Raspberry Pi absichern

Mit Raspbian Jessie geprüft.

Standardmäßig ist auf einer Linux-Distribution für den Raspberry Pi, wie zum Beispiel Raspbian, ein SSH-Server aktiv. Der ermöglicht es, dass man sich mit einem SSH-Client über das Netzwerk auf dem Raspberry Pi einloggt, ohne direkt mit Tastatur und Bildschirm am Raspberry Pi zu sitzen.

Dieser Remote-Zugriff ist standardmäßig relativ sicher. Wer seinen Raspberry Pi nur als Client im Netzwerk und auch nur gelegentlich betreibt, braucht sich keine weiteren Gedanken über die Sicherheit des SSH-Servers machen. Ganz anders sieht das aus, wenn der Raspberry Pi als Gateway oder Server dauerhaft läuft und beispielsweise per VPN, IPv6 oder anderweitig aus dem Internet direkt erreichbar ist. Spätestens dann sollte man sich über die sichere Betriebsweise des Raspberry Pi Gedanken machen. Zum Beispiel wie man den SSH-Server auf dem Raspberry Pi absichert.

Hinweis: In einem Heimnetz-Netzwerk ohne Port-Forwarding auf den Server hat man bei einem Root-Zugang eigentlich kein Sicherheitsproblem. Riskant wird es nur dann, wenn IPv6 eingeschaltet ist. Dann steht und fällt die Sicherheit mit einer gut konfigurierten Firewall auf dem Netzzugangsrouter.

Aufgabe

  1. Beurteilen Sie die folgenden Sicherheitsprobleme für Ihr Gesamtsystem.
  2. Setzen Sie dafür geeignete Maßnahmen um.

Vorbemerkung zu den folgenden Sicherheitsproblemen und Maßnahmen

  • Bei allen Lösungen in der IT-Security schwingt immer eine gewisse Paranoia mit. Der Grund ist, man weiß nie, was der Angreifer kann, welche Tools er benutzt und welche unbekannten Sicherheitslücken das System hat.
  • Grundsätzlich ist es gestattet, die Sinnhaftigkeit und Nützlichkeit aller Lösungen zu hinterfragen.
  • Bei jeder Einschränkung des SSH-Logins geht auch ein Komfortverlust einher. Das kann soweit gehen, dass man sich in einem Notfall den Zugriff mühsam "erkämpfen" muss.
  • Es gibt keinen festen Weg ein System "sicher" zu machen. Wenn es den gäbe, dann wäre das überall voreingestellt.
  • Die folgenden Teile dieser Anleitung bzw. die einzelnen Lösungen bauen "nicht" aufeinander auf. Die Reihenfolge richtet sich nicht zwangsläufig nach "wichtig" und "dringend". Alle Maßnahmen machen ein System sicherer. Manche davon mehr oder weniger wirkungsvoll. Je mehr Hürden ein Login aufweist, desto sicherer.
  • Die beschriebenen Lösungen gehen davon aus, dass die Linux-Distribution Raspbian verwendet wird und dass der Nutzer per "sudo" Root-Rechte erlangen kann. Prinzipiell funktionieren die Lösungen auch mit anderen Distributionen.

Übersicht: Sicherheitsprobleme und mögliche Maßnahmen

  • Sicherheit des Gesamtsystems
    • Server-Betrieb
  • Remote-Zugriff
    • Grundlegende Einstellungen
    • SSH-Zugriff für einen bestimmten Benutzer sperren oder freigeben
    • Speziellen Benutzer für den SSH-Zugriff erstellen
    • SSH-Zugriff für eine bestimmte Benutzer-Gruppe freigeben
    • Berechtigung für "sudo" einschränken
  • Standard-Port
    • Standard-Port ändern
  • Angreifer im lokalen Netzwerk
    • IP-Binding
    • Benutzer bei mehreren fehlerhaften Authentifizierungen sperren
  • Passwort-Zugang abschalten

Sicherheit des Gesamtsystems

Man muss zwischen der Sicherheit des Gesamtsystems und der Sicherheit des SSH-Servers unterscheiden. Bevor wir an den Einstellungen des SSH-Servers herumschrauben, ist die Betrachtung des Gesamtsystems notwendig. Einen SSH-Server zu "härten" ist sinnlos, wenn das Gesamtsystem Sicherheitslücken und -mängel aufweist. Beispielsweise Standard-Benutzer und -Passwörter. Sicherheitsschwächen des Gesamtsystems können jegliche Sicherheitsmaßnahmen bei SSH aufheben.
Sicherheit muss man immer als Gesamtkonzept sehen. Unabhängig davon welche Sicherheitsmaßnahmen für SSH sinnvoll sind, muss man immer auch die Sicherheit des Gesamtsystems berücksichtigen. Grundsätzlich sollte man dort anfangen.

Vorbereitung: Backup von der SSH-Konfigurationsdatei

Bevor wir loslegen erstellen wir eine Kopie der SSH-Konfigurationsdatei. Wenn irgendetwas schief geht, können wir jederzeit zur ursprünglichen Konfiguration zurückkehren.

sudo cp /etc/ssh/sshd_config /etc/ssh/sshd_config_backup

Sicherheitsproblem: Remote-Zugriff

Generell ist die Möglichkeit des Remote-Zugriffs übers Netzwerk immer ein Problem. Er erlaubt den Zugriff auf ein System, ohne räumliche Nähe. Prinzipiell ist das komfortabel, wenn man aus der Ferne an Systeme kommen kann. Unter Umständen ist die Entfernung zu weit, um zeitnah an das System zu kommen. Der Zugang zu wichtigen Systemen ist in der Regel auch organisatorisch und räumlich beschränkt. Manchmal ist ein physikalischer Zugriff nur mit viel Aufwand möglich. Wenn aber der Remote-Zugriff Schwachstellen aufweist, dann kann ein Angreifer ganz bequem aus der Ferne auf das System zugreifen.
Unter Umständen stellt der Remote-Zugriff ein Sicherheitsproblem dar. Besonders der Zugriff per SSH über das Internet ist keine gute Idee.

Der Remote-Zugriff per SSH ist praktisch. Keine Frage. Doch ist er wirklich notwendig? Oder anders gefragt, ist es der Komfort eines Remote-Zugriffs wert, dafür ein hohes Maß an Sicherheit aufzugeben. In der Regel wird man diese Frage leichtfertig mit "Ja" beantworten, obwohl unter strenger Auslegung von Sicherheitsvorschriften ein "Nein" richtig wäre.
Ohne die Analyse der Gefahren und damit verbundenen Risiken lässt sich diese Frage nicht so leicht beantworten. Deshalb noch ein mal die Frage: Ist ein wirklich Remote-Zugriff notwendig? Würde der Zugriff per Bildschirm und Tastatur vor Ort nicht ausreichen?

Lösung: SSH-Server (temporär) abschalten

Ist ein Remote-Zugriff per SSH überhaupt notwendig? Wenn die Antwort "Nein" ist, dann kann man die Sicherheit des Raspberry Pi mit einem Schlag drastisch erhöhen. Durch das Abschalten UND eventuell Deinstallieren des SSH-Servers. Denn dann kommt man von außen nicht mehr drauf. Der Angreifer ist gezwungen lokal an die Maschine zu kommen, was den Aufwand eines Angriffs deutlich erhöht. In der Regel lässt sich der Zugang von unbefugten Personen organisatorisch ausschließen.

sudo insserv -r ssh
sudo apt-get remove ssh

Sicherer ist nur noch, wenn der Server nicht mehr am Netz hängt. Aber das ist bei einem Server nicht vorgesehen.

Wenn man auf den Komfort eines Remote-Zugriffs nicht verzichten will, der aber nicht dauernd verfügbar sein muss, dann kann man diesen temporär ein- und ausschalten. Beispielsweise in dem der SSH-Server installiert und sicher konfiguriert bleibt. Aber nur temporär für den Remote-Zugriff eingeschaltet wird. Beispielsweise per Schlüsselschalter, der vor Ort betätigt werden muss. Oder durch die Befehlseingabe vor Ort per Bildschirm und Tastatur.

sudo service ssh start
sudo service ssh stop

Sicherheitsproblem: Root-Zugriff per SSH

Man kann sagen, dass wenn ein Angreifer erst einmal bis dahin gekommen ist, wo er einen Anmeldeversuche mit "root" durchführen kann, dann ist es eigentlich schon zu spät. Im Prinzip hat man dann vorher schon etwas falsch gemacht und hat ein richtiges Sicherheitsproblem.
Und aus diesem Grund, wenn vorhergehende Sicherheitsmaßnahmen nicht greifen, dann ist es eine Hürde für den Angreifer, wenn der Zugang per "root" nicht möglich ist.

Standardmäßig ist in der Linux-Distribution Raspbian für den Benutzer "root" kein Passwort gesetzt und typischerweise deshalb auch kein Login per SSH möglich. Allerdings könnte doch mal irgendjemand ein Passwort für "root" setzen. Dann sollte der Zugang für den Benutzer "root" nicht per SSH möglich sein.

Lösung: Grundlegende Einstellungen

Es gibt ein paar grundlegende Einstellungen in der SSH-Konfigurationsdatei, die per Default gesetzt sein sollten. Zur Sicherheit sollte man das prüfen.

sudo nano /etc/ssh/sshd_config

Folgende Einstellung legt das SSH-Protokoll auf die Version 2 fest. Version 1 gilt als veraltet und unsicher und existiert nur noch aus Kompatibilitätsgründen.

Protocol 2

Jedes System hat Standard-Benutzer für die kein Passwort festgelegt ist. Für diese Benutzer sollte kein Zugriff per SSH möglich sein. Folgende Einstellung erlaubt keinen Zugriff für Benutzer, die kein Passwort aufweisen.

PermitEmptyPasswords no

Nach mehrheitlicher Meinung sollte der Root-Zugang per SSH unmöglich sein. Der Administrator sollte sich immer als normaler User einloggen und sich erst dann bedarfsweise die Rechte von "root" verschaffen.

PermitRootLogin no

Damit die Änderung in dieser Datei übernommen werden, muss die Datei gespeichert und anschließend der Dienst oder der Raspberry Pi neugestartet werden.

sudo service ssh restart

Ist man per SSH mit dem Raspberry Pi verbunden beeinflusst das die Verbindung nicht. Das heißt, die SSH-Verbindung wird dabei nicht beendet.

Hinweis: Für alle weiteren Einstellungen gehen wir davon aus, dass diese in der Datei "/etc/ssh/sshd_config" erfolgen und im Anschluss zur Übernahme der Einstellungen ein Neustart des SSH-Servers notwendig ist.

Lösung: SSH-Zugriff für einen bestimmten Benutzer sperren oder freigeben

Wenn man einen bestimmten Nutzer von der Nutzung des SSH-Servers ausnehmen will, dann kann man ihn direkt mit seinem Benutzernamen sperren.

DisallowUsers {USERNAME}

Eine bessere Idee ist, den SSH-Zugang nur auf einen bestimmten Benutzer zu beschränken. Zum Beispiel auf "pi".
In der Konfigurationsdatei trägt man hierfür folgendes ein:

AllowUsers pi

Mit dieser Einstellung ist es allen anderen Usern nicht mehr möglich sich per SSH einzuloggen.

Lösung: Speziellen Benutzer für den SSH-Zugriff erstellen

Es ist eine sinnvolle Maßnahme, den SSH-Zugriff auf einen bestimmten Benutzer zu beschränken. Man kann sogar noch einen Schritt weiter gehen und einen Benutzer erstellen, der nur dem SSH-Zugriff dient. Es kann sich also nachher nur noch dieser Benutzer per SSH anmelden.

Erst erstellen wir einen neuen Benutzer:

sudo adduser sshuser

und folgen den Anweisungen.

Dann muss man diesen Benutzer noch in die Konfigurationsdatei eintragen.

sudo nano /etc/ssh/sshd_config

Hier trägt man folgende Zeile ein:

AllowUsers sshuser

Dadurch beschränkt man den SSH-Zugriff auf den Benutzer "sshuser". Standardmäßig ist es diesem Benutzer möglich per "sudo" Root-Rechte zu erlangen.

Lösung: SSH-Zugriff für eine bestimmte Benutzer-Gruppe freigeben

Die Lösung, den SSH-Zugriff auf einen bestimmten Benutzer zu beschränken, ist sicherlich eine gute Lösung. Was aber, wenn man später weitere Nutzer hinzufügen möchte. Dann ist jedes mal ein Reboot oder Restart notwendig. Das möchte man bei einem Server eigentlich vermeiden. Deshalb löst man das einmalig über die Linux-Benutzersteuerung. Hier legt man eine Benutzer-Gruppe "ssh" oder ähnlich an. Weist dieser Gruppe die entsprechenden Benutzer zu und gibt diese Benutzer-Gruppe in der SSH-Server-Konfiguration frei.

Zuerst legen wir eine neue Benutzer-Gruppe mit dem Namen "ssh" an.

sudo groupadd -r ssh

Dann weisen wir den Benutzer "pi" der Benutzer-Gruppe "ssh" zu.

sudo gpasswd -a pi ssh

Anschließend tragen wir in der Datei "/etc/ssh/sshd_config" die Erlaubnis für die Gruppe "ssh" ein.

AllowGroups ssh

An der Stelle muss man darauf achten, dass man die Erlaubnis einzelner Benutzer per "AllowUsers" entfernt, damit die Berechtigung ausschließlich über die Zuweisung der Benutzer zu der Benutzer-Gruppe "ssh" auch wirklich funktioniert.

Anschließend kann man jederzeit auch ohne Reboot Nutzern die Erlaubnis geben per SSH auf den Raspberry Pi zuzugreifen und auch wieder zu entfernen.

Freigeben:

sudo gpasswd -a {USER} ssh

Entfernen:

sudo gpasswd -d {USER} ssh

Lösung: Berechtigung für "sudo" einschränken

Streng genommen ist die Beschränkung des SSH-Zugangs auf einen Benutzer, der "sudo" ohne Passwort von "root" ausführen darf, nicht wirklich sicher. Bei einem Raspbian ist es so, dass der Standard-Benutzer "pi" jederzeit Root-Rechte per "sudo" erhalten kann. Und das ohne Eingabe des Root-Passworts. Man sollte darüber nachdenken, ob es vielleicht Sinn macht, dieser Konstellation einen Riegel vorzuschieben. Sicherer ist es, wenn der Angreifer zwei Passwörter braucht. Einmal das des Benutzers und dann noch das Passwort von "root".

Sicherheitsproblem: Standard-Port

Wenn ein Angreifer per SSH auf einen Host zugreifen möchte, verwendet er dafür den Standard-Port 22. Dabei nutzt er automatische Programme, mit denen er das Internet nach potentiellen Zielen absucht, die auf Port 22 hören. Hat einer ein Ziel gefunden, das antwortet, versucht er sich beispielsweise mit Standard-Benutzernamen und -Passwörtern anzumelden. Oder er versucht es gleich mit einer Brute-Force-Attacke. Irgendwann findet er vielleicht das richtige Passwort heraus.

Besser wäre es also, wenn der SSH-Server nicht auf den Standard-Port 22 hört, sondern auf einen anderen Port zwischen 1.024 und 65.535.

Die Änderung des Standard-Ports ist aber keine echte Sicherheitsmaßnahme, sondern nur ein Verstecken bzw. Verschleiern, was unter dem Begriff "Security by Obscuritiy" fällt. Das einzige, was man damit verhindert, dass der SSH-Server mit einfältigen Angreifern und systematisch suchenden Programmen nicht behellig wird. Denn auch fehlschlagende Authentifizierungsversuche binden Ressourcen in Form von Rechenleistung und Speicherplatz.
In der Regel prüfen diese Art von Angreifer nicht alle Ports, ob dort vielleicht irgendwo ein SSH-Server lauscht. Die meisten gehen zum nächsten Angriffsziel über.

Mit dem Ändern des Standard-Ports verhindert man höchstens, dass unbedarfte Script-Kiddies weitere Angriffsversuche unternehmen. Jemand, der sich wirklich Zugang verschaffen will, den hält man damit nicht auf.

Die Änderung des Standard-Ports geht immer mit einem Komfort-Verlust einher. Der ist unter Umständen größer als der Sicherheitsgewinn. Ein Remote-Zugriff ist ja trotzdem möglich. Aber nur auf einem anderen Port. Als Administrator muss man dann immer mit der Einschränkung kämpfen, weil man die abweichende Portnummer bei der Adressierung explizit angeben muss.
In der Praxis ist eine abweichende Portnummer immer ein Ärgernis. Es gibt gute Gründe für Standard-Ports. Man sollte daran nichts ändern, wenn es nicht wirklich einen Grund dafür gibt. Der Komfort-Verlust wiegt den Sicherheitsgewinn nicht immer auf.
Das einzige, was es wirklich bringt, weniger Last auf dem System und weniger Einträge in den Logfiles.

Lösung: Standart-Port ändern

Um den Standard-Port zu ändern, muss ein Eintrag in der SSH-Konfigurationsdatei geändert werden.

sudo nano /etc/ssh/sshd_config

Hier schaut man nach der folgenden Zeile:

Port 22

Die Zahl "22" ist die Portnummer, die man in eine beliebig andere Portnummer zwischen 1.024 und 65.535 ändert. Wichtig ist nur, dass man sich die Portnummer merkt, weil man die in Zukunft beim Verbindungsaufbau angeben muss.

Port 10101

Nach dem Speichern und Schließen ist ein Restart des SSH-Servers oder des Raspberry Pi notwendig.

Ab dann muss die Portnummer bei der Verbindungsaufnahme mit angegeben werden, weil der SSH-Client von der Standard-Portnummer ausgeht.

ssh username@myhostnaname.com -p 10101

Hinweis: Das Ändern des Standart-Ports verhindert keine Angriffe. Es reduziert nur Zugriffe von Bots, die sich automatisiert anmelden wollen. Wenn der SSH-Server auf Port 22 nicht antwortet, ziehen Angreifer meistens einfach weiter. Ein Angreifer, der es Ernst meint, der wird sich davon jedoch nicht abhalten lassen einfach alle Ports auf Zugriffsmöglichkeiten zu prüfen. Er wird sehr schnell feststellen auf welchem Port der SSH-Server hört, wenn einer aktiv ist.

Sicherheitsproblem: Angreifer im lokalen Netzwerk

Wenn es der Angreifer irgendwie ins lokale Netzwerk geschafft hat, dann hat man wirklich ein Problem. Denn dann sind alle Hosts in Gefahr, auf die man sich nicht direkt aus dem Internet verbinden kann.

Lösung: IP-Binding

Es gibt mehrere Möglichkeiten, um sich gegen Angreifer aus dem eigenen Netz abzusichern. Eine davon, sofern man bei der Authentifizierung mit Benutzername und Passwort arbeiten will ist, die Verbindung nur von einer bestimmten IP-Adresse zuzulassen.

ListenAddress 192.168.1.5
ListenAddress fe80::5

Man muss nur sicherstellen, dass der Angreifer nicht herausbekommt, um welche Adressen es sich handelt, weil er sonst versuchen wird, einen Client im lokalen Netz zu installieren, der diese Adressen aufweist.

Lösung: Benutzer bei mehreren fehlerhaften Authentifizierungen sperren

Wenn eine IP-Adresse innerhalb einer bestimmten Zeit mehrere fehlgeschlagene Verbindungen initiiert hat, dann riecht das stark nach einem Angriff. Vielleicht sogar automatisiert durch einen Bot, der das Passwort durch automatisiertes Durchprobieren erraten soll. Die beste Lösung dafür wäre eine Public-Key-Lösung. Nur möchte oder kann das nicht immer umsetzen.
Alternativ bestünde die Möglichkeit den Angreifer bei mehrmaligen fehlerhaften Authentifizierungen zu sperren.

MaxStartups 10:30:60

Diese Einstellung besteht aus drei durch einen Doppelpunkt voneinander getrennten Zahlen (start:rate:full).

"start" ist die Anzahl der Verbindungen, die wegen einer fehlerhaften Authentifizierung fehlgeschlagen sind. Dann werden die Verbindungen mit einer Wahrscheinlichkeit von "rate" in Prozent abgewiesen. Ab einer Anzahl von "rate" fehlgeschlagener Authentifizierungen wird jeder weitere Verbindungsversuch abgewiesen.
Welche Werte machen Sinn? Bei "start" muss man sich die Frage stellen, wie viele Anmeldeversuche ein menschlicher Benutzer wohl unternimmt, bis ihm klar ist, dass er das richtige Passwort nicht weiß. Damit ist weniger ein Angreifer gemeint, sondern eher ein normaler Nutzer, der das Passwort vergessen hat oder sich nicht mehr sicher ist und nach mehreren Fehlversuchen vielleicht doch den Systemadministrator anruft. Sagen wir 10 mal. Das ist ein guter Wert.
Bei "rate" geht es darum, die Verbindungsmöglichkeit nach mehrmals fehlgeschlagenen Anmeldungen einzuschränken. Eine sofortige vollständige Sperrung ist schwer umzusetzen, weil man die nach einer gewissen Zeit sowieso wieder aufheben muss. Anstatt hier einen Timer zu setzen, arbeitet man hier mit einer hohen Wahrscheinlichkeit von Verbindungsabbrüchen. Bei einer Wahrscheinlichkeit von 30% klappt nur noch ungefähr jeder dritte Verbindungsversuch. Für einen menschlichen Benutzer sicherlich akzeptabel, wenn ihm doch noch das Passwort irgendwann einfällt. Für einen Angreifer eine nervtötende Angelegenheit. Für einen Bot eine zusätzliche zeitliche Verzögerung beim automatisierten Passwortraten.
Bei "full" geht es darum, die Verbindungsmöglichkeit vollständig zu unterbinden. Besonders interessant bei Bots, die automatisiert Passwörter erraten wollen. Nach "60" fehlgeschlagenen Anmeldeversuchen würde der Bot ausgeschlossen. Sicherlich ein akzeptabler Wert, den man auch noch tiefer ansetzen kann.
Wenn man "start" beispielsweise schon nach 2 fehlgeschlagenen Anmeldeversuchen die Verbindungsversuche abbrechen lässt, dann sollte man "rate" höher wählen.
Außerdem muss man einem menschlichen Benutzer gerade bei komplizierten Passwörtern die Möglichkeit geben sein Passwort mehrmals ohne Beschränkung einzugeben. Sonst sinkt die Akzeptanz für eine solche Sicherheitsmaßnahme.

Secure Secure Shell

Eine gute Quelle, um die Secure Shell weiter abzusichern:

Weitere verwandte Themen:

Frag Elektronik-Kompendium.de

Elektronik-Set Raspberry Pi Edition
Elektronik-Set Raspberry Pi Edition

Elektronik erleben mit dem Raspberry Pi mit Python und GPIO Zero

  • Leichter Einstieg ins Hardware-nahe Programmieren mit Python und GPIO Zero
  • Experimentieren und Programmieren ohne Vorkenntnisse
  • Sofort Loslegen mit All-in-one-Set

Elektronik-Set jetzt bestellen

Elektronik-Fibel

Elektronik einfach und leicht verständlich

Die Elektronik-Fibel ist ein Buch über die Grundlagen der Elektronik, Bauelemente, Schaltungstechnik und Digitaltechnik.

Das will ich haben!