OpenSSH ist sehr flexibel in der Konfiguration von Authentifizierungsmethoden. Man kann Authentifizierungsmethoden

  • miteinander kombinieren (`AuthenticationMethods`) oder
  • in Abhängigkeit von Nutzer*innen (`match user`) oder Gruppen (`match group`) festlegen.

Schlüsselbasierte Authentifizierung

Insbesondere Linux-Systemadrministratoren sollten statt Passwörter `sshkeys` als Authentifizierungsmethode verwenden. Hierbei ist zu beachten, dass die Schlüssel auf jeden Fall mit einem Passwort versehen werden müssen, um sie vor Missbrauch zu schützen.

# file: /etc/ssh/sshd_config
PubkeyAuthentication yes
IgnoreRhosts yes
HostbasedAuthentication no
ChallengeResponseAuthentication no
PasswordAuthentication no
PermitEmptyPasswords no
AuthenticationMethods publickey

Erstellen von SSH Schlüsseln

Der*die Nutzer*in erstellt sich auf dem _Client_ ein SSH Schlüsselpaar (privater und öffentlicher Schlüssel) mit `ssh-keygen`. Windows-Benutzer*innen können die Software `putty` verwenden.

# RSA key
ssh-keygen -t rsa -b 4096 -C '<user name>' -f ~/.ssh/id_rsa
    
# ed25519 key
ssh-keygen -t ed25519 -C '<user name>' -f ~/.ssh/id_ed25519

Exkurs: Extrahieren von SSH Schlüsseln aus X.509 Zertifikaten

SSH Schlüssel können auch aus X.509 Zertifikaten extrahiert werden. Dies ist besonders vorteilhaft, wenn man Kryptotoken (eToken, Nitrokey, u.a.) verwendet, da diese eine Schnittstelle bereitstellen, über die das Zertifikat direkt als privater Schlüssel verwendet werden kann.

Um ein X.509 Zertifikat in ein SSH Schlüssel umzuwandeln, wird zuerst der private Schlüssel extrahiert, um anschließend aus diesem den öffentliche Schlüssel zu generieren.

Achtung: Die folgenden Befehle sollten nur in einer vertrauenswürdigen Umgebung ausgeführt werden, da der private Schlüssel des X.509 Zertifikats entschlüsselt wird, was potentiell zu Verlust der privaten Informationen führen kann.

1. Extrahieren des privaten Schlüssels. Dies sollte in einem Schritt erfolgen, um den SSH Schlüssel direkt zu verschlüsseln.

openssl pkcs12 -in cert.p12 -nodes -nocerts | 
        (sleep 5; openssl rsa -aes256 
            -in /proc/self/fd/0 
            -out ~/.ssh/id_cert && chmod 600 ~/.ssh/id_cert)

2. Generieren des öffentlichen Schlüssels

ssh-keygen -y -f ~/.ssh/id_cert >> ~/.ssh/id_cert.pub

Übertragen des öffentlichen Schlüssels und Login

Der öffentliche Schlüssel (`id_*.pub`) muss danach auf den Server übertragen werden. Erlaubt der Server noch remote access via Passwort, so geht das einfach mit `ssh-copy-id`. Ansonsten muss der öffentliche Schlüssel anders auf den Server kopiert werden (bspw. per E-Mail oder USB-Stick).

ssh-copy-id -i ~/.ssh/id_rsa <user>@<host>

Beim ersten Login wird der Client eine Meldung geben, dass der Host unbekannt ist oder der Schlüssel geändert wurde. Der angezeigte Schlüssel sollte geprüft werden. Serverseitig kann der Fingerprint folgendermaßen angezeigt werden:

# RSA key
ssh-keygen -lf /etc/ssh/ssh_host_rsa_key.pub

# ed25519 key
ssh-keygen -lf /etc/ssh/ssh_host_ed25519_key.pub

2-Faktor-Authentifizierung

2FA mit SSH-Schlüssel und Passwort

Bei manchen Systemen kann es notwendig sein, eine stärkere Authentifizierungsmethode zu verwenden. Eine Kombination aus SSH-Schlüsseln und Passwörtern geht einfach durch Hinzufügen komma-separierter Authentifizierungsmethoden zu der Option `AuthenticationMethods`.

# file: /etc/ssh/sshd_config
match group sudo
    PubkeyAuthentication yes
    PasswordAuthentication yes
    AuthenticationMethods publickey,password

Hinweis: Es wird empfohlen, die Match-Blöcke an das Ende der sshd_config zu schreiben. Einerseits liegt das am Geltungsbereich der match-Blöcke (alle Zeilen zwischen dem Match-Block und einem nachfolgenden Match-Block oder dem Ende der Datei - je nachdem was zuerst eintritt). Andererseits lassen sich durch diese Schreibweise die "globalen" von den spezifischen Einstellungen trennen. Dies erleichtert Ausnahmeregelungen und allgemein hin das Verständnis.

Exkurs: 2FA mit OTP und Passwort

One-Time-Passwords (OTPs) sind einmal gültige Passwörter, die basierend auf einem gemeinsamen Geheimnis (OTP Schlüssel) und einem Ereignis (Zähler oder Zeit) auf dem Server und einem Token (Software oder Hardware) unabhängig voneinander berechnet werden. Nur der Inhaber des gemeinsamen Geheimnisses kann das OTP berechnen.

Unterstützung in Linux für OTP gibt es mittels PAM-Modul. Als OTP Token bietet sich eine Smartphone APP an. Wir empfehlen den `FreeOTP Authenticator` (Android Version, iOS Version) oder den `Aegis Authenticator` (Android).

Hinweis: Auch Google bietet mit dem Google Authenticator und `libpam-google-authenticator` Open Source Lösungen für Multi-Faktor-Authentifizierung an. Man sollte diese Tools nur einsetzen, wenn man einen Verlust der privaten Informationen ausschliessen kann.

Auf dem Server ist das Paket `libpam-oath` zu installieren.

sudo apt-get install libpam-oath

Danach erstellt man ein UsersFile, das Informationen über Nutzer*innen und deren Schlüssel enthält. Diese Datei darf nur von `root` les- und schreibbar sein.

sudo touch /etc/users.oath
sudo chmod 600 /etc/users.oath

Danach wird SSH so konfiguriert, dass es das PAM Modul zur Authentifizierung verwendet. Die folgende Zeile wird am Anfang von `/etc/pam.d/sshd` hinzugefügt.

# file: /etc/pam.d/sshd
auth required pam_oath.so usersfile=/etc/users.oath window=10 digits=6

Achtung: Verwenden Sie unbedingt `required` statt `sufficient`, da die OTP Abfrage sonst einfach übersprungen werden kann.

Die sshd-Konfiguration wird ebenfalls angepasst.

# file: /etc/ssh/sshd_config
ChallengeResponseAuthentication yes
UsePAM yes
match group sudo
    AuthenticationMethods keyboard-interactive

Hinweis: Es wird empfohlen, die Match-Blöcke an das Ende der sshd_config zu schreiben. Einerseits liegt das am Geltungsbereich der match-Blöcke (alle Zeilen zwischen dem Match-Block und einem nachfolgenden Match-Block oder dem Ende der Datei - je nachdem was zuerst eintritt). Andererseits lassen sich durch diese Schreibweise die "globalen" von den spezifischen Einstellungen trennen. Dies erleichtert Ausnahmeregelungen und allgemein hin das Verständnis.

Mit dieser Einstellung fragt SSH erst nach dem OTP, dann nach dem Passwort.

Achtung: `UsePAM` umgeht die von SSH verwendete Passwort-Abfrage und verwendet stattdessen das PAM Modul. Daher wird nicht `AuthenticationMethods password` verwendet, da es nicht mehr korrekt funktioniert. Dementsprechend lässt sich diese Authentifikationsmethode auch nicht beliebig mit anderen kombinieren (bspw. geht nicht `AuthenticationMethods keyboard-interactive publickey,password`). Will man PAM ohne Passwort verwenden, so muss `/etc/pam.d/sshd` entsprechend angepasst werden (Auskommentieren von `@include common-auth`).


Eine alternative Einstellung verwendet SSH Schlüssel und OTPs (Auskommentieren von `@include common-auth` und Hinzufügen von `publickey` zu `AuthenticationMethods`). Allerdings entspricht dies nicht ganz den Anforderungen einer 2-Faktor-Authentifizierung, die Wissen und Besitz erfordert, da sowohl der SSH Schlüssel als auch der OTP Schlüssel lediglich Besitz nachweisen, nicht aber Wissen.


Stattdessen kann man durch `AuthenticationMethods publickey,keyboard-interactive` auch eine 3-Faktor-Authentifizierung erzwingen, die nach SSH Schlüssel, OTP und Passwort fragt.

Generieren von OTP Schlüsseln

OTP Schlüssel sind hexadezimal (`UsersFile`) oder base32 (Tokens) kodierte Strings. Da der OTP Schlüssel ein gemeinsames Geheimnis zwischen Server und Client / Token ist, kann er sowohl auf dem Server oder dem Client erstellt werden.

Hierzu gibt es mehrere Möglichkeiten, bspw. per Kommandozeile (`openssl rand -hex 20`). Da der Schlüssel sowohl im `UsersFile` als auch auf dem Token eingerichtet werden muss, bietet sich ein Tool an, welches die notwendigen Konfigurationen automatisch erstellt.

Das Tool `gen-oath-safe` erstellt sowohl die Konfigurationszeile für das `UsersFile` als auch einen QR Code, der mit dem `FreeOTP Authenticator` eingescannt werden kann.