Permission denied (publickey) ist der am häufigsten getroffene SSH-Fehler, den es gibt, und die Meldung tut dir keinen Gefallen. Sie bedeutet nicht „dein Schlüssel ist falsch“. Sie bedeutet: Der Server hat jede Authentifizierungsmethode abgelehnt, die du angeboten hast, und Public Key war die einzige Methode, über die er zu reden bereit war. Der Klammerzusatz ist die Liste der Methoden, die der Server noch offen lässt – (publickey) heißt, die Passwort-Authentifizierung ist aus, also muss ein Schlüssel funktionieren, und keiner von deinen tat es.
Die Liste kann länger sein, und es lohnt sich, sie zu lesen. Permission denied (publickey,password) heißt, der Server würde auch ein Passwort nehmen – wenn du also eins tippen wolltest und nie danach gefragt wurdest, hat dein Client die Schlüssel aufgegeben und hätte zurückfallen sollen; erzwing die Abfrage zum Testen mit -o PubkeyAuthentication=no. Permission denied (publickey,keyboard-interactive) ist dieselbe Idee mit einer interaktiven Methode (oft eine PAM-Abfrage oder 2FA) noch im Spiel. Was auch immer in den Klammern steht, ist die vollständige Menge an Türen, die der Server offen gelassen hat; wenn die erwartete nicht aufgeführt ist, hätte der Server sie nie akzeptiert.
Das ist ein weites Netz: Der falsche Benutzername erzeugt diesen Fehler. Ebenso ein Schlüssel, den der Client nie angeboten hat, ein Schlüssel, den der Server nie erhielt, ein Berechtigungsproblem, das sshd still nicht übergeht, und ein SELinux-Label, von dem du nie gehört hast. Die Lösung ist systematisch, kein Raten – hier die Schleife, dann die Übeltäter in der Reihenfolge, wie oft sie tatsächlich die Antwort sind. (Du pushst zu GitHub oder GitLab? Das ist eine andere Checkliste – GitHub-/GitLab-SSH-Schlüssel funktioniert nicht.)
Die Diagnose-Schleife: lies, was der Client versucht hat
Führ die scheiternde Verbindung mit maximaler Ausführlichkeit aus (und wenn die Wand aus Ausgabe wie Rauschen aussieht, entschlüsselt ssh -vvv lesen (auf Englisch) die Zeilen, auf die es ankommt):
ssh -vvv user@host
Drei Dinge, die du in der Ausgabe finden willst:
Authentications that can continue: publickey– die Methodenliste des Servers. Wennpasswordfehlt, wird nie nach einem Passwort gefragt; ein Schlüssel muss zum Erfolg führen.Offering public key: /home/you/.ssh/id_ed25519– jeder Schlüssel, den der Client versucht hat. Wenn der Schlüssel, den du meintest, nicht in dieser Liste steht, liegt das Problem auf Client-Seite (Übeltäter 2). Wenn doch –- was zurückkam.
Server accepts keygefolgt von einem Signaturaustausch heißt, der Schlüssel passte und etwas Späteres scheiterte (selten). Der übliche Anblick ist das Angebot, unmittelbar gefolgt vom nächsten Schlüssel oderPermission denied– der Server sah sich den Schlüssel an und zuckte mit den Schultern, was auf die Serverseite zeigt (Übeltäter 3–8).
Wenn du irgendeinen anderen Weg auf die Kiste hast (Web-Konsole des Anbieters, ein anderer Benutzer, ein anderer Admin), nennt das Server-Log den wahren Grund direkt:
sudo journalctl -u sshd -f # systemd distros
sudo tail -f /var/log/auth.log # Debian/Ubuntu
sudo tail -f /var/log/secure # RHEL/Alma/Rocky
Zeilen wie Authentication refused: bad ownership or modes for directory /home/deploy beenden die Untersuchung auf der Stelle.
Übeltäter 1: falscher Benutzer
Die mit Abstand häufigste Ursache, besonders bei Cloud-Images (es ist die erste Hürde beim ersten EC2- oder VPS-Login (auf Englisch)), weil der Login-Benutzer nicht der ist, den du raten würdest: ubuntu bei Ubuntu-Images, ec2-user bei Amazon Linux, admin bei Debian-AMIs, root bei den meisten nackten VPSes, azureuser bei Azure-Standards. Der richtige Schlüssel mit dem falschen Benutzernamen erzeugt genau diesen Fehler – der Server prüft ~wronguser/.ssh/authorized_keys, findet nichts, verweigert.
Bevor du irgendetwas anderes anfasst, bestätige den Benutzer, den dein Image dokumentiert, und fixiere ihn in ~/.ssh/config, damit du ihn nie neu tippst (der ssh_config-Leitfaden (auf Englisch) behandelt das Muster):
Host web1
HostName 203.0.113.10
User ubuntu
Übeltäter 2: dein Schlüssel wurde nie angeboten
Wenn ssh -vvv deinen Schlüssel nicht in einer Offering public key-Zeile zeigt, kennt der Client ihn nicht. Zeig ausdrücklich darauf:
ssh -i ~/.ssh/id_ed25519 user@host
Wenn das klappt, mach es mit IdentityFile im Konfigurationsblock oben dauerhaft. Zwei verwandte Fallen: Ein Agent, vollgestopft mit vielen Schlüsseln, kann das Versuchslimit des Servers auslösen, bevor er den richtigen erreicht (Too many authentication failures – behebbar mit IdentitiesOnly yes), und ein Schlüssel mit einer Passphrase, die du weggeklickt hast, wird still übersprungen. Prüf, was der Agent tatsächlich hält:
ssh-add -l
Unter Windows kann diese Liste leer wirken, selbst wenn du gerade einen Schlüssel geladen hast – Git Bash, der OpenSSH-Dienst und WSL betreiben jeweils einen eigenen Agenten, und ssh-add -l antwortet nur für das ssh, das du tatsächlich nutzt; ssh-agent unter Windows entwirrt die drei.
Übeltäter 3: der öffentliche Schlüssel liegt nicht auf dem Server
Die öffentliche Hälfte muss eine Zeile in ~user/.ssh/authorized_keys sein – für diesen Benutzer, im Home dieses Benutzers. Der zuverlässige Weg, sie dorthin zu bringen (nutzt Passwort-Authentifizierung oder einen vorhandenen Schlüssel für die Kopie):
ssh-copy-id -i ~/.ssh/id_ed25519.pub user@host
Von Hand – etwa über eine Anbieter-Konsole – häng die einzelne Zeile an und überschreib die Datei nie:
mkdir -p ~/.ssh && cat >> ~/.ssh/authorized_keys
# paste the one line from id_ed25519.pub, Enter, Ctrl-D
Klassische Fehlgriffe: Der Schlüssel landete in der Datei von root, aber du meldest dich als deploy an; die Zeile wurde von einem Editor umgebrochen und ist jetzt zwei Zeilen; du hast den privaten Schlüssel eingefügt (die Datei beginnt mit ssh-ed25519 AAAA… – wenn du -----BEGIN siehst, ist das die falsche Hälfte).
Übeltäter 4: Berechtigungen und Eigentümer
sshds StrictModes (standardmäßig an) weigert sich, authorized_keys zu beachten, wenn der Pfad dorthin von jemand anderem als dem Eigentümer beschreibbar ist. Das ist das klassische „Ich habe den Schlüssel kopiert, und er funktioniert trotzdem nicht“. Die vollständige Lösung, ausgeführt als der Zielbenutzer:
chmod go-w ~
chmod 700 ~/.ssh
chmod 600 ~/.ssh/authorized_keys
chown -R $USER:$USER ~/.ssh
Die Zeile zum Home-Verzeichnis zählt und wird vergessen: Ein gruppenschreibbares /home/deploy scheitert an der Prüfung genauso hart wie eine für alle lesbare Schlüsseldatei. Die Zeile bad ownership or modes im Server-Log sagt dir genau, welches Verzeichnis es bemängelt.
Übeltäter 5: falsches Schlüsselformat oder falsche Passphrase
OpenSSH kann PuTTYs .ppk-Dateien nicht lesen – -i darauf zu richten scheitert mit invalid format in der ausführlichen Ausgabe. Exportiere einen Schlüssel im OpenSSH-Format aus PuTTYgen (Conversions → Export OpenSSH key) oder erzeug einen frischen, modernen Schlüssel und trag ihn ein (Ed25519, in fast allen Fällen (auf Englisch)). Wenn du unter Windows noch in PuTTYgen feststeckst, nimmt dir ein SSH-Client für Windows, der PuTTY-Sitzungen importiert und OpenSSH-Schlüssel direkt nutzt, diesen Umwandlungsschritt komplett ab. Um zu prüfen, ob eine private Schlüsseldatei lesbar ist und die Passphrase die ist, die du denkst, lass sie ihre öffentliche Hälfte ausgeben:
ssh-keygen -y -f ~/.ssh/id_ed25519
Wenn das einen Schlüssel ausgibt, sind Datei und Passphrase in Ordnung – und du kannst die Ausgabe gegen die Zeile in authorized_keys diffen, um zu bestätigen, dass es tatsächlich derselbe Schlüssel ist.
Übeltäter 6: die Server-Konfiguration verbietet es
Seltener, aber billig zu prüfen, wenn du Server-Zugriff hast. Frag sshd, womit es tatsächlich läuft:
sudo sshd -T | grep -Ei 'pubkeyauthentication|authorizedkeysfile'
PubkeyAuthentication muss yes sein (Standard, aber Härtungsskripte legen es manchmal um), und AuthorizedKeysFile sagt dir, wo sshd sucht – wenn jemand es auf /etc/ssh/authorized_keys/%u gerichtet hat, wird deine sorgfältig platzierte ~/.ssh/authorized_keys ignoriert. Nach jeder Änderung an /etc/ssh/sshd_config:
sudo systemctl reload sshd
Übeltäter 7: SELinux-Kontexte (RHEL-Familie)
Auf RHEL, Alma, Rocky, Fedora und Verwandten kann ein ~/.ssh, das auf ungewöhnliche Weise entstanden ist – aus einem Backup wiederhergestellt, als root kopiert, auf einem gemounteten Volume angelegt –, das falsche SELinux-Label tragen, und sshd wird der Lesezugriff auf eine Datei mit perfekten Berechtigungen verweigert. Alles oben stimmt, der Fehler bleibt, und ls -Z ~/.ssh zeigt etwas anderes als ssh_home_t. Ein Befehl repariert die Labels:
restorecon -R -v ~/.ssh
Wenn dir auf einer Kiste der RHEL-Familie die Ideen ausgehen, führ ihn trotzdem aus – er ist harmlos, wenn die Labels schon richtig waren.
Übeltäter 8: der root-Login ist deaktiviert
Moderne Standards setzen PermitRootLogin prohibit-password (nur Schlüssel) oder no (nie). Wenn du root@host versuchst und der Schlüssel wirklich in /root/.ssh/authorized_keys liegt, prüf:
sudo sshd -T | grep -i permitrootlogin
Bei no funktioniert nie ein Zugangsmittel für root – melde dich als unprivilegierter Benutzer an und nutz sudo, worauf dich der Standard ohnehin hinlenkt.
Schnelle Antworten
Heißt Permission denied (publickey), dass mein Schlüssel beschädigt ist?
Fast nie. Es heißt, der Server hat keine der von dir angebotenen Methoden akzeptiert – meist der falsche Benutzer oder der falsche Schlüssel, kein kaputter Schlüssel. Bestätige mit ssh-keygen -y -f ~/.ssh/id_ed25519, dass der Schlüssel lesbar und die Passphrase richtig ist.
Was ist der Unterschied zwischen (publickey) und (publickey,password)?
Die Klammern listen die Methoden auf, die der Server noch erlaubt. (publickey) sind nur Schlüssel; (publickey,password) heißt, ein Passwort würde auch gehen, du hättest also gefragt werden sollen – wenn nicht, hat dein Client aufgegeben, nachdem die Schlüssel erschöpft waren.
Gestern ging es, heute scheitert es – was hat sich geändert?
Ein neu aufgesetzter Server, ein rotierter Schlüssel oder ein Agent, der den Schlüssel nach einem Timeout fallen ließ. Führ zuerst ssh-add -l aus, um zu sehen, was geladen ist, dann prüf, ob die Kiste neu abgebildet wurde (was auch host key verification failed (auf Englisch) auslöst).
Dafür sorgen, dass es aufhört
Fast jeder Übeltäter oben ist eine Tatsache pro Host, die du nicht erneut herleiten solltest: welcher Benutzer, welcher Schlüssel, welcher Port. Fixiere sie in ~/.ssh/config, und die Fehlerklasse verschwindet weitgehend – und für die verbleibenden Fehler deckt SSH-Fehler entschlüsselt die anderen neun ab, auf die du triffst.
Dieselben Tatsachen können in einem Client wohnen statt in einer Dotfile. Termalin speichert Benutzer, Port und Schlüssel beim gespeicherten Host, entsperrt deine Schlüssel einmal über seinen integrierten Agenten (kein weggeklicktes Passphrase-Prompt, das still einen Schlüssel überspringt), verifiziert die Identität des Servers beim ersten Verbinden und zeigt Live-Status pro Host – sodass „läuft die Kiste überhaupt?“ und „nutze ich den richtigen Schlüssel?“ keine Diagnoseschritte mehr sind. Es importiert außerdem PuTTY-Sitzungen (auf Englisch) direkt, was Übeltäter 5 endgültig in Rente schickt.
Termalin ist ein kostenloser, plattformübergreifender SSH-Client, der Benutzer, Ports und Schlüssel pro Host beim Host hält und Server beim ersten Verbinden verifiziert – lade es herunter oder lies, wie es Schlüssel sicher verwahrt.