SSH-Zertifikate: eine eigene SSH-CA einrichten
Wer drei Server betreibt, pflegt drei authorized_keys-Dateien. Wer dreissig betreibt, pflegt dreissig — und weiss irgendwann nicht mehr, welcher öffentliche Schlüssel dort eigentlich noch liegt und wem er gehört. Genau dieses Verteilproblem lösen SSH-Zertifikate: Der Server merkt sich nicht mehr eine Liste von Schlüsseln, sondern genau eine Unterschrift, der er vertraut. Wer diese Unterschrift vorweisen kann, kommt rein; wer sie nicht mehr vorweisen kann, nicht.

Diese Anleitung setzt voraus, dass ihr euch schon einmal per Schlüsselpaar bei einem Server angemeldet habt. Darauf baut alles auf, was hier folgt — ein Zertifikat ersetzt das Schlüsselpaar nicht, es kommt oben drauf. Wir richten eine eigene Zertifizierungsstelle ein, signieren damit Benutzer- und Hostschlüssel, begrenzen deren Rechte und Laufzeit und widerrufen sie am Ende wieder. Alles mit Bordmitteln von OpenSSH, ohne Zusatzsoftware und ohne fremden Dienst.
Warum SSH-Zertifikate das Problem mit authorized_keys lösen
Die klassische Anmeldung per öffentlichem Schlüssel ist eine Liste. Auf jedem Server steht in ~/.ssh/authorized_keys, welche Schlüssel dort hineindürfen. Ab dem dritten Server wird daraus eine Matrix: Jeder Schlüssel muss auf jeden Server, jede Änderung überall nachgezogen werden.
Das eigentliche Problem ist aber nicht das Hinzufügen, sondern das Wegnehmen. Ein einmal verteilter Schlüssel bleibt gültig, bis ihn jemand aktiv entfernt — auf jedem einzelnen Server. Verschwindet ein Notebook, beginnt eine Suchaktion durch Rechner, die vielleicht gerade gar nicht laufen. Ein öffentlicher Schlüssel hat kein Ablaufdatum, keinen Besitzer und keine Rolle. Er ist einfach da.
Ein Zertifikat dreht das um. Dem Server wird einmalig gesagt, welcher Zertifizierungsstelle er glaubt. Danach zählt kein einzelner Schlüssel mehr, sondern nur noch: Ist dieses Zertifikat von der richtigen Stelle unterschrieben, ist es noch gültig, und steht darin ein Name, der hier etwas zu suchen hat? Wer geht, bekommt kein neues mehr — und das alte läuft von allein ab.

Was ein Zertifikat ist — und was es ausdrücklich nicht ist
Das Verfahren ist keine Neuerung. OpenSSH hat es mit Version 5.4 am 8. März 2010 eingeführt: "Add support for certificate authentication of users and hosts using a new, minimal OpenSSH certificate format (not X.509)." Es steckt also seit über fünfzehn Jahren in jedem halbwegs gepflegten System.
Der Klammerzusatz ist wichtig. Ein SSH-Zertifikat hat mit den X.509-Zertifikaten, die euer Browser für HTTPS auswertet, nichts zu tun — kein gemeinsames Format, keine gemeinsame Werkzeugkette, keine Wurzelzertifikate von Dritten. Die Entwickler begründen das in der Formatbeschreibung PROTOCOL.certkeys so: "SSH eschews the use of X.509 certificates and uses raw keys. This approach has some benefits relating to simplicity of configuration and minimisation of attack surface." Weniger Angriffsfläche durch weniger Format — eine Begründung, die in dieser Branche selten zu lesen ist.
Was drinsteht, beschreibt die Handbuchseite ssh-keygen(1) knapp: "Certificates consist of a public key, some identity information, zero or more principal (user or host) names and a set of options that are signed by a Certification Authority (CA) key." Es gibt zwei Sorten: Ein Benutzerzertifikat weist einen Benutzer gegenüber einem Server aus, ein Hostzertifikat den Server gegenüber dem Benutzer. Beide entstehen mit demselben Werkzeug und sind unabhängig voneinander nutzbar.
Principals: der Name, auf den es ankommt
Der wichtigste Teil eines Zertifikats sind die Principals. Bei einem Benutzerzertifikat sind das Namen, unter denen sich der Inhaber anmelden darf. Bei einem Hostzertifikat sind es Rechnernamen; laut ssh-keygen(1) gilt dort: "For host certificates, principals are hostnames and may include wildcards."
Ein Principal ist nicht zwingend ein Unix-Benutzername. Er kann eine Rolle sein — deploy, dba, backup —, und der Server entscheidet getrennt davon, welche Rolle sich als welcher Benutzer anmelden darf. Darauf kommen wir in Schritt 4 zurück.
Critical Options und Extensions
In einem Zertifikat stehen ausserdem Einschränkungen und Erlaubnisse, und die sind in zwei Töpfe geteilt. PROTOCOL.certkeys erklärt den Unterschied: "critical options are used to control features that restrict access where extensions are used to enable features that grant access. This ensures that certificates containing unknown restrictions do not inadvertently grant access while allowing new protocol features to be enabled via extensions without breaking certificates' backwards compatibility."
Praktisch heisst das: Eine critical option, die ein alter Server nicht kennt, lässt ihn das Zertifikat ablehnen. Eine unbekannte extension ignoriert er. Einschränkungen fallen im Zweifel zu eurem Vorteil aus, Erlaubnisse im Zweifel weg — genau so herum soll es sein.
Was ihr für diese Anleitung braucht
- Mindestens einen Linux-Server mit OpenSSH-Server und funktionierendem Schlüssel-Login, dazu einen Arbeitsrechner mit OpenSSH-Client.
- Einen dritten, möglichst gut abgesicherten Ort für den CA-Schlüssel. Ein verschlüsselter USB-Stick genügt, ein zweiter Rechner ist besser.
- Einen zweiten Zugangsweg zum Server für den Notfall: eine offene zweite SSH-Sitzung, eine Konsole beim Anbieter oder physischen Zugriff.
Die Befehle sind für Debian und Ubuntu geschrieben und laufen auf anderen Distributionen genauso; nur Pfade und Paketnamen können abweichen.
Schritt 1: Die CA erzeugen und sofort wegsperren
Eine Zertifizierungsstelle ist bei OpenSSH nichts anderes als ein normales Schlüsselpaar — kein eigenes Format, kein Dienst, keine Datenbank. Erzeugt wird sie auf dem Rechner, auf dem sie später bleiben soll, nicht auf dem Server, den ihr damit absichern wollt:
mkdir -p ~/ssh-ca && chmod 700 ~/ssh-ca
cd ~/ssh-ca
ssh-keygen -t ed25519 -f user_ca -C "user-ca yourdevice"
ssh-keygen -t ed25519 -f host_ca -C "host-ca yourdevice"
Zwei getrennte Schlüssel, einer für Benutzer- und einer für Hostzertifikate. Technisch ginge auch einer. Tut es nicht: Wenn ihr den Host-Schlüssel später auf ein Provisionierungssystem legt, soll damit nicht zugleich der Benutzerzugang unterschrieben werden können.
Vergebt für beide Schlüssel eine Passphrase. Das ist hier keine Geschmacksfrage wie beim Anmeldeschlüssel. Wer diese Datei ohne Passphrase in die Hände bekommt, kann sich selbst ein gültiges Zertifikat für jeden eurer Server ausstellen, und ihr merkt es nicht. Prüft anschliessend die Rechte — die privaten Dateien gehören ausschliesslich euch, wie in unserem Beitrag zu Gruppen und Berechtigungen unter Linux beschrieben:
chmod 600 ~/ssh-ca/user_ca ~/ssh-ca/host_ca
chmod 644 ~/ssh-ca/user_ca.pub ~/ssh-ca/host_ca.pub
ls -l ~/ssh-ca
Legt jetzt eine Sicherung der beiden privaten Schlüssel an einem zweiten Ort an. Ein verlorener CA-Schlüssel bedeutet, dass ihr auf jedem Server von Hand wieder auf authorized_keys zurückfallen müsst. Wer ohnehin mit Hardwareschlüsseln arbeitet, findet die Grundlagen dazu unter Server SSH Zugang mit YubiKey absichern.
Schritt 2: Den Servern beibringen, wem sie glauben
Kopiert den öffentlichen Teil der Benutzer-CA auf den Server. Nur diesen — der private Schlüssel hat auf dem Server nichts verloren:
scp ~/ssh-ca/user_ca.pub benutzer@server:/tmp/user_ca.pub
ssh benutzer@server
sudo mv /tmp/user_ca.pub /etc/ssh/user_ca.pub
sudo chown root:root /etc/ssh/user_ca.pub
sudo chmod 644 /etc/ssh/user_ca.pub
Dann eine Zeile in die Serverkonfiguration. Die Direktive dafür heisst TrustedUserCAKeys und ist in sshd_config(5) beschrieben als "a file containing public keys of certificate authorities that are trusted to sign user certificates for authentication":
sudo tee /etc/ssh/sshd_config.d/60-ssh-ca.conf >/dev/null <<'EOF'
TrustedUserCAKeys /etc/ssh/user_ca.pub
EOF
sudo sshd -t && sudo systemctl reload ssh
Der Aufruf sshd -t prüft die Konfiguration, ohne den Dienst anzufassen. Nehmt ihn euch zur Gewohnheit: Ein Tippfehler in sshd_config und ein beherzter Neustart sind die klassische Art, sich selbst auszusperren. Heisst die Unit auf eurem System sshd statt ssh, passt den Namen an. Existiert /etc/ssh/sshd_config.d/ nicht oder wird es nicht eingebunden, schreibt die Zeile direkt in /etc/ssh/sshd_config.
Wichtig: Diese Zeile ergänzt die Anmeldung, sie ersetzt sie nicht. Eure bestehenden Einträge in authorized_keys funktionieren unverändert weiter — und das soll bis zum Schluss dieser Anleitung auch so bleiben.
Schritt 3: Den ersten Benutzerschlüssel signieren
Zurück auf dem Rechner mit der CA. Ihr braucht dort den öffentlichen Schlüssel des Anwenders, den ihr ausstatten wollt — also die Datei id_ed25519.pub von seinem Arbeitsgerät. Signiert wird so:
ssh-keygen -s ~/ssh-ca/user_ca \
-I "mario@laptop" \
-n mario,deploy \
-V +8w \
-z 1001 \
id_ed25519.pub
Die Schalter stehen in ssh-keygen(1). -s gibt den CA-Schlüssel an, mit dem unterschrieben wird. -I setzt die Kennung, die später in jeder Protokollzeile des Servers auftaucht — nehmt etwas, mit dem ihr Person und Gerät wiederfindet. -n nennt die Principals: "Multiple principals may be specified, separated by commas." -V ist die Gültigkeit, -z eine Seriennummer, die laut Handbuch dazu dient, "to distinguish this certificate from others from the same CA" — die braucht ihr spätestens beim Widerrufen.
Herausgekommen ist eine Datei id_ed25519-cert.pub. Schaut sie euch an, bevor ihr sie weitergebt:
ssh-keygen -L -f id_ed25519-cert.pub
Die Ausgabe zeigt Typ, Kennung, Seriennummer, Principals, Gültigkeitszeitraum und die enthaltenen Erweiterungen im Klartext — eure Kontrolle, dass wirklich das im Zertifikat steht, was ihr gemeint habt.
Die Zertifikatsdatei kommt nun neben den privaten Schlüssel auf dem Arbeitsgerät, also nach ~/.ssh/id_ed25519-cert.pub. Mehr ist nicht zu tun: Laut ssh_config(5) gilt, dass "if no certificates have explicitly been specified by CertificateFile, ssh(1) will try to load certificate information from the filename obtained by appending -cert.pub to the path of a specified IdentityFile." Wollt ihr das Zertifikat woanders ablegen, tragt den Pfad mit CertificateFile in ~/.ssh/config ein.
Der Test:
ssh -v mario@server 2>&1 | grep -i cert
Taucht dort eine Zeile mit ED25519-CERT auf und die Anmeldung gelingt, ist der Weg fertig. Behaltet die alte Sitzung offen, bis das sicher funktioniert.
Schritt 4: Principals sauber von Benutzernamen trennen
Bis hierher hat der Server eine stillschweigende Annahme gemacht. sshd_config(5) beschreibt sie bei AuthorizedPrincipalsFile: Der Standardwert ist "none, i.e. not to use a principals file", und dann gilt — "in this case, the username of the user must appear in a certificate's principals list for it to be accepted". Deshalb steht oben mario in der Principal-Liste.
Das skaliert schlecht: Ihr müsstet in jedes Zertifikat jeden Benutzernamen schreiben, unter dem sich jemand irgendwo anmelden können soll. Der bessere Weg ist eine Datei je Zielbenutzer, die sagt, welche Rollen dort hineindürfen:
sudo mkdir -p /etc/ssh/auth_principals
echo 'deploy' | sudo tee /etc/ssh/auth_principals/www-deploy
echo -e 'dba\nnotfall' | sudo tee /etc/ssh/auth_principals/postgres
sudo chown -R root:root /etc/ssh/auth_principals
sudo chmod 644 /etc/ssh/auth_principals/*
Und in der Serverkonfiguration:
AuthorizedPrincipalsFile /etc/ssh/auth_principals/%u
Das %u ist der Benutzername, unter dem die Anmeldung versucht wird. Laut sshd_config(5) sind an dieser Stelle die Token %%, %h, %U und %u erlaubt. Wer sich als www-deploy anmelden will, braucht ab jetzt ein Zertifikat mit dem Principal deploy — sein eigener Benutzername steht nirgends mehr im Zertifikat.
Das ist der eigentliche Gewinn der ganzen Übung. Ihr stellt ein Zertifikat auf eine Rolle aus und entscheidet danach auf jedem Server lokal, welche Rolle dort etwas darf. Wer die Rolle verliert, verliert sie überall gleichzeitig — ohne dass ihr einen einzigen Schlüssel suchen müsst. Wird die Zuordnung komplizierter, gibt es dafür noch AuthorizedPrincipalsCommand, ein Programm, das die erlaubten Principals zur Laufzeit ausrechnet.
Schritt 5: Kurze Gültigkeit statt langer Schlüssel
Ein Zertifikat läuft ab, ein öffentlicher Schlüssel nicht. Das ist der zweite grosse Unterschied, und er ist mehr wert als jede Widerrufsliste. Die Syntax von -V beschreibt ssh-keygen(1) so: "A validity interval may consist of a single time, indicating that the certificate is valid beginning now and expiring at that time, or may consist of two times separated by a colon to indicate an explicit time interval." Die Beispiele aus dem Handbuch:
+52w1d— gültig ab jetzt für 52 Wochen und einen Tag.-4w:+4w— gültig von vor vier Wochen bis in vier Wochen.20100101123000:20110101123000— ein fester Zeitraum mit Datum und Uhrzeit.-1m:forever— gültig ab vor einer Minute und niemals ablaufend.
Die letzte Form solltet ihr nicht benutzen. Sie baut genau den Zustand nach, den ihr gerade loswerden wolltet. Für Personen sind wenige Wochen ein brauchbarer Wert, für automatische Zugänge wie ein Deployment-Konto eher Stunden. Das kleine Minus am Anfang, etwa -5m:+8w, ist kein Schönheitsfehler, sondern der Umgang mit ungenauen Uhren: Läuft die Uhr des Servers ein paar Minuten vor, wäre ein frisch ausgestelltes Zertifikat dort sonst noch nicht gültig.
Kurze Laufzeiten heissen regelmässiges Nachsignieren. Ein kleines Skript, das den öffentlichen Schlüssel neu signiert und die Zertifikatsdatei ablegt, lässt sich sauber über einen systemd-Timer statt eines Cronjobs auslösen — samt Benachrichtigung, wenn es einmal nicht klappt. Achtet dabei darauf, dass der CA-Schlüssel dafür nicht ungeschützt auf einem dauerhaft laufenden Rechner landet.
Schritt 6: Was das Zertifikat überhaupt erlauben darf
Ohne weitere Angaben stellt ssh-keygen ein Zertifikat mit den üblichen Erlaubnissen aus: Terminal, Portweiterleitung, Agent-Weiterleitung, X11 und ~/.ssh/rc. Für ein Zertifikat, das nur ein Backup abholen soll, ist das zu viel. Mit -O clear räumt ihr erst alles ab — laut Handbuch "Clear all enabled permissions. This is useful for clearing the default set of permissions so permissions may be added individually." — und gebt danach einzeln zurück, was gebraucht wird:
ssh-keygen -s ~/ssh-ca/user_ca \
-I "backup-runner" \
-n backup \
-V +1d \
-z 2001 \
-O clear \
-O force-command="/usr/local/bin/backup-pull" \
-O source-address=10.0.0.0/24 \
backup_key.pub
Dieses Zertifikat kann genau eine Sache. force-command ist in PROTOCOL.certkeys beschrieben als "a command that is executed (replacing any the user specified on the ssh command-line) whenever this key is used for authentication" — was der Aufrufer als Befehl mitschickt, ist damit egal. source-address ist eine "comma-separated list of source addresses from which this certificate is accepted for authentication. Addresses are specified in CIDR format". Und weil permit-pty nach dem clear fehlt, gibt es kein Terminal: "In the absence of this option PTY allocation will be disabled."
Beide Beschränkungen sind critical options: Ein Server, der sie nicht versteht, lehnt das Zertifikat ab, statt es durchzuwinken. Die Erlaubnisse permit-pty, permit-port-forwarding, permit-agent-forwarding, permit-user-rc und permit-X11-forwarding sind dagegen extensions und werden stillschweigend übergangen, wenn ein Server sie nicht kennt.
Schritt 7: Hostzertifikate und das Ende der known_hosts-Frage
Bis jetzt ging es darum, wie der Server euch erkennt. Die andere Richtung ist mindestens so wichtig und wird viel seltener gemacht. Jeder kennt die Frage beim ersten Verbindungsaufbau, ob der Fingerabdruck des Servers stimmt — und jeder kennt die ehrliche Antwort darauf: Nachgeprüft wird sie fast nie, bestätigt wird sie immer.
Ein Hostzertifikat schafft diese Frage ab. Signiert wird der öffentliche Hostschlüssel des Servers, den ihr euch vorher holt:
scp benutzer@server:/etc/ssh/ssh_host_ed25519_key.pub .
ssh-keygen -s ~/ssh-ca/host_ca \
-I "web01" \
-h \
-n web01.example.ch,web01,10.0.0.11 \
-V +52w \
-z 3001 \
ssh_host_ed25519_key.pub
Der Schalter -h ist der Unterschied: "When signing a key, create a host certificate instead of a user certificate." In die Principals gehört jeder Name, unter dem der Server angesprochen wird — voller Name, Kurzform und IP-Adresse. Wer das vergisst, wundert sich, warum die Verbindung über die IP wieder nachfragt.
Die entstandene Datei ssh_host_ed25519_key-cert.pub kommt zurück auf den Server, und dort wird sie bekannt gemacht. sshd_config(5) beschreibt HostCertificate als "a file containing a public host certificate. The certificate's public key must match a private host key already specified by HostKey.":
scp ssh_host_ed25519_key-cert.pub benutzer@server:/tmp/
ssh benutzer@server
sudo mv /tmp/ssh_host_ed25519_key-cert.pub /etc/ssh/
sudo chown root:root /etc/ssh/ssh_host_ed25519_key-cert.pub
sudo chmod 644 /etc/ssh/ssh_host_ed25519_key-cert.pub
echo 'HostCertificate /etc/ssh/ssh_host_ed25519_key-cert.pub' \
| sudo tee -a /etc/ssh/sshd_config.d/60-ssh-ca.conf
sudo sshd -t && sudo systemctl reload ssh
Bleibt die Client-Seite. Der öffentliche Host-CA-Schlüssel kommt in die known_hosts, aber mit einem Marker davor. sshd(8) beschreibt ihn im Abschnitt zum Dateiformat: @cert-authority dient dazu, "to indicate that the line contains a certification authority (CA) key".
{ printf '@cert-authority *.example.ch '; cat ~/ssh-ca/host_ca.pub; } \
>> ~/.ssh/known_hosts
Ab jetzt gilt jeder Server unter *.example.ch als bekannt, sobald er ein gültiges Hostzertifikat vorzeigt — auch der, den ihr erst nächste Woche aufsetzt. Löscht die alten Einzeleinträge dieser Server aus der Datei, sonst prüft der Client weiterhin gegen den dort hinterlegten Schlüssel. Auf mehreren Geräten genügt es, diese eine Zeile zu verteilen oder sie systemweit in /etc/ssh/ssh_known_hosts abzulegen.
Schritt 8: Widerrufen, bevor ihr es braucht
Kurze Laufzeiten sind die beste Widerrufsliste, weil sie ohne Zutun wirken. Trotzdem braucht ihr einen Weg, ein noch gültiges Zertifikat sofort zu entwerten. OpenSSH kennt dafür Key Revocation Lists, und ssh-keygen(1) beschreibt sie so: "These binary files specify keys or certificates to be revoked using a compact format." Erzeugt wird eine solche Liste mit -k:
ssh-keygen -k -f revoked.krl id_ed25519-cert.pub
ssh-keygen -k -u -f revoked.krl weiteres-cert.pub
ssh-keygen -Q -f revoked.krl id_ed25519-cert.pub
Die erste Zeile legt die Liste an, die zweite ergänzt sie — zu -u sagt das Handbuch: "keys listed via the command line are added to the existing KRL rather than a new KRL being created". Die dritte prüft nach: -Q "will query an existing KRL, testing each key specified on the command line" und endet mit einem Rückgabewert ungleich null, wenn der Schlüssel gesperrt ist. Sperren geht auch ohne das Zertifikat in der Hand, nämlich über Kennung oder Seriennummer — beim Erzeugen einer KRL gibt -s dann "a path to a CA public key file used to revoke certificates directly by key ID or serial number" an.
Die Liste muss auf jeden Server und dort eingetragen werden. RevokedKeys nimmt beide Formate: "Keys may be specified as a text file, listing one public key per line, or as an OpenSSH Key Revocation List (KRL) as generated by ssh-keygen(1)."
echo 'RevokedKeys /etc/ssh/revoked.krl' \
| sudo tee -a /etc/ssh/sshd_config.d/60-ssh-ca.conf
sudo sshd -t && sudo systemctl reload ssh
Zwei Stolperfallen. Erstens: Zeigt RevokedKeys auf eine Datei, die es nicht gibt, verweigert sshd die Anmeldung — legt die Datei also an, bevor ihr die Zeile setzt. Zweitens wirkt eine Widerrufsliste nur dort, wo sie liegt; der beim Verteilen vergessene Server akzeptiert das gesperrte Zertifikat weiter. Für die Gegenrichtung kennt die known_hosts den Marker @revoked, der laut sshd(8) anzeigt, "that the key contained on the line is revoked and must not ever be accepted".
Der Preis: was ihr euch mit einer CA einhandelt
Ihr tauscht ein verteiltes Problem gegen ein zentrales ein, und diese Gegenseite ist nicht klein. Der CA-Schlüssel ist ab sofort der wertvollste Gegenstand in eurer Infrastruktur: Wer ihn hat, hat alles — ohne dass irgendwo eine Datei verändert werden müsste, die euch auffiele. Bei authorized_keys hinterlässt ein Angreifer wenigstens Spuren.
Dazu kommen praktische Kanten. Zertifikate laufen ab, und sie tun das mit Vorliebe am Freitagabend. Verwaltungsoberflächen von Anbietern, Netzwerkgeräte und manche Backup-Ziele sprechen nur klassische Schlüssel; ihr braucht also weiterhin einen Rückfallweg, der ebenso gepflegt werden will. Und der ganze Aufbau hängt an synchronen Uhren.
Unterhalb von etwa drei Servern und zwei Geräten lohnt sich das schlicht nicht. Wer einen Heimserver betreibt, ist mit einem sauber gesetzten Schlüssel, abgeschalteter Passwortanmeldung und einer Absicherung wie CrowdSec besser bedient als mit einer eigenen Zertifizierungsstelle. Interessant wird es ab dem Punkt, an dem ihr anfangt, eine Tabelle darüber zu führen, welcher Schlüssel auf welchem Rechner liegt.
Bevor ihr die CA scharf schaltet
Diese Anleitung hat bewusst nichts abgeschaltet. Der letzte Schritt — authorized_keys leeren — kommt erst, wenn diese Punkte alle abgehakt sind:
- Eine zweite SSH-Sitzung zum Server ist offen und bleibt offen, bis alles geprüft ist. Sie ist eure Rückfahrkarte.
- Die Anmeldung mit Zertifikat funktioniert aus einer neuen Sitzung, nicht nur laut
ssh -v. - Der private CA-Schlüssel liegt gesichert an einem zweiten Ort, ist mit einer Passphrase geschützt und befindet sich nicht auf einem der abgesicherten Server.
- Die Datei aus
RevokedKeysexistiert tatsächlich, und ihr habt einmal geprüft, dass ein gesperrtes Zertifikat wirklich abgewiesen wird. - Die Uhren von Server und Arbeitsgerät gehen synchron, und beim Signieren ist ein kleiner Vorlauf wie
-5mgesetzt. - Ihr wisst, wie ihr auf den Server kommt, wenn SSH gar nicht mehr geht — Konsole beim Anbieter, IPMI, Bildschirm und Tastatur. Und
sshd -tläuft vor jedemreloadfehlerfrei durch. - Es ist notiert, welche Zertifikate mit welcher Seriennummer und Laufzeit ausgestellt wurden. Ohne diese Notiz ist gezieltes Widerrufen später Raten.
Fazit: Zertifikate lösen ein Verteilproblem, kein Vertrauensproblem
SSH-Zertifikate nehmen euch die Arbeit ab, die eigentliche Frage aber nicht. Ein Zugang muss nicht mehr an dreissig Stellen gepflegt und an dreissig Stellen wieder entfernt werden; er entsteht an einer und verschwindet von allein. Der Gewinn wächst mit der Zahl der Rechner und Personen.
Was sie nicht lösen, ist die Frage, wem ihr eigentlich vertraut. Die verschiebt sich nur — vom einzelnen Schlüssel auf den einen Schlüssel, der alle anderen unterschreibt. Ein Zertifikat ist eine Aussage, keine Prüfung: Es sagt, dass jemand mit dem CA-Schlüssel diesen Zugang gutgeheissen hat. Ob das eine gute Entscheidung war, steht nicht drin.
Genau deshalb ist die entscheidende Massnahme dieser Anleitung nicht der Signierbefehl, sondern der USB-Stick im Schrank. Alles andere ist Handwerk und in zwei Stunden erledigt. Wer die CA dagegen ohne Passphrase auf dem Rechner liegen lässt, von dem aus er ohnehin ständig arbeitet, hat sich die Mühe gespart — und mit ihr die Sicherheit.
Quellen und weiterführende Links
- ssh-keygen(1) — Abschnitte CERTIFICATES und KEY REVOCATION LISTS, alle Schalter zum Signieren und Widerrufen.
- sshd_config(5) — TrustedUserCAKeys, HostCertificate, AuthorizedPrincipalsFile, AuthorizedPrincipalsCommand, RevokedKeys, CASignatureAlgorithms.
- sshd(8) — Aufbau von authorized_keys und known_hosts samt der Marker @cert-authority und @revoked.
- ssh_config(5) — CertificateFile und das automatische Laden von
-cert.pubneben IdentityFile. - ssh(1) — Optionen des Clients, unter anderem
-iund die Ausgabe von-v. - OpenSSH 5.4 Release Notes vom 08.03.2010 — die Ankündigung der Zertifikatsunterstützung im Wortlaut.
- PROTOCOL.certkeys — die Formatbeschreibung, Begründung gegen X.509, Liste der critical options und extensions.
- OpenSSH-Projektseite — Quelltext, Release Notes und Sicherheitshinweise; aktuell ist dort OpenSSH 10.5 vom 11.08.2026 verzeichnet.
- Auf yourdevice.ch: Sicher per SSH einloggen, Server SSH Zugang mit YubiKey absichern, systemd-Timer statt Cronjob und Unterwegs sicher und stabil arbeiten mit SSHFS.