Was Sie sehen
In einem Skript mit BatchMode=yes oder ohne Terminal für Rückfragen erscheint nur eine einzige Zeile:
Host key verification failed.
Mit StrictHostKeyChecking=yes steht darüber ein Grund:
No ED25519 host key is known for server and you have requested strict checking.
Host key verification failed.
Git fügt eigene Zeilen hinzu, die nicht bedeuten, dass das Repository fehlt:
Host key verification failed.
fatal: Could not read from remote repository.
Herausfinden, welcher Fall vorliegt
Führen Sie dies als derselbe Benutzer aus, der den fehlgeschlagenen Befehl ausführt:
ssh-keygen -F server
Bei einem Server auf einem anderen Port wird der Eintrag mit eckigen Klammern gespeichert:
ssh-keygen -F '[server]:2222'
- Keine Ausgabe: Der Host ist diesem Benutzer unbekannt. Siehe Ursache 1 und Ursache 2.
- Eine Zeile wird ausgegeben und der Fehler zeigt eine große Warnung REMOTE HOST IDENTIFICATION HAS CHANGED: siehe Ursache 3.
Ursache 1: Der Server steht nicht in known_hosts
An einem Terminal würde SSH Sie bitten, den Fingerprint zu bestätigen. BatchMode=yes verbietet Fragen, und ein Job ohne Terminal hat niemanden, den er fragen kann, also schlägt SSH fehl. Tragen Sie den Schlüssel vorher ein.
Holen Sie den Schlüssel und vergleichen Sie ihn mit dem auf dem Server, bevor Sie ihm vertrauen:
ssh-keyscan -t ed25519 server > server.hostkey
ssh-keygen -lf server.hostkey
Auf dem Server selbst oder über eine Konsole Ihres Anbieters:
ssh-keygen -lf /etc/ssh/ssh_host_ed25519_key.pub
Stimmen die beiden Fingerprints überein, installieren Sie den Schlüssel:
mkdir -p ~/.ssh && chmod 700 ~/.ssh
cat server.hostkey >> ~/.ssh/known_hosts
Für einen anderen Port als 22 nehmen Sie ssh-keyscan -p 2222 -t ed25519 server. ssh-keyscan allein beweist nichts, denn es akzeptiert alles, was an dieser Adresse antwortet. Erst der Vergleich macht es sicher. Hosting-Dienste veröffentlichen ihre Fingerprints, zum Beispiel GitHub auf der Seite, die in den Quellen steht.
In CI
Speichern Sie die geprüfte Zeile als CI-Variable und schreiben Sie sie am Anfang des Jobs in die Datei, statt bei jedem Lauf zu scannen:
mkdir -p ~/.ssh && chmod 700 ~/.ssh
printf '%s\n' "$KNOWN_HOSTS" >> ~/.ssh/known_hosts
accept-new und no
StrictHostKeyChecking=accept-new speichert einen noch nie gesehenen Schlüssel und lehnt trotzdem einen geänderten ab. Es vertraut der ersten Verbindung ohne Prüfung, was für eine Wegwerf-Maschine in einem Netz, dem Sie vertrauen, ein vertretbarer Kompromiss ist. Vermeiden Sie StrictHostKeyChecking=no: Damit läuft die Verbindung auch dann weiter, wenn sich der Schlüssel geändert hat, und genau dafür gibt es diese Prüfung.
Was jede Zeile der Datei enthält: known_hosts erklärt.
Ursache 2: ein anderer Benutzer oder ein anderes HOME
known_hosts gehört einem Benutzer. Es funktioniert in Ihrem Terminal und scheitert im Job, wenn der Job als jemand anderes läuft: sudo ssh nutzt die Datei von root, und cron, Docker-Builds und CI-Runner haben ein eigenes Home-Verzeichnis, das bei jedem Lauf oft leer ist.
whoami
echo "$HOME"
ssh -G server | grep -iE '^(userknownhostsfile|stricthostkeychecking) '
Der letzte Befehl zeigt, welche Dateien SSH für diesen Host liest, ohne eine Verbindung aufzubauen. Installieren Sie den Schlüssel für diesen Benutzer oder verweisen Sie den Job auf eine Datei, die Sie kontrollieren:
ssh -o UserKnownHostsFile=/path/to/known_hosts -o BatchMode=yes user@server true
Ursache 3: Der gespeicherte Schlüssel ist ein anderer
Die Ausgabe beginnt dann mit dieser Warnung, und die letzten beiden Zeilen lauten:
Host key for server has changed and you have requested strict checking.
Host key verification failed.
Eine Neuinstallation oder ein neuer Server unter derselben Adresse ist der übliche Grund, aber genau so sieht auch ein Abfangen der Verbindung aus. accept-new kommt daran nicht vorbei. Vergleichen Sie die Fingerprints wie oben gezeigt und entfernen Sie erst dann den alten Eintrag:
ssh-keygen -R server
Bei github.com ist das häufig: GitHub hat im März 2023 seinen RSA-Host-Schlüssel ersetzt, deshalb scheitert eine ältere gespeicherte Zeile jetzt. Entfernen Sie sie mit ssh-keygen -R github.com und fügen Sie dann die Schlüssel hinzu, die GitHub veröffentlicht, von der Seite in den Quellen.
Mehr zu diesem Fall unter REMOTE HOST IDENTIFICATION HAS CHANGED.
Fragen
Was bedeutet Host key verification failed?
SSH konnte die Identität des Servers nicht bestätigen und hat abgebrochen. Entweder steht der Server nicht in known_hosts und niemand konnte die Frage beantworten, oder sein Schlüssel weicht vom gespeicherten ab.
Ist StrictHostKeyChecking=no in CI eine sichere Lösung?
Nein. Es akzeptiert auch einen geänderten Schlüssel. Installieren Sie den geprüften Schlüssel in known_hosts, oder nutzen Sie accept-new auf Wegwerf-Maschinen in einem vertrauenswürdigen Netz.
Warum klappt es im Terminal, aber nicht in cron?
known_hosts gehört zu einem Benutzer. Cron, sudo und CI-Runner nutzen einen anderen Benutzer oder ein anderes Home-Verzeichnis, in dem der gespeicherte Eintrag fehlt.
Warum meldet git bei GitHub Host key verification failed?
Entweder fehlt github.com in der known_hosts des Benutzers, der git ausführt, oder dort steht noch eine RSA-Zeile von vor März 2023. Entfernen Sie sie mit ssh-keygen -R github.com und fügen Sie die Schlüssel von GitHubs Fingerprint-Seite hinzu.
Quellen
- ssh_config(5), StrictHostKeyChecking
- ssh-keyscan(1), OpenBSD-Handbuch
- ssh-keygen(1), OpenBSD-Handbuch
- SSH-Schlüssel-Fingerprints von GitHub