SSH mit Public Key Authentication sollte im Jahr 2024 längst die Standardeinstellung sein. Die schlüsselbasierte Authentifizierung verbessert nicht nur die Sicherheit, sondern bringt obendrein einen echten Komfortgewinn.
Alles beginnt mit dem Erzeugen eines SSH-Schlüsselpaars mit dem Befehl »ssh-keygen«. Bereits an diesem Punkt liegen die ersten Fallstricke, denn inzwischen gibt es massive Attacken auf RSA2048, und man darf erwarten, dass RSA3072 demnächst ebenso in den Fokus von Kryptoanalytikern rückt. Wer also heute noch RSA mit Schlüssellängen von 2048 Bit oder weniger nutzt, sollte dringend etwas tun.
Im Rahmen des Artikels erzeuge ich ein Schlüsselpaar auf Basis elliptischer Kurven. Um mehr über Elliptische-Kurven-Kryptografie zu erfahren, werfen Sie bitte einen Blick auf ein Papier [1] des Bundesministeriums für Sicherheit in der Informationstechnik (BSI). Der Typ des Schlüsselpaars, ob nun EDCSA oder ED25519, und damit die Wahl der Kurve, hat praktisch keinen Einfluss auf die Sicherheit. Beide Verfahren gelten als sehr sicher; ED25519 liefert unter bestimmten Voraussetzungen eine minimal bessere Performance.
Mit dem Code aus der ersten Zeile von Listing 1 generiere ich zu Testzwecken ein Schlüsselpaar (Abbildung 1). Den Public Key lade ich daraufhin auf das Zielsystem (Zeile 2). Anschließend kann ich mich dort mit dem neuen Schlüsselpaar einloggen (Zeile 3). Mit dem privaten Schlüssel und dazugehörigen Passwort liegt das Sicherheitsniveau deutlich höher.
Listing 1
Elliptische-Kurven-Kryptografie
$ ssh-keygen -t ecdsa -b 384 -f ~/.ssh/ecdsa_2024-03 $ ssh-copy-id -i ~/.ssh/ecdsa_2024-03.pub thomas@pihole $ ssh -i ~/.ssh/ecdsa_2024-03 thomas@pihole $ ssh -o PreferredAuthentications=password -o PubkeyAuthentication=no root@pihole
Nach dem erfolgreichen Login gilt es noch, die Konfigurationsdatei des SSH-Daemons »/etc/ssh/sshd_config« auf dem Zielsystem anzupassen. Zusätzlich sollten Sie unbedingt den SSH-Login für root über die Option »PermitRootLogin no« sowie die Möglichkeit der Passwortauthentifizierung über die Option »PasswordAuthentication no« deaktivieren.
SSH hält beim Restart des Servers die aktiven Verbindungen offen. Deswegen kann ich risikolos den SSH-Daemon per »systemctl restart sshd« neu starten, ohne mich selbst auszusperren. Zu diesem Zeitpunkt öffne ich testweise eine weitere SSH-Verbindung, um sicherzustellen, dass der Login per Public-Key-Authentifizierung funktioniert. Ich empfehle dringend, hier außerdem zu prüfen, ob ein Root-Login und Passwort-Login noch funktionieren. Das bewerkstelligen Sie in einem Rutsch mit dem Kommando aus der letzten Zeile von Listing 1.
Der zweite Faktor
Public-Key-Authentifizierung ist ein wichtiger Schritt. Allerdings bedeutet ein kompromittiertes Schlüsselpaar, dass sich womöglich Unbefugte Zugang zum System verschaffen können. Wer über den Private Key verfügt, kann versuchen, ihn zu entsperren; es fehlt ein getrennter, weiterer Faktor. Jetzt kommt das Time-based-one-time-password-Verfahren (TOTP) zum Einsatz, das viele wohl durch Google Authenticator kennen dürften. Dabei vereinbaren Sender und Empfänger eingangs einen gemeinsamen geheimen Schlüssel. Nach einem festgelegten Zeitraum, typischerweise 30 Sekunden, wird auf Basis des geheimen Schlüssels und der absoluten Uhrzeit ein kryptografischer Hash berechnet, das OTP.
Unter Debian und dessen Derivaten benötigen Sie dafür nur ein weiteres Paket, das Sie per »sudo apt install libpam-google-authenticator« installieren. Danach müssen Sie das System dazu bewegen, nach erfolgreicher Authentifizierung mit dem Public-Key-Verfahren diesen zweiten Faktor abzufragen. Hier kommt das Konzept der Pluggable Authentication Modules (PAM) ins Spiel. PAM ist, wie der Name andeutet, in der Lage, die Authentifizierung an bestimmten Diensten über erweiterbare Regelwerke zu steuern. Es lohnt sich, von allen Dateien vorab eine Sicherungskopie anzulegen: Fehler können dazu führen, dass eine Anmeldung am System nicht mehr gelingt.
Nachdem Sie die Authenticator-Library eingebunden haben, müssen Sie sie in PAM aktivieren. Öffnen Sie dazu die Datei »/etc/pam.d/sshd« mit einem Editor, und ergänzen Sie die Zeile »auth required pam_google_authenticator.so«. Achten Sie bitte zudem darauf, dass in der Datei »/etc/ssh/sshd_config« das Challenge-Response-Verfahren aktiv ist. Für TOTP ist die Zeile »ChallengeResponseAuthentication yes« zwingend erforderlich. Schließlich starten Sie den SSH-Daemon per »sudo systemctl restart sshd.service« neu.
Nun fehlt noch das Einrichten von Google Authenticator. Dazu starten Sie einfach »google-authenticator« in einem Terminal und müssen mehrere Fragen beantworten (Listing 2). Nach den Eingaben erscheinen ein QR-Code, den Sie mit Google Authenticator scannen können, sowie einige Notfallcodes.
Listing 2
Interaktives TOTP-Setup
$ google-authenticator Make tokens "time-base": yes Update the .google_authenticator file: yes Disallow multiple uses: yes Increase the original generation time limit: no Enable rate-limiting: yes
Prinzipiell sollte der QR-Code genauso mit anderen TOTP-Programmen funktionieren, beispielsweise mit KeePassXC. Statt des QR-Codes kopieren Sie in diesem Fall den Secret Key. Über das Kontextmenü des jeweiligen Passworteintrags lässt sich TOTP einrichten. Dazu fügen Sie den Secret Key ins zugehörige Textfeld ein.
Die restlichen Optionen sind ebenso schnell gesetzt: Mit der Option RFC 6238 stellen Sie den Algorithmus auf SHA-1, die Periode auf 30 Sekunden und die Codelänge auf sechs Zeichen ein. Anschließend genügt es, noch den aktuell angezeigten TOTP-Code einzugeben, um das Setup abzuschließen. Damit haben Sie einen echten zweiten Faktor zusätzlich zum privaten Schlüssel.
Höchste Hürden
Unter Linuxern scheinen Hardware-Token überproportional stark verbreitet zu sein – das ergab zumindest eine (nicht ganz repräsentative) Umfrage bei den diesjährigen Chemnitzer Linux-Tagen. Wer im Besitz eines FIDO2-Sticks [2] ist, profitiert bei der SSH-Authentifizierung davon – vorausgesetzt, SSH liegt auf dem Zielsystem mindestens in Version 8.2p1 vor, besser noch in Version 8.3. Möchten Sie Discoverable Credentials (früher als Resident Key bezeichnet) einsetzen, benötigen Sie zwingend SSH 8.3 oder höher. Bis einschließlich SSH 8.2p1 sind Anwender auf Non-discoverable Credentials (ex: Non-resident Key) beschränkt.
Der Unterschied zwischen Discoverable und Non-discoverable Credentials liegt im Wesentlichen in den Speicherorten und den damit verbundenen Mechanismen. Discoverable Credentials werden direkt auf dem Authenticator selbst gespeichert, sie sind resident. Dazu kann ein Security-Token wie ein Yubikey [3] dienen, aber auch die Apple Security Enclaves auf dem iPhone, das HSM auf Android-Geräten oder das Trusted Platform Module auf einem Laptop.
Der Name Discoverable Credentials rührt daher, dass der Client eine Liste möglicher Schlüssel im Authenticator ermitteln kann, die zur jeweiligen Relying Party ID (rpID) passen. Dabei kann es sich um E-Mail-Adressen, Telefonnummern oder Benutzernamen handeln. Daher funktioniert eine Autovervollständigung ausschließlich mit Discoverable Credentials.
Wie die Login-Prozedur per Discoverable Credentials vonstattengeht, zeigt Abbildung 2. Die Relying Party (RP), beispielsweise eine Webseite, sendet eine unspezifische Authentifizierungsanfrage an den Client, etwa einen Browser. Der Client befragt den Authenticator, in meinem Fall einen Yubikey, der alle Discoverable Credentials für die passende RP ermittelt. Über den Webbrowser erfolgt anschließend die Auswahl der gewünschten Discoverable Credentials, die dann ihrerseits dazu dienen, die Anfrage der anfragenden Partei zu signieren.

Abbildung 2: Der schematische Ablauf einer Authentifizierung per Discoverable Credentials. Diese Methode ermöglicht, dass niemand Credentials auswendig wissen muss.
Hier zeigt sich schnell einer der Vorteile von Discoverable Credentials. Nachdem der Authenticator die entsprechenden User-Handles (E-Mail-Adressen, Benutzernamen, Telefonnummern und so weiter) enthält, muss man sie sich nicht mehr merken. Die Handles können vorausgefüllt werden. Ebenso lassen sich bestimmte Authentifizierungen an ein bestimmtes Gerät koppeln (Device-specific Authentication).
Das Verfahren hat allerdings seine Schattenseiten, denn auch in Zeiten nahezu unbegrenzten Speicherplatzes können viele Security Keys nur sehr begrenzte Mengen von Credentials speichern. In der Regel bieten Hardware-Token zwischen 8 und 100 Speicherplätze für Resident Keys. Erreichen Sie das Limit, muss der Inhalt einiger Speicherplätze weichen, um Freiraum für neue Credentials zu schaffen.
Hinzu kommt das Risiko, das Hardware-Token zu verlieren. Kommt es abhanden, gehen damit sämtliche gespeicherten Schlüssel verloren. Das kann bedeuten, dass Sie sich nicht mehr bei den entsprechenden Diensten anmelden können. Obendrein besteht zumindest theoretisch die Gefahr, dass es einem Angreifer unter Umständen gelingen könnte, aus einem erbeuteten Security Key die gespeicherten Credentials zu extrahieren. Obwohl moderne Authenticator-Geräte diesbezüglich stark gehärtet sind und Mechanismen wie PINs oder biometrische Daten zum Schutz vor Extraktion einsetzen, bleibt stets ein (sehr geringes) Risiko.
Non-discoverable Credentials
Die Non-discoverable Credentials ticken etwas anders. Im Gegensatz zu den auf dem Gerät gespeicherten Resident Keys liegen sie eben nicht auf dem Hardware-Token. Stattdessen generiert der Authenticator auf Basis des geschützten, internen Master Keys für jeden Anfragenden (RP) ein eigenes Schlüsselpaar. Dessen Public Key wird zusammen mit einer Credential-ID beim initialen Setup an den anfragenden Server der RP. Die Relying Party verknüpft dann diesen Public Key mit dem Benutzerkonto. Für jede nachfolgende Authentifizierung leitet nun der Authenticator mithilfe der Credential-ID erneut den Private Key vom Master Key ab.
Nachdem dieser Key nur temporär im geschützten Speicher des Authenticators enthalten ist, heißt er auch Ephemeral Key (kurzlebiger Schlüssel). Wichtig ist hier, dass der Authenticator selbst die Non-discoverable Credentials erkennen kann (Abbildung 3). Er kann ja nicht anhand der rpID nach dem Schlüssel suchen, und ohne die Credential-ID könnte er nicht einmal ermitteln, ob es überhaupt einen passenden Key gibt.

Abbildung 3: Der schematische Ablauf einer Authentifizierung per Non-discoverable Credentials. Der Authenticator selbst kann Non-discoverable Credentials nicht identifizieren.
Offensichtlich muss im Fall von Non-discoverable Credentials die Relying Party zunächst die E-Mail-Adresse, den Benutzernamen oder eine Telefonnummer einholen. Erst danach kann sie die zugehörige Credential-ID an den Browser zurückschicken. Sobald der Security Key diese Credential-ID durch den Browser erhält, kann er über den Master Key einen Ephemeral Key ableiten und zur Signatur verwenden.
Im Gegensatz zu den Discoverable Credentials gibt es hier keine Beschränkung. Die Schlüssel liegen nicht auf dem Authenticator, was im Prinzip beliebig viele Schlüssel ermöglicht. Setzen Sie Non-resident Keys ein, sind Sie außerdem nicht an bestimmte Geräte gebunden. Über einen geeigneten Authenticator klappt die Authentifizierung übergreifend über beliebig viele Geräte und Plattformen hinweg.
Allerdings gehen mit der höheren Flexibilität ebenso Nachteile einher. So müssen Sie sich merken, welchen User-Handle (E-Mail, Benutzername, Telefonnummer) sie für welche Webseite verwendet haben. Weiterhin müssen Webseiten zuverlässig die Verbindungen zwischen Benutzerkonten und Public Keys speichern. Mangelnde Sorgfalt beschwört hierbei allzu leicht schwere Sicherheitsprobleme herauf.
Es fragt sich, was das bezogen auf die SSH-Authentifizierung bedeutet. Dritte können Non-discoverable Credentials nicht benutzen, wenn ihnen die zugehörige Credential-ID-Datei nicht vorliegt – selbst dann nicht, wenn sie die PIN kennen. Für Umgebungen, in denen die Vertraulichkeit auch dann gewährleistet werden muss, wenn ein Yubikey abhandenkommt, ist dieses Verfahren optimal.
Im Gegensatz dazu bestechen Discoverable Credentials durch ihre Flexibilität. So ist es hier ausschließlich durch Berühren des Yubikeys und Eingabe der FIDO2-PIN möglich, sich von beliebigen Arbeitsplätzen aus anzumelden. Bei bekannter PIN eignet sich dieses Verfahren hervorragend, wenn es auf besonders einfache Prozesse ankommt.
OpenSSH und FIDO2
Um OpenSSH mit FIDO2-Authentifizierung einzurichten, bedarf es wie eingangs erwähnt der entsprechenden OpenSSH-Versionen. Zudem muss auf einem Yubikey eine PIN für FIDO2 gesetzt sein. Sind diese Voraussetzungen erfüllt, gilt es, auf sämtlichen Remote-Systemen die Datei »/etc/ssh/sshd_config« um die Option »PubkeyAuthOptions verify-required« zu erweitern und anschließend SSH neu zu starten. Das lässt sich auf bestimmte Credentials einschränken, indem Sie in »~/.ssh/authorized_keys« den entsprechenden Einträgen »verify-required« als Suffix anhängen.
Um Discoverable Credentials mit einem Yubikey zu verwenden, stecken Sie als Erstes das Token ein. Dann laden Sie mittels des Codes aus der ersten Zeile von Listing 3 ein auf der ECDSA-Kurve basierendes Schlüsselpaar darauf. Möchten Sie stattdessen eine ED25519-Kurve verwenden (zweite Zeile), erfordert das auf dem Yubikey eine Firmware in Version 5.2.3 oder höher.
Listing 3
Schlüsselpaare hochladen
$ ssh-keygen -t ecdsa-sk -O resident -O application=ssh:Beschreibung -O verify-required $ ssh-keygen -t ed25519-sk -O resident -O application=ssh:Beschreibung -O verify-required
Bei der »Beschreibung« handelt es sich lediglich um einen Text, der erklärt, wo dieser Schlüssel zum Einsatz kommt – etwa um einen Server-Namen. Er hilft dabei, das richtige Discoverable Credential zu identifizieren, sollten sich auf dem Yubikey mehrere befinden. Dieser Beschreibungstext ist zwar optional; dennoch empfehle ich wärmstens, eine aussagekräftige Beschreibung zu hinterlegen.
Während ich in Abbildung 1 per Ssh-keygen noch ein konventionelles Schlüsselpaar anlegen lasse, erzeugt das Tool in Abbildung 4 eine für Secure Keys optimierte Variante. Dabei muss ich nicht nur eine PIN vergeben, sondern auch den Authenticator berühren.
Nachdem ich den öffentlichen Schlüssel per Ssh-copy-id auf das Zielsystem gebracht habe, kann ich das Login testen. Dabei muss ich meine User Presence nachweisen, also meinen Yubikey antippen. Daraufhin fragt der SSH-Client meine PIN ab. Hat alles geklappt, bestätigt SSH meine User Presence und lässt mich auf das System.
Fazit
Wer heute SSH zugänglich macht, womöglich sogar ins Internet, der tut gut daran, die Authentifizierung maximal abzusichern. Sowohl der Einsatz von Google Authenticator (also TOTP) als auch die hardwaregestützte Authentifizierung per Secure-Key verschaffen hier bei überschaubarem Konfigurationsaufwand erhebliche Sicherheitsvorteile. (csi)
Infos
- BSI-Papier über Elliptische-Kurven-Kryptografie (PDF, englisch): https://www.bsi.bund.de/SharedDocs/Downloads/EN/BSI/Publications/TechGuidelines/TR03111/BSI-TR-03111_V-2-1_pdf.pdf?__blob=publicationFile&v=1
- Dokumentation der FIDO Alliance: https://fidoalliance.org/specifications/
- Yubikey: https://developers.yubico.com/SSH/Securing_SSH_with_FIDO2.html







