SSH Zugang mit Keyfiles absichern

OpenSSH oder kurz SSH ist das Tool der Wahl wenn es um den Fernzugriff und die Administration von Servern geht. Dazu wählt man sich mit der Kommandozeile des Client Rechners auf dem Server ein und kann dann auf dessen Kommandozeile arbeiten als ob man lokal vor dem Server sitzen würde. Da keine grafische Oberfläche übertragen wird, reagiert die Ausgabe des Servers auf dem Client quasi ohne Verzögerung und man kann flüssig arbeiten auch wenn der Server physisch sehr weit weg steht.

Auf dem Server läuft der SSH Daemon "sshd" der auf Port 22 auf Anfragen lauscht. Auf dem Client muss nur das Kommando in der Form

ssh Diese E-Mail-Adresse ist vor Spambots geschützt! Zur Anzeige muss JavaScript eingeschaltet sein.

eingegeben werden. Der Benutzer muss natürlich auf dem Server existieren. Der Server fragt jetzt das Passwort des Benutzers ab und schon arbeitet man auf dem Server.

Über diesen Zugang erhält der legitime Benutzer auf dem Server Benutzerrechte bis zur Rootebene (sofern er die passende Berechtigung dazu hat). Da sollte man sich natürlich entsprechende Gedanken zum Thema Sicherheit machen, denn ehe man sich versieht ist der Server gekapert und dient der dunklen Seite des Netzes.

Der Transportweg wird bei SSH automatisch verschlüsselt. Passworte werden also nicht im Klartext übertragen. Dennoch sollte ein entsprechend langes und komplexes Passwort gewählt werden.

Es gibt jedoch einen besseren Weg zur Authentifizierung am Server. Mit dem Public Key Verfahren erhält der Server den öffentlichen Schlüssel und der Client, der sich anmelden möchte, muss den passenden privaten Schlüssel besitzen. Ohne diese Schlüsseldatei akzeptiert der Server die Anmeldung nicht.

Die Einrichtung ist schnell und einfach. Allerdings muss man ein wenig aufpassen. Wenn man leichtsinnig wird und ungeprüft den Server auf Public Key umschaltet, kann man sich aussperren.

Diese Anleitung bezieht sich auf macOS 10.12.5 (Sierra) und Ubuntu 17.04 auf den Client Rechnern und Debian 8 bzw. Ubuntu 16.04 LTS auf den Servern. Funktioniert aber (getestet) auch mit neueren Versionen.

 

Schlüsselpaar auf dem Client generieren

Im Terminal wird mit dem Kommando ssh-keygen -b 4096 ein 4096 Bit RSA Schlüsselpaar erstellt. Der Speicherort des Schlüsselpaares und ein Passwort um den privaten Schlüssel zu schützen wird abgefragt. Als Speicherort ist der Ordner .ssh im persönlichen Homeverzeichnis (also ~/.ssh/) eine gute Wahl. Ich gebe den Schlüsseldateien Namen mit denen ich sie dem entsprechenden Server zuordnen kann.

Man kann die Passphrase für den privaten Schlüssel leer lassen. Das ermöglicht eine passwortfreie Anmeldung am Server. Es bedeutet aber auch, dass ein Angreifer, der die Schlüsseldatei abfischt Zugang zum Server hat.

Los geht's:

Client:~ reinhard$ ssh-keygen -b 4096
Generating public/private rsa key pair.
Enter file in which to save the key (/Users/reinhard/.ssh/id_rsa): /Users/reinhard/.ssh/testserver_rsa
Enter passphrase (empty for no passphrase):
Enter same passphrase again:
Your identification has been saved in /Users/reinhard/.ssh/testserver_rsa.
Your public key has been saved in /Users/reinhard/.ssh/testserver_rsa.pub.
The key fingerprint is:
SHA256:OpkF7pdsiIdtUPwvXgwPkKfHYyhzSkhZw0w8NrlclXk Diese E-Mail-Adresse ist vor Spambots geschützt! Zur Anzeige muss JavaScript eingeschaltet sein.
The key's randomart image is:
+---[RSA 4096]----+
| =+. ..o |
| oOo..o E |
| oo =* .. |
| . .oo O |
| . = = S |
| . @ X O |
| + @ * = |
| o = o |
| . |
+----[SHA256]-----+
Client:~ reinhard$

Die Dateien testserver_rsa (privater Schlüssel) und testserver_rsa.pub (öffentlicher Schlüssel) liegen nun im Verzeichnis ~/.ssh/

Client:~ reinhard$ ls .ssh
known_hosts known_hosts.old testserver_rsa testserver_rsa.pub

 

Öffentlichen Schlüssel auf Server übertragen

Der Server speichert alle öffentlichen Schlüssel in der Datei ~/.ssh/authorized_keys. Jeder Benutzer auf dem Server führt eine eigene authorized_keys Datei. Dadurch wird eine eindeutige Zuordnung zwischen privatem Schlüssel und Benutzer auf dem Server erreicht. Soll auf dem Server ein neuer öffentlicher Schlüssel installiert werden, so wird dieser einfach an authorized_keys angehangen. Um den Inhalt der Schlüsseldatei in authorized_keys einzutragen gibt es ein Kommando. Auf dem Client wird folgender Befehl ausgeführt:

Client:~ reinhard$ ssh-copy-id -i .ssh/testserver_rsa.pub admin@testserver
admin@testservers's password:
Now try logging into the machine, with "ssh 'admin@testserver'", and check in:

~/.ssh/authorized_keys

to make sure we haven't added extra keys that you weren't expecting.

Der Server verlangt das Passwort für die SSH Anmeldung und fügt dann den angegeben öffentlichen Schlüssel in authorized_keys ein.

 

WICHTIG: Zugang testen!

Jetzt muss die Anmeldung per Public Key Verfahren unbedingt geprüft werden denn im nächsten Schritt wird die Anmeldung per Passwort deaktiviert. Sollte es ein Problem mit den Schlüsseldateien geben, hat man sich danach vom Server ausgesperrt. Die Anmeldung mit der Schlüsseldatei testet man mit

Client:~ reinhard$ ssh -i .ssh/testserver_rsa admin@testserver

Wenn der private Schlüssel mit einem Passwort gesichert ist, wird dieses jetzt abgefragt ansonsten erfolgt direkt die Anmeldung am Server.

 

Den Server auf Public Key umstellen

Auf dem Server wird nun mit root Rechten die Datei /etc/ssh/sshd_config bearbeitet. Dabei wird die Zeile

PasswordAuthentication yes

in

PasswordAuthentication no

geändert.

Dadurch ist nur noch eine Anmeldung mit dem Public Key Verfahren möglich. Bei der Gelegenheit kann man noch generell die Anmeldung als Root verbieten indem man weiter oben in der sshd_config Datei die Zeile

PermitRootLogin yes

auf

PermitRootLogin no

ändert.

sshd_config speichern und den Editor beenden.

Jetzt muss nur noch mit service sshd reload die neue Konfiguration geladen werden. Fertig!

 

Anmeldung

Mein Clientrechner mit Ubuntu 17.04 meldet sich nach Eingabe von ssh admin@testserver sofort per Public Key an. Der ssh_agent (quasi die SSH Schlüsselverwaltung) sucht automatisch den passenden privaten Schlüssel zum öffentlichen Schlüssel des Servers.

Apple hat jedoch in macOS 10.12 das Verhalten des ssh_agent geändert. Dieser sucht nicht mehr automatisch nach passenden Schlüsseldateien. Deshalb muss man sich unter macOS mit ssh -i .ssh/testserver_rsa admin@testserver anmelden. Es gibt aber noch eine andere Möglichkeit. Im Ordner ~/.ssh/ legt man die Datei config mit folgendem Inhalt an:

#Konfiguration für Testserver
Host testserver
HostName testserver.rdnet.local
User admin
IdentityFile /Users/reinhard/.ssh/testserver_rsa

Nach dem Speichern ändert man die Zugriffsrechte mit

chmod 600 config

Dadurch kann nur der Eigentümer die Datei lesen bzw. bearbeiten.

Nun kann man sich mit dem einfachen Befehl ssh testserver anmelden. Folgende Parameter werden in der config Datei definiert:

1 #Konfiguration für Testserver Kommentar
2 Host testserver Der Name, der im ssh Befehl als Platzhalter genutzt wird
3 HostName testserver.rdnet.local Name oder IP Adresse des Servers mit dem die Verbingung hergestellt wird
4 User admin Als welcher Nutzer möchte man sich auf dem Server anmelden
5 IdentityFile /Users/reinhard/.ssh/testserver_rsa Der private Schlüssel der zur Anmeldung genutzt wird

Übrigens: Unter Ubuntu kann man die Config Datei ebenfalls im .ssh Verzeichnis anlegen um die Anmeldung am Server zu vereinfachen.

 

Noteingang

Nachdem der Server jetzt nur noch Anmeldungen mit einem Keyfile akzeptiert, bauen wir mal ein hypothetisches Horrorszenario. Es gibt kein Backup des privaten Schlüssels und der Clientrechner wird vom Blitz getroffen. Die Schlüsseldatei ist unwiderruflich zerstört. Und nun? Wie kann man sich denn jetzt noch auf dem Server anmelden? Einfache Antwort: gar nicht!

Deshalb müssen zum Einen die privaten Schlüssel gesichert werden und zum Anderen kann man sich auf dem Server einen Noteingang einrichten. Der Noteingang ist ein einzelner Nutzer, der adminstrative Rechte auf dem Server hat (also Befehle als root ausführen darf) und der sich als einziger Nutzer per Passwort an SSH anmeden darf.

Auf dem Server wird der Nutzer "noteingang" mit

sudo adduser noteingang --no-create-home

angelegt und ein Passwort für den Nutzer wird festgelegt. Da der Nutzer "noteingang" kein eigenes Homeverzeichnis braucht wird mit dem Parameter --no-create-home die Erstellung des Verzeichnisses unterbunden.

Als Nächstes erhält "noteingang" Rootrechte. Dies geschieht durch

sudo usermod -aG sudo noteingang

Der Nutzer "noteingang" wird der Gruppe "sudo" hinzugefügt.

Nun wird wieder mit Rootrechten die Datei /etc/ssh/sshd_config bearbeitet. Am Ende der Datei werden folgende Zeilen eingefügt

# Noteingang per Passwort
Match User noteingang
     PasswordAuthentication yes

Achtung! Die Zeile "PasswordAuthentication yes" muss mit einem Tabstopp eingerückt werden! Bin gerade darüber gestolpert und sshd wollte die neue Konfiguration nicht laden.

Die Datei speichern und den Editor beenden.

Mit service sshd reload die neue Konfiguration von SSH laden. Ab jetzt kann man sich mit ssh noteingang@testserver und dem richtigen Passwort am Server auch ohne die Schlüsseldatei anmelden.

Für den Noteingang benutze ich keinen logischen Usernamen. Ich lasse mir von einem Passwortgenerator eine zufällige lange Zeichenkette ausgeben und diese ist der Nutzername. Ebenso wird natürlich ein langes Passwort generiert. Der Noteingang ist definitiv eine Angriffsfläche um per Bruteforce Attacke Zugriff auf den Server zu erhalten. Durch zwei lange, zufällige Zeichenketten maximiere ich dabei die Rechenzeit für die Attacke.