SSH-Zertifikate zur Authentifizierung erklärt

Ein SSH-Zertifikat ist ein öffentlicher Schlüssel, signiert von einer Zertifizierungsstelle (CA), die Sie kontrollieren, mit einer Liste erlaubter Benutzernamen und einem Ablaufdatum. Signieren Sie einen Schlüssel mit ssh-keygen -s ca -I id -n user -V +8h key.pub und setzen Sie dann auf jedem Server TrustedUserCAKeys. Die Server akzeptieren dann jedes gültige Zertifikat dieser CA, ohne authorized_keys-Eintrag für jede Person.

Sie haben schon ein signiertes Zertifikat? Wardterm bewahrt es mit seinem Schlüssel auf und meldet sich mit beiden an. Zeigen

Aktualisiert am . Alle Befehle liefen mit OpenSSH 10.3 unter macOS als Client und OpenSSH 10.0 unter Debian 13 als Server, einschließlich falschem Principal, abgelaufenem Zertifikat, Beschränkung der Quelladresse, Sperrung und Host-Zertifikaten.

Was es löst

Bei einfachen Schlüsseln führt jeder Server eine Liste erlaubter Schlüssel, und jeder Laptop eine Liste von Host-Schlüsseln. Bei 50 Servern bedeutet das Hinzufügen oder Entfernen einer Person, 50 Dateien zu ändern, und alte Schlüssel bleiben gern für immer.

Bei Zertifikaten vertrauen die Server einem einzigen CA-Schlüssel. Sie signieren den öffentlichen Schlüssel einer Person für eine bestimmte Zeit, und wenn das Zertifikat abläuft, endet der Zugang. Das sind OpenSSH-Zertifikate, nicht die X.509-Art, die für Websites verwendet wird, und Sie brauchen weder eine externe Firma noch einen externen Dienst.

Die CA erstellen

ssh-keygen -t ed25519 -f user_ca -C "user-ca"

Das ist ein normales Schlüsselpaar. Wer die private Hälfte user_ca besitzt, kann sich auf jedem Server, der ihr vertraut, als jeder beliebige Benutzer anmelden. Geben Sie ihr daher eine starke Passphrase und halten Sie sie von Ihrem Alltagsrechner und von den Servern fern. Verwenden Sie für Hosts eine getrennte CA, wie unten gezeigt.

Den öffentlichen Schlüssel eines Benutzers signieren

Die Person schickt Ihnen id_ed25519.pub, niemals den privaten Schlüssel:

ssh-keygen -s user_ca -I "alice@example.com" -n deploy,alice -V +8h id_ed25519.pub
OptionBedeutung
-s user_caDer private CA-Schlüssel zum Signieren.
-IDie Schlüssel-ID. Sie steht bei jeder Anmeldung im Server-Log, sie sollte also die Person benennen.
-nDie Principals: die Namen, für die dieses Zertifikat gilt.
-VDie Gültigkeit. +8h, +1d oder ein Bereich wie -5m:+1d, der auch einen Server abdeckt, dessen Uhr etwas nachgeht.

Das Ergebnis ist id_ed25519-cert.pub. Geben Sie es der Person zurück, die es neben den privaten Schlüssel legt. ssh findet es dann am Namen, ohne zusätzliche Konfiguration. Liegt es woanders, braucht es eine Zeile CertificateFile in ~/.ssh/config. So lesen Sie eines aus:

ssh-keygen -L -f id_ed25519-cert.pub

Ohne -V läuft ein Zertifikat nie ab, was einen großen Teil des Nutzens zunichtemacht.

Den Server der CA vertrauen lassen

Kopieren Sie user_ca.pub, nur den öffentlichen Teil, nach /etc/ssh/user_ca.pub auf dem Server. Tragen Sie dies in die sshd-Konfiguration ein, führen Sie dann sudo sshd -t aus und laden Sie neu:

TrustedUserCAKeys /etc/ssh/user_ca.pub

Der Benutzer kann sich jetzt ohne Zeile in authorized_keys anmelden. Das Server-Log zeigt, wer es war:

Accepted publickey for deploy from 203.0.113.50 port 56276 ssh2: ED25519-CERT SHA256:... ID alice@example.com (serial 0) CA ED25519 SHA256:...

Principals

Standardmäßig verlangt der Server, dass der Kontoname einer der Principals des Zertifikats ist. Ein Zertifikat für alice öffnet das Konto deploy nicht.

Um statt Kontonamen Rollen zu verwenden, listen Sie für jedes Konto die akzeptierten Principals auf:

AuthorizedPrincipalsFile /etc/ssh/auth_principals/%u

Dann enthält /etc/ssh/auth_principals/deploy einen Namen pro Zeile, zum Beispiel ops, und Sie signieren mit -n ops. Mit dieser Einstellung wird der Kontoname nicht mehr automatisch akzeptiert: Nur die Namen in der Datei zählen, und ein Konto ohne Datei lehnt Zertifikate ab.

Beschränken, was ein Zertifikat darf

Optionen werden beim Signieren gesetzt. Hier funktioniert das Zertifikat nur aus einem Netz und kann kein Terminal öffnen:

ssh-keygen -s user_ca -I alice -n ops -V +1h -O source-address=203.0.113.0/24 -O no-pty id_ed25519.pub

-O clear entfernt alle Standardrechte, und Sie können dann die gewünschten wieder hinzufügen, zum Beispiel -O clear -O permit-pty.

Wenn eine Anmeldung fehlschlägt

Der Client sagt nur Permission denied (publickey). Der Grund steht im Server-Log:

Log-ZeileUrsache
Certificate invalid: name is not a listed principalDas Konto steht nicht in der -n-Liste des Zertifikats.
Certificate invalid: expiredDas Enddatum ist überschritten. Signieren Sie es neu.
Refused by certificate optionsEine Beschränkung wie source-address passt nicht.
Authentication key ... revoked by file ...Der Schlüssel steht auf der Sperrliste.

Ein Zertifikat vor Ablauf sperren

Halten Sie Zertifikate kurz, dann brauchen Sie das selten. Für den dringenden Fall erstellen Sie aus dem öffentlichen Schlüssel eine Key Revocation List und kopieren sie auf jeden Server:

ssh-keygen -k -f revoked.krl id_ed25519.pub
ssh-keygen -Q -f revoked.krl id_ed25519.pub
RevokedKeys /etc/ssh/revoked.krl

Weitere Schlüssel fügen Sie mit -u derselben Liste hinzu. Gehen Sie mit dieser Datei sorgfältig um: Kann sshd sie nicht lesen, wird die Anmeldung per öffentlichem Schlüssel für alle Benutzer abgelehnt.

Für Schlüssel ohne Zertifikat siehe wie Sie einen SSH-Schlüssel beim Weggang widerrufen.

Host-Zertifikate

Host-Zertifikate lösen die andere Richtung. Ihre Benutzer sehen die Abfrage zu einem unbekannten Host nicht mehr, weil sie einer CA vertrauen und nicht jedem einzelnen Host-Schlüssel. Signieren Sie den öffentlichen Host-Schlüssel des Servers mit -h und listen Sie die Namen auf, mit denen man sich verbindet:

ssh-keygen -t ed25519 -f host_ca -C "host-ca"
ssh-keygen -s host_ca -I server1 -h -n server1.example.com -V +52w ssh_host_ed25519_key.pub

Auf dem Server, mit ssh_host_ed25519_key-cert.pub in /etc/ssh/:

HostKey /etc/ssh/ssh_host_ed25519_key
HostCertificate /etc/ssh/ssh_host_ed25519_key-cert.pub

Fügen Sie auf jedem Client eine Zeile in ~/.ssh/known_hosts ein, mit dem Inhalt von host_ca.pub:

@cert-authority *.example.com ssh-ed25519 AAAA...

Das Muster muss zu dem Namen passen, mit dem Sie sich verbinden. Tut es das nicht, ignoriert ssh die Zeile und behandelt den Host als unbekannt, oder lehnt ihn ab, wenn StrictHostKeyChecking auf yes steht. Auch Host-Zertifikate laufen ab, erneuern Sie sie also vor diesem Datum. Wie der Rest dieser Datei funktioniert, steht in known_hosts erklärt.

Wann sich Zertifikate lohnen

Für wenige Server und wenige Personen sind einfache Schlüssel unkomplizierter. Zertifikate zahlen sich aus, wenn oft Personen kommen und gehen, oder wenn Sie kurzlebigen Zugang mit einem Namen im Log wollen. Der schwierige Teil ist der Prozess um die CA: wer signieren darf, wo der private Schlüssel liegt und wie eine Person jeden Tag ein neues Zertifikat bekommt. ssh-keygen liefert das Signieren, nicht diesen Prozess.

Fragen

Was ist der Unterschied zwischen SSH-Schlüssel und SSH-Zertifikat?

Ein Zertifikat ist ein öffentlicher Schlüssel, den eine CA signiert hat, mit einer Liste erlaubter Benutzernamen und einem Ablaufdatum. Ein Server, der der CA vertraut, akzeptiert es ohne Eintrag in authorized_keys für diesen Schlüssel.

Wie sehe ich, wann ein SSH-Zertifikat abläuft?

Führen Sie ssh-keygen -L -f id_ed25519-cert.pub aus. Die Zeile Valid zeigt Beginn und Ende der Gültigkeit.

Ersetzen SSH-Zertifikate authorized_keys?

Für Anmeldungen per Zertifikat ja: Der Server braucht nur TrustedUserCAKeys. Normale Schlüssel in authorized_keys funktionieren daneben weiter.

Quellen

Mehr zu Schlüssel und Anmeldung

Alle Anleitungen