SSH-Fehler "Permission denied (publickey)" beheben

Veröffentlicht am 17 Min. Lesezeit

Der SSH-Login scheitert mit Permission denied (publickey)? Sieben Ursachen von Dateirechten über AllowUsers bis SELinux, jeweils mit Logzeile im Wortlaut und der passenden Gegenmaßnahme.

Der Verbindungsversuch bricht nach einer Sekunde ab, es kommt kein Passwortprompt, nur eine einzige Zeile: Permission denied (publickey). Diese Meldung ist deshalb so unangenehm, weil sie absichtlich nichts verrät. Der SSH-Server sagt einem potenziellen Angreifer nicht, ob der Benutzer existiert, ob der Schlüssel falsch war oder ob die Datei unlesbar ist. Genau dieselbe Zurückhaltung trifft aber auch dich, wenn du legitim vor der Tür stehst.

Die gute Nachricht: die Ursachen sind endlich, sie lassen sich in einer festen Reihenfolge abklopfen, und in den meisten Fällen sind es schlicht die Dateirechte. Dieser Beitrag geht die Ursachen in der Reihenfolge ihrer Häufigkeit durch, zeigt zu jeder den Wortlaut im Log und erklärt, wie du mit ssh -vvv in dreißig Sekunden entscheidest, ob das Problem auf deinem Rechner oder auf dem Server liegt.

Was die Meldung genau bedeutet

Die Klammer am Ende ist kein Zierrat, sie ist die wichtigste Information der ganzen Zeile. Darin steht, welche Authentifizierungsverfahren der Server nach dem gescheiterten Versuch noch anbietet:

Permission denied (publickey).
Permission denied (publickey,password).
Permission denied (publickey,gssapi-keyex,gssapi-with-mic).

Steht dort nur publickey, ist die Passwortanmeldung auf dem Server abgeschaltet. Steht password mit in der Liste, wäre eine Passwortanmeldung grundsätzlich möglich gewesen, sie wurde nur nicht versucht oder ist ebenfalls gescheitert. Die Variante mit gssapi ist typisch für AlmaLinux, Rocky Linux und RHEL, dort ist Kerberos-Unterstützung mit einkompiliert.

Wichtig ist die Abgrenzung zu Meldungen, die ähnlich aussehen, aber ein völlig anderes Problem beschreiben:

  • Permission denied, please try again. ohne Klammer ist ein falsches Passwort, kein Schlüsselproblem.
  • Host key verification failed. betrifft den Serverschlüssel in deiner known_hosts, nicht deinen eigenen Schlüssel.
  • Received disconnect from 203.0.113.7 port 22:2: Too many authentication failures heißt, dass dein Agent zu viele Schlüssel nacheinander angeboten hat und der Server nach MaxAuthTries abgebrochen hat.
  • Connection refused oder ein Timeout sind Netz- oder Firewallthemen. Wenn du dich vorher an einer UFW-Firewall oder an Fail2ban zu schaffen gemacht hast, fang dort an.

Die Weggabelung: ssh -vvv richtig lesen

Bevor du irgendetwas änderst, lass dir den Ablauf zeigen. Drei v sind Absicht, bei einem v fehlen die entscheidenden Zeilen:

ssh -vvv deploy@203.0.113.7

Die Ausgabe ist lang, aber du suchst nur vier Stellen. Erstens den Benutzernamen, mit dem tatsächlich verbunden wird:

debug1: Authenticating to 203.0.113.7:22 as 'deploy'

Zweitens, welche Schlüssel der Client überhaupt in Betracht zieht, und drittens, welchen er wirklich sendet:

debug1: Will attempt key: /home/tom/.ssh/id_ed25519 ED25519 SHA256:8Qk... agent
debug1: Offering public key: /home/tom/.ssh/id_ed25519 ED25519 SHA256:8Qk... agent
debug1: Authentications that can continue: publickey
debug1: No more authentication methods to try.

Und viertens die Erfolgsmeldung, die im Fehlerfall eben fehlt:

debug1: Server accepts key: /home/tom/.ssh/id_ed25519 ED25519 SHA256:8Qk...
debug1: Authenticated to 203.0.113.7 ([203.0.113.7]:22) using "publickey".

Daraus ergibt sich die Weggabelung, die dir die halbe Fehlersuche spart:

  • Es erscheint kein Offering public key mit deinem Schlüssel. Dann liegt das Problem auf deinem Rechner, der Schlüssel wurde nie gesendet. Springe zu Ursache 3.
  • Es erscheint Offering public key, aber danach wieder Authentications that can continue. Dann hat der Server deinen Schlüssel gesehen und abgelehnt. Das sind die Ursachen 1, 2, 4, 5 und 6, alle serverseitig.
  • Es erscheint send_pubkey_test: no mutual signature algorithm. Dann ist der Schlüsseltyp das Thema, springe zu Ursache 7.

Zwei weitere Zeilen aus der Debugausgabe lohnen einen Blick. debug3: no such identity: /home/tom/.ssh/id_rsa: No such file or directory ist harmlos, der Client probiert schlicht alle Standardnamen durch. Permissions 0644 for '/home/tom/.ssh/id_ed25519' are too open. dagegen ist ein echter Treffer, dein privater Schlüssel wird dann ignoriert.

Die Serverseite: sshd -T und die Logs

ssh -vvv zeigt ausschließlich die Sicht des Clients. Warum der Server abgelehnt hat, steht nur im Serverlog. Sofern du noch eine offene Sitzung hast oder über die Konsole im Kundenbereich hereinkommst, sieh dort zuerst nach.

Auf Debian und Ubuntu heißt der Dienst ssh, auf AlmaLinux, Rocky Linux und RHEL heißt er sshd. Das ist eine klassische Stolperfalle beim Kopieren von Befehlen:

journalctl -u ssh -n 50 --no-pager      # Debian, Ubuntu
journalctl -u sshd -n 50 --no-pager     # AlmaLinux, Rocky, RHEL

Die klassische Textdatei gibt es nicht mehr überall. Ubuntu 22.04 und 24.04 führen in der Serverinstallation weiterhin /var/log/auth.log, weil rsyslog dort mitgeliefert wird. Debian 12 und Debian 13 installieren rsyslog in einer Minimalinstallation nicht mehr mit, dort existiert die Datei schlicht nicht und alles landet im Journal. Auf der Red-Hat-Familie heißt die Datei /var/log/secure. Wer die Textdatei auf Debian zurück will, installiert rsyslog nach, auf Debian und Ubuntu mit apt-get install -y rsyslog, auf der Red-Hat-Familie mit dnf install -y rsyslog.

Der zweite Serverbefehl ist noch wichtiger, weil er die tatsächlich wirksame Konfiguration ausgibt und dabei alle eingebundenen Dateien auflöst:

sshd -T | grep -Ei 'pubkeyauth|authorizedkeysfile|strictmodes|permitrootlogin'

Antwortet der Befehl statt einer Konfiguration nur mit Missing privilege separation directory: /run/sshd und gibt keine einzige Zeile aus, fehlt schlicht ein Laufzeitverzeichnis. Das passiert auf Debian 11, Debian 12, Ubuntu 22.04 und Ubuntu 24.04 unmittelbar nach der Paketinstallation, solange der Dienst noch nie gestartet wurde, und in Containern. Im Normalbetrieb legt die systemd-Unit das Verzeichnis über RuntimeDirectory=sshd selbst an. Erscheint die Meldung, hilft ein vorgeschaltetes mkdir -p /run/sshd, danach liefert sshd -T sauber permitrootlogin, pubkeyauthentication yes, strictmodes yes und authorizedkeysfile. Debian 13 mit OpenSSH 10 und die gesamte Red-Hat-Familie kennen die Einschränkung nicht mehr. Achte darauf, dass die Meldung in einer Pipe untergeht: sshd -T | grep ... zeigt dann nur eine leere Ausgabe, der eigentliche Rückgabewert 255 verschwindet im grep.

Und wenn du wirklich sehen willst, was der Server denkt, ohne den laufenden Dienst anzufassen: starte eine zweite Instanz im Debugmodus auf einem freien Port. Sie beendet sich nach einer Verbindung von selbst und kann dich nicht aussperren.

/usr/sbin/sshd -ddd -p 2222

Von deinem Rechner aus dann ssh -p 2222 deploy@203.0.113.7, und im Terminal des Servers steht die Ablehnung im Klartext. Der Port muss dafür natürlich in der Firewall offen sein.

Ursache 1: Rechte und Eigentümer, der mit Abstand häufigste Fall

OpenSSH hat die Option StrictModes yes standardmäßig aktiv. Der Server weigert sich, einen Schlüssel aus einer Datei zu lesen, auf die außer dem Benutzer selbst noch jemand schreiben könnte. Das ist keine Schikane, sondern verhindert, dass ein anderer Nutzer sich einfach seinen eigenen Schlüssel in dein authorized_keys schreibt.

Der Sollzustand ist eng definiert:

chmod 700 ~/.ssh
chmod 600 ~/.ssh/authorized_keys
chmod 750 ~
chown -R "$(id -un):$(id -gn)" ~/.ssh

Nachprüfen lässt sich das in einer Zeile:

stat -c "%a %U %G %n" ~ ~/.ssh ~/.ssh/authorized_keys

Erwartet werden 750 oder 700 für das Heimatverzeichnis, 700 für .ssh und 600 für authorized_keys, und in allen drei Zeilen dein eigener Benutzername. Entscheidend ist: das Heimatverzeichnis darf für Gruppe und andere nicht schreibbar sein, 770 oder 777 reichen also schon zum Scheitern.

Eine Zahl darfst du dabei nicht als Fehler missdeuten: Auf AlmaLinux, Rocky Linux und Oracle Linux hat /root die Rechte 550, nicht 700 wie auf Debian und Ubuntu. stat -c zeigt das korrekt an, und es ist völlig in Ordnung. Für StrictModes zählt nur, dass Gruppe und andere kein Schreibrecht haben, und genau das erfüllt 550. Wer hier ein chmod 700 /root nachschiebt, hat den Login damit nicht repariert, sondern nur die Ursache weiter verdeckt.

Im Serverlog steht dann sehr deutlich:

Authentication refused: bad ownership or modes for directory /home/deploy/.ssh
Authentication refused: bad ownership or modes for file /home/deploy/.ssh/authorized_keys
error: Could not open authorized keys '/home/deploy/.ssh/authorized_keys': Permission denied

Zwei Details, die andere Anleitungen gern auslassen. Erstens der Eigentümer: wenn du die Datei mit sudo nano ~/.ssh/authorized_keys angelegt hast, gehört sie root und nicht dem Benutzer, und der Login scheitert trotz perfekter 600-Rechte. Zweitens prüft sshd den gesamten Pfad nach oben. Liegt das Heimatverzeichnis nicht unter /home, sondern etwa unter /srv/kunden/deploy, müssen auch /srv und /srv/kunden root oder dem Benutzer gehören und dürfen für Gruppe und andere nicht schreibbar sein.

Ursache 2: Der falsche Benutzername

Ein nicht existierender Benutzer erzeugt exakt dieselbe Meldung wie ein falscher Schlüssel, denn der Server verrät bewusst nicht, welcher der beiden Fälle vorliegt. Im Log sieht man den Unterschied sofort:

Invalid user deply from 203.0.113.7 port 51234

Der häufigste Auslöser ist, dass der Schlüssel in /root/.ssh/authorized_keys liegt, du dich aber als regulärer Benutzer anmeldest, oder umgekehrt. Bei fertigen Cloud-Abbildern ist der root-Login oft gesperrt und es existiert stattdessen ein vorbereiteter Benutzer, je nach Distribution debian, ubuntu, almalinux oder rocky. Bei den Standardabbildern auf einem KernelHost-Rootserver meldest du dich dagegen direkt als root an.

Prüfe außerdem, ob deine ~/.ssh/config dir einen anderen Benutzer unterschiebt. Der folgende Befehl baut keine Verbindung auf, sondern zeigt nur, welche Einstellungen für dieses Ziel tatsächlich gelten:

ssh -G deploy@203.0.113.7

In der Ausgabe interessieren user, hostname, port und die Liste der identityfile-Einträge.

Ursache 3: Der Schlüssel wird gar nicht angeboten

Wenn in ssh -vvv kein Offering public key mit deinem Schlüssel auftaucht, hat der Server nie eine Chance bekommen. Dafür gibt es vier typische Gründe.

Der Schlüssel hat einen eigenen Namen

Automatisch probiert OpenSSH nur die Standardnamen id_ed25519, id_ecdsa und id_rsa. Ein Schlüssel namens id_produktion wird nur benutzt, wenn du ihn nennst:

ssh -i ~/.ssh/id_produktion -o IdentitiesOnly=yes deploy@203.0.113.7

IdentitiesOnly=yes ist hier kein Beiwerk. Ohne diese Option bietet ssh zusätzlich alle Schlüssel aus dem Agent an, und bei zu vielen Versuchen bricht der Server mit Too many authentication failures ab, bevor der richtige Schlüssel überhaupt an der Reihe ist.

Der Agent hat den Schlüssel nicht

ssh-add -l

Antwortet der Befehl mit The agent has no identities. oder Could not open a connection to your authentication agent., lade den Schlüssel mit ssh-add ~/.ssh/id_ed25519 nach.

Rechte auf dem privaten Schlüssel

Der private Schlüssel muss 600 haben, sonst verweigert der Client den Dienst. Unter Windows greift chmod nicht, dort wird über ACLs gearbeitet:

icacls %USERPROFILE%\.ssh\id_ed25519 /inheritance:r /grant:r "%USERNAME%":R

Die Datei authorized_keys ist kaputt

Ein öffentlicher Schlüssel ist genau eine Zeile. Beim Kopieren über Editoren, Ticketsysteme oder Chatfenster wird daraus gern ein Umbruch mitten im Base64-Block, und dann passt nichts mehr. Zähle nach:

grep -c '^ssh-' ~/.ssh/authorized_keys
awk '{print NR": "NF" Felder, Typ "$1}' ~/.ssh/authorized_keys

Jede Zeile muss mit ssh-ed25519, ssh-rsa oder ecdsa-sha2- beginnen und aus zwei bis drei Feldern bestehen. Die Anzahl der Zeilen muss zur Anzahl der Schlüssel passen. Ein zweiter Klassiker ist, dass versehentlich der private statt der öffentliche Schlüssel eingetragen wurde, erkennbar an BEGIN OPENSSH PRIVATE KEY. Und ein Schlüssel im PuTTY-Format (.ppk) funktioniert so nicht, er muss erst nach OpenSSH exportiert werden.

Ob privater und öffentlicher Schlüssel zusammengehören, klärt ein Fingerabdruckvergleich:

ssh-keygen -lf ~/.ssh/id_ed25519.pub
ssh-keygen -lf ~/.ssh/authorized_keys

Derselbe SHA256-Wert muss in beiden Ausgaben vorkommen. Wie das Ganze sauber aufgesetzt aussieht, steht in unserem Beitrag zu SSH absichern und Key-Login einrichten.

Ursache 4: PubkeyAuthentication ist aus

Seltener, aber dann sehr eindeutig. Prüfe nicht die Konfigurationsdatei, sondern das Ergebnis:

sshd -T | grep -i pubkeyauthentication

Hier lauert eine Falle, die viele Stunden kostet. Debian ab Version 12 und Ubuntu ab 22.04 haben ganz oben in /etc/ssh/sshd_config die Zeile Include /etc/ssh/sshd_config.d/*.conf stehen. Bei sshd gilt: für jedes Schlüsselwort zählt der zuerst gefundene Wert. Weil die Einbindung am Anfang steht, gewinnt jede Kleinigkeit aus sshd_config.d gegen die Hauptdatei, egal was dort weiter unten steht. Wenn deine Änderung wirkungslos bleibt, sieh dort nach:

grep -rniE 'pubkeyauthentication|authorizedkeysfile|allowusers|allowgroups' /etc/ssh/

Der zweite Punkt in dieser Kategorie ist AuthorizedKeysFile. Standard sind .ssh/authorized_keys und .ssh/authorized_keys2. Manche Härtungsskripte setzen den Pfad auf etwas wie /etc/ssh/authorized_keys/%u. Danach wird deine Datei im Heimatverzeichnis komplett ignoriert, ohne jede Fehlermeldung. Auch das zeigt sshd -T.

Ursache 5: AllowUsers, AllowGroups und Match greifen

Diese Direktiven schneiden ganze Benutzergruppen ab, und zwar bevor der Schlüssel überhaupt geprüft wird. Der Wortlaut im Log:

User root from 203.0.113.7 not allowed because not listed in AllowUsers
User deploy from 203.0.113.7 not allowed because none of user's groups are listed in AllowGroups
User root from 203.0.113.7 not allowed because "PermitRootLogin no"

Merke dir die Rangfolge: DenyUsers schlägt AllowUsers, und sobald AllowUsers überhaupt gesetzt ist, sind alle nicht genannten Benutzer ausgesperrt. Bei AllowGroups muss die Gruppenmitgliedschaft stimmen, was du mit id deploy prüfst.

Bei PermitRootLogin ist die Unterscheidung wichtig: prohibit-password erlaubt den root-Login mit Schlüssel. Nur no sperrt root vollständig aus. Erwarte in der Ausgabe von sshd -T allerdings nicht das Wort prohibit-password: dort steht der ältere, gleichbedeutende Name without-password. Und der Vorgabewert ist keineswegs überall gleich, was beim Vergleich zweier Server regelmäßig für Verwirrung sorgt:

SystemWert aus sshd -T
Debian 11, 12, 13without-password
Rocky Linux 9, Oracle Linux 9without-password
AlmaLinux 9, AlmaLinux 10yes

Auf AlmaLinux darf root also auch mit Passwort herein, auf den übrigen genannten Systemen nicht. Wer einen Dienst von AlmaLinux nach Debian umzieht und sich bisher als root mit Passwort angemeldet hat, landet danach genau bei Permission denied (publickey).

Steckt die Regel in einem Match-Block, hilft die Option, die die Konfiguration für einen konkreten Fall auswertet:

sshd -T -C user=deploy,host=client.example.com,addr=203.0.113.7 | grep -Ei 'pubkeyauth|allowusers|permitrootlogin'

Das ist der zuverlässigste Weg, um zu sehen, was für genau diesen Benutzer von genau dieser IP-Adresse gilt.

Ursache 6: SELinux auf AlmaLinux, Rocky und RHEL

Auf der Red-Hat-Familie läuft SELinux standardmäßig im Modus Enforcing, auf Debian und Ubuntu spielt es keine Rolle. Der sshd-Prozess darf authorized_keys nur lesen, wenn die Datei den Kontext ssh_home_t trägt. Das ist der Fall, wenn sie normal im Heimatverzeichnis erzeugt wurde. Es ist nicht der Fall, wenn du sie mit mv aus /tmp geholt oder das Heimatverzeichnis von Hand angelegt hast, denn mv nimmt den alten Kontext mit.

getenforce
ls -Z ~/.ssh

Richtig ist ein Eintrag, der auf ssh_home_t endet. Steht dort user_tmp_t oder user_home_t, ist die Ursache gefunden. Die Reparatur:

restorecon -R -v ~/.ssh

Dieser Schritt gilt ausschließlich für die Red-Hat-Familie. Auf Debian und Ubuntu gibt es kein SELinux-Standardsetup, dort antwortet die Shell mit restorecon: command not found, und das ist kein Fehler, sondern schlicht nicht anwendbar. Aber auch auf AlmaLinux und Rocky Linux fehlt der Befehl in einer schlanken Installation, weil das Paket dazu nicht gesetzt ist. Dann vorher nachinstallieren:

dnf install -y policycoreutils

Belege findest du im Auditlog, dort steht die Ablehnung im Klartext:

ausearch -m avc -ts recent

Liegen die Heimatverzeichnisse an einem ungewöhnlichen Ort, reicht restorecon allein nicht, weil SELinux den Pfad gar nicht als Heimatverzeichnis kennt. Dann meldest du die Gleichsetzung einmalig an und stellst danach wieder her:

semanage fcontext -a -e /home /srv/kunden
restorecon -R -v /srv/kunden

semanage steckt im Paket policycoreutils-python-utils. Schalte SELinux nicht ab, um den Login zum Laufen zu bringen, das behebt ein Zwei-Befehle-Problem mit einem systemweiten Sicherheitsverlust.

Ursache 7: Alter Server, falscher Schlüsseltyp

Seit OpenSSH 8.8 lehnt der Client RSA-Signaturen mit SHA-1 ab. Betroffen ist bereits Ubuntu 22.04, und Debian 13 liefert mittlerweile OpenSSH 10. Wenn du von so einem aktuellen System auf einen sehr alten Server willst, der nur das alte ssh-rsa beherrscht, siehst du in der Debugausgabe:

debug1: send_pubkey_test: no mutual signature algorithm

Das ist kein Rechteproblem, dein Schlüssel ist völlig in Ordnung. Für den einmaligen Zugriff hilft:

ssh -o PubkeyAcceptedAlgorithms=+ssh-rsa -o HostKeyAlgorithms=+ssh-rsa deploy@203.0.113.7

Dauerhaft gehört das in ~/.ssh/config unter einen Host-Eintrag, damit es nur diesen einen Server betrifft. Auf sehr alten Clients heißt die Option noch PubkeyAcceptedKeyTypes. Die eigentliche Lösung ist, den alten Server zu aktualisieren, denn ab OpenSSH 7.2 beherrscht auch er die SHA-2-Varianten, und dein bestehender RSA-Schlüssel funktioniert dann unverändert weiter. Nur das Signaturverfahren ändert sich.

Der umgekehrte Fall existiert ebenfalls. Ein ed25519-Schlüssel braucht mindestens OpenSSH 6.5 auf beiden Seiten, Hardwaretoken vom Typ ed25519-sk mindestens 8.2. Und DSA ist Geschichte: seit OpenSSH 10.0 ist ssh-dss vollständig entfernt, solche Altschlüssel funktionieren gegenüber Debian 13 gar nicht mehr. Welche Typen dein Client kennt, zeigt:

ssh -Q key

Fehlt ssh auf einem frisch aufgesetzten AlmaLinux, Rocky Linux oder RHEL komplett, liegt das an einer Stolperfalle der Paketnamen: dnf install openssh-server bringt nur den Dienst mit, keine Client-Werkzeuge. Ohne sie fehlen ssh, ssh-add und damit auch ssh -Q und ssh -G. Nachinstalliert wird mit Plural-s, anders als beim Debian-Paket openssh-client:

dnf install -y openssh-clients

Auf AlmaLinux, Rocky und RHEL 9 kommt eine zweite Ebene dazu. Dort steuern systemweite Kryptorichtlinien mit, was erlaubt ist, unabhängig von der sshd-Konfiguration:

update-crypto-policies --show

Auch dieses Werkzeug ist rein Red-Hat-seitig, auf Debian und Ubuntu existiert es nicht. Und selbst auf Oracle Linux 9 fehlt es in der Minimalinstallation, dort liefert dnf install -y crypto-policies-scripts es nach, danach kommt wie erwartet DEFAULT heraus. Steht dort DEFAULT, sind SHA-1-Signaturen bereits systemweit blockiert. update-crypto-policies --set LEGACY löst das, schwächt aber die gesamte Maschine und sollte allenfalls eine Übergangslösung für eine Migration sein.

Wenn du dich ausgesperrt hast

Der gefährliche Moment ist nicht der Fehler selbst, sondern die Reparatur an sshd_config. Drei Regeln, die das Aussperren praktisch unmöglich machen:

  1. Zweite Sitzung offen lassen. Ein Neustart von sshd trennt bestehende Verbindungen nicht. Solange ein Terminal offen bleibt, kannst du jede Änderung zurücknehmen.
  2. Vor jedem Neustart die Syntax prüfen. sshd -t gibt bei Fehlern die Zeilennummer aus und schweigt, wenn alles passt. Ein Tippfehler in der Konfiguration verhindert sonst den Start des Dienstes, und dann kommt niemand mehr herein. Kommt stattdessen Missing privilege separation directory: /run/sshd, ist deine Konfiguration in Ordnung und es fehlt nur das Laufzeitverzeichnis, siehe oben.
  3. Aus der zweiten Sitzung heraus testen, bevor du die erste schließt.

Beim Neustart unterscheiden sich die Systeme. Auf Debian und Ubuntu heißt die Unit ssh, auf der Red-Hat-Familie sshd. Seit Ubuntu 22.10 und in Debian 13 wird SSH zusätzlich über eine Socketaktivierung gestartet: die Konfiguration aus sshd_config gilt weiterhin, aber eine geänderte Port-Angabe greift erst, wenn auch ssh.socket neu gestartet wurde.

sshd -t
systemctl restart ssh          # Debian, Ubuntu
systemctl restart ssh.socket   # zusätzlich, wenn der Port geändert wurde
systemctl restart sshd         # AlmaLinux, Rocky, RHEL

Ist es doch passiert, brauchst du einen Weg an SSH vorbei. Bei einem KernelHost-Rootserver öffnest du im Kundenbereich die VNC-Konsole und meldest dich dort mit dem root-Passwort an, ganz ohne Netzwerkdienst. Führt das nicht zum Ziel, etwa weil sshd gar nicht mehr startet, hilft das Rescue-System: du bootest in eine Notfallumgebung, hängst das Systemdateisystem ein und korrigierst authorized_keys und die Rechte direkt auf der Platte. Denk daran, nach dem Einhängen die Eigentümerverhältnisse zu prüfen, denn im Rescue-System bist du root und legst Dateien sonst mit falschem Eigentümer an.

Woran du erkennst, dass es wirklich funktioniert

Dass eine Anmeldung klappt, heißt noch nicht, dass sie über den Schlüssel lief. Solange die Passwortanmeldung aktiv ist, kann dich der Server still darauf zurückfallen lassen. Der ehrliche Test schließt jede andere Methode aus:

ssh -o BatchMode=yes -o PreferredAuthentications=publickey deploy@203.0.113.7 'id -un; hostname'

BatchMode=yes unterdrückt jede interaktive Rückfrage. Kommt dein Benutzername und der Hostname zurück und liefert echo $? anschließend eine 0, hat ausschließlich der Schlüssel gearbeitet.

Der zweite Beleg steht im Serverlog und nennt sogar den Fingerabdruck des verwendeten Schlüssels:

Accepted publickey for deploy from 203.0.113.7 port 51234 ssh2: ED25519 SHA256:8Qk...

Vergleiche diesen SHA256-Wert mit der Ausgabe von ssh-keygen -lf ~/.ssh/id_ed25519.pub. Stimmen beide überein, weißt du nicht nur, dass der Login funktioniert, sondern auch, welcher Schlüssel es war. Das ist relevant, wenn mehrere Schlüssel im Spiel sind und du einen davon zurückziehen willst.

Die Reihenfolge zum Abarbeiten

Wenn du keine Zeit für Theorie hast, geh diese Liste von oben nach unten durch. Sie ist nach Häufigkeit sortiert, nicht nach Eleganz.

  1. ssh -vvv starten und feststellen, ob Offering public key erscheint. Das teilt das Problem in Client und Server.
  2. Rechte prüfen: 700 auf ~/.ssh, 600 auf authorized_keys, Heimatverzeichnis nicht gruppenschreibbar, alles im Besitz des Benutzers.
  3. Benutzernamen prüfen, im Zweifel ssh -G befragen und im Log nach Invalid user suchen.
  4. Fingerabdrücke von privatem Schlüssel und authorized_keys vergleichen, Zeilenzahl der Datei kontrollieren.
  5. sshd -T auswerten: pubkeyauthentication, authorizedkeysfile, strictmodes, permitrootlogin.
  6. Auf AllowUsers, AllowGroups, DenyUsers und Match-Blöcke prüfen, samt Verzeichnis sshd_config.d.
  7. Auf der Red-Hat-Familie ls -Z ~/.ssh und bei Bedarf restorecon -R -v ~/.ssh.
  8. Nur bei sehr alten Gegenstellen: Signaturalgorithmus mit PubkeyAcceptedAlgorithms=+ssh-rsa erweitern.

Spätestens hier ist die Ursache gefunden. Wenn du den Zugang danach sauber neu aufsetzen willst, sind der Einstieg zur SSH-Verbindung und die Checkliste für einen neuen Rootserver die passenden Anschlusspunkte.

Häufige Fragen

Was bedeutet die Klammer in "Permission denied (publickey,password)"?
Sie listet die Authentifizierungsverfahren auf, die der Server nach dem gescheiterten Versuch noch anbietet. Steht dort nur publickey, ist die Passwortanmeldung abgeschaltet. Steht password mit in der Liste, wäre eine Passwortanmeldung möglich gewesen. Die Variante mit gssapi-keyex und gssapi-with-mic ist typisch für AlmaLinux, Rocky Linux und RHEL.
Welche Rechte müssen ~/.ssh und authorized_keys haben?
700 für ~/.ssh, 600 für ~/.ssh/authorized_keys, und das Heimatverzeichnis darf für Gruppe und andere nicht schreibbar sein, also 750 oder 700. Alle drei müssen dem jeweiligen Benutzer gehören und nicht root. Prüfen lässt sich das mit: stat -c "%a %U %G %n" ~ ~/.ssh ~/.ssh/authorized_keys
Woran erkenne ich in ssh -vvv, ob das Problem beim Client oder beim Server liegt?
An der Zeile "Offering public key". Fehlt sie, hat der Client deinen Schlüssel nie gesendet, das Problem liegt lokal (falscher Dateiname, Agent leer, zu offene Rechte auf dem privaten Schlüssel). Erscheint sie und danach wieder "Authentications that can continue", hat der Server den Schlüssel gesehen und abgelehnt, dann liegt es an Rechten, Benutzername, sshd-Konfiguration oder SELinux.
Warum funktioniert der Key-Login auf AlmaLinux nicht, obwohl die Rechte stimmen?
Meist ist es der SELinux-Kontext. Die Datei authorized_keys muss den Typ ssh_home_t tragen. Wurde sie mit mv aus /tmp verschoben, behält sie den alten Kontext und sshd darf sie nicht lesen. Prüfen mit ls -Z ~/.ssh, reparieren mit restorecon -R -v ~/.ssh. Fehlt restorecon in einer schlanken Installation, liefert dnf install -y policycoreutils es nach. Belege stehen im Auditlog, abrufbar über ausearch -m avc -ts recent.
Was bedeutet "no mutual signature algorithm"?
Der Client ist OpenSSH 8.8 oder neuer und lehnt RSA-Signaturen mit SHA-1 ab, der Gegenserver kennt aber nur das alte ssh-rsa. Für einen einmaligen Zugriff hilft die Option PubkeyAcceptedAlgorithms=+ssh-rsa zusammen mit HostKeyAlgorithms=+ssh-rsa. Die saubere Lösung ist ein Update des alten Servers, dein RSA-Schlüssel funktioniert danach unverändert weiter, nur das Signaturverfahren wechselt.
Meine Änderung in /etc/ssh/sshd_config wirkt nicht. Woran liegt das?
Auf Debian ab 12 und Ubuntu ab 22.04 steht ganz oben die Zeile Include /etc/ssh/sshd_config.d/*.conf. Da sshd für jedes Schlüsselwort den zuerst gefundenen Wert nimmt, überstimmt jede Datei in diesem Verzeichnis die Hauptdatei. Maßgeblich ist immer die Ausgabe von sshd -T, nicht der Inhalt der Datei.
Wie komme ich wieder auf den Server, wenn ich mich ausgesperrt habe?
Über die VNC-Konsole im Kundenbereich meldest du dich mit dem root-Passwort direkt an der Maschine an, ganz ohne SSH. Startet sshd gar nicht mehr, bootest du in das Rescue-System, hängst das Systemdateisystem ein und korrigierst authorized_keys, Rechte und Eigentümer direkt auf der Platte.

SSH OpenSSH Fehlerbehebung Linux Serververwaltung Authentifizierung SELinux Debian Ubuntu AlmaLinux