Wozu die Datei dient
Ein SSH-Client muss wissen, dass er mit dem echten Server spricht, bevor er ein Passwort sendet oder einen Befehl ausführt. Bei der ersten Verbindung zeigt er den Fingerprint des Servers und fragt nach. Akzeptieren Sie, wandert der öffentliche Schlüssel in known_hosts. Bei späteren Verbindungen läuft die Prüfung automatisch, und ein anderer Schlüssel führt zum Fehler REMOTE HOST IDENTIFICATION HAS CHANGED.
Die Datei enthält nur öffentliche Schlüssel. Sie enthält keine Geheimnisse, verrät aber, welche Server Sie nutzen.
Das Format
203.0.113.10 ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIGYt...
[server]:2222 ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIMJi...
server,203.0.113.10 ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAAB...
Jede Zeile enthält die Hostnamen, den Schlüsseltyp und den Schlüssel. Ein anderer Port als 22 wird in eckigen Klammern geschrieben, etwa [server]:2222. Namen können eine kommagetrennte Liste sein und Platzhalter enthalten. Davor können zwei optionale Markierungen stehen: @cert-authority für einen CA-Schlüssel und @revoked für einen Schlüssel, der nie akzeptiert werden darf. Mit SSH-Host-Zertifikaten kann eine einzige CA-Zeile eine Zeile pro Server ersetzen.
Der Client liest außerdem eine systemweite Datei, /etc/ssh/ssh_known_hosts, die ein Administrator für alle befüllen kann.
Gehashte Einträge
|1|eoQ3SZFlQ/5gRWuuw3MoS+AtytA=|BlzFc5MrVrt8iIEm7rloTmKPRBo= ssh-ed25519 AAAAC3Nz...
Bei einer Zeile, die mit |1| beginnt, ist der Hostname gehasht, sodass jemand, der die Datei stiehlt, keine fertige Liste Ihrer Server erhält. ssh findet den Eintrag trotzdem. Gesteuert wird das über HashKnownHosts. Der OpenSSH-Standard ist no, aber Debian schaltet es in /etc/ssh/ssh_config ein, Sie sehen also beide Formen.
Um eine bestehende Datei zu hashen:
ssh-keygen -H
Dabei bleibt das Original als known_hosts.old im Klartext erhalten. Löschen Sie diese Kopie, wenn Sie es aus Datenschutzgründen getan haben.
Alltägliche Befehle
Diese funktionieren auch mit gehashten Dateien. Mit -f file nutzen Sie eine andere Datei als die Standarddatei.
| Ziel | Befehl |
|---|---|
| Eintrag eines Hosts finden | ssh-keygen -F server |
| Einen auf einem anderen Port finden | ssh-keygen -F '[server]:2222' |
| Fingerprint dieses Hosts anzeigen | ssh-keygen -lF server |
| Alle Fingerprints auflisten | ssh-keygen -lf ~/.ssh/known_hosts |
| Einen Host entfernen | ssh-keygen -R server |
Mit -F ist der Exit-Code 1, wenn der Host nicht gefunden wird, was in Skripten nützlich ist. -R endet in beiden Fällen mit 0.
So prüfen Sie einen Fingerprint
Bei der ersten Verbindung sehen Sie Folgendes:
The authenticity of host 'server (203.0.113.10)' can't be established.
ED25519 key fingerprint is: SHA256:iU7+QOFWSHJeCFBdzU31dTOoJRNhncp+Wzw3UJMzasU
This key is not known by any other names.
Are you sure you want to continue connecting (yes/no/[fingerprint])?
Ein yes ohne Prüfung bedeutet, allem zu vertrauen, was geantwortet hat. Um richtig zu prüfen, holen Sie den Wert von einer Stelle, die nicht über diese Verbindung läuft, etwa der Konsole Ihres Anbieters oder von der Person, die den Server betreibt. Auf dem Server:
sudo ssh-keygen -lf /etc/ssh/ssh_host_ed25519_key.pub
Vergleichen Sie die Werte, oder fügen Sie am Prompt statt yes den richtigen Fingerprint ein, dann vergleicht ssh für Sie. In unserem Test wurde der richtige Wert akzeptiert, und ein falscher ergab Please type 'yes', 'no' or the fingerprint:.
ssh-keyscan und sein Vertrauensproblem
ssh-keyscan -t ed25519 server >> ~/.ssh/known_hosts
Das holt den öffentlichen Schlüssel eines Servers und taucht häufig in Setup-Skripten und CI-Jobs auf. Das Problem: Es prüft nichts. Es speichert alles, was geantwortet hat, ein Angreifer auf dem Weg bekommt also seinen Schlüssel eingetragen, und der Angriff ist ab diesem Moment unsichtbar.
Es ist in Ordnung, wenn Sie das Ergebnis anschließend prüfen:
ssh-keyscan -t ed25519 server | ssh-keygen -lf -
Für CI ist es besser, die erwartete known_hosts-Zeile als Wert in Ihrer Pipeline zu speichern und diese in die Datei zu schreiben.
Die Werte von StrictHostKeyChecking
| Wert | Neuer Host | Geänderter Schlüssel |
|---|---|---|
ask (Standard) | Fragt Sie | Lehnt ab |
yes | Lehnt ab | Lehnt ab |
accept-new | Fügt ihn hinzu | Lehnt ab |
no oder off | Fügt ihn hinzu | Verbindet, mit Einschränkungen |
accept-new ist die sinnvolle Wahl für Automatisierung: Es vertraut beim ersten Mal und erkennt spätere Änderungen. yes ist am strengsten und passt zu Serverparks, in denen Sie known_hosts selbst verteilen. Damit ergibt ein unbekannter Host:
No ED25519 host key is known for server and you have requested strict checking.
Host key verification failed.
Vermeiden Sie no. Es verbindet sich mit einem Host, dessen Schlüssel sich geändert hat, und genau diesen Fall soll diese Datei erkennen.
UpdateHostKeys
Ein Server kann einem Client nach der Anmeldung alle seine Host-Schlüssel mitteilen. Mit UpdateHostKeys fügt der Client sie zu known_hosts hinzu. So kann ein Administrator einen neuen Schlüssel ergänzen, warten, bis die Clients ihn kennen, und dann den alten ohne Warnungen entfernen. Wir haben UpdateHostKeys=yes getestet: Ausgehend von nur dem ED25519-Eintrag fügte eine Anmeldung RSA- und ECDSA-Zeilen hinzu.
Laut Handbuch ist es standardmäßig an, wenn Sie UserKnownHostsFile nicht geändert und VerifyHostKeyDNS nicht aktiviert haben. Es akzeptiert nur Schlüssel von einem Host, dem Sie über Ihre eigene Datei bereits vertrauen, nicht über eine globale Datei, und es greift nicht, wenn sich der Host mit einem Zertifikat authentifiziert hat.
SSHFP: Fingerprints im DNS
Fingerprints von Host-Schlüsseln lassen sich auch als SSHFP-Records im DNS veröffentlichen. Dieser Befehl gibt die Records aus, die für einen Server hinzuzufügen sind, auszuführen auf diesem Server:
ssh-keygen -r example.com
Clients nutzen sie mit VerifyHostKeyDNS yes. Automatisch vertraut wird nur, wenn die DNS-Antwort gesichert ist, was in der Praxis signierte Zonen und einen Resolver bedeutet, der sie validiert. Andernfalls verhält es sich wie ask: Es zeigt Ihnen die Übereinstimmung, und Sie bestätigen trotzdem. Der Standard ist no.
Fragen
Wo liegt die Datei known_hosts?
In ~/.ssh/known_hosts in Ihrem Home-Ordner, auf jedem System mit OpenSSH. Zusätzlich kann es eine systemweite Datei unter /etc/ssh/ssh_known_hosts geben.
Kann ich known_hosts löschen?
Sie enthält nur öffentliche Schlüssel, Geheimes geht also nicht verloren. Aber ssh fragt dann bei jedem Server erneut, und Sie verlieren die Prüfung, die einen geänderten Schlüssel erkennt. Entfernen Sie besser einen einzelnen Host mit ssh-keygen -R.
Wie entferne ich einen Host aus known_hosts?
Führen Sie ssh-keygen -R server aus, geschrieben als '[server]:2222', wenn der Port nicht 22 ist. Das funktioniert auch bei gehashten Dateien.
Quellen
- sshd(8), Format der Datei SSH_KNOWN_HOSTS
- ssh_config(5), OpenBSD-Handbuch
- ssh-keygen(1), OpenBSD-Handbuch
- ssh-keyscan(1), OpenBSD-Handbuch