SSH absichern: Key-Anmeldung, Root-Login sperren, Passwortanmeldung abschalten

Veröffentlicht am 15 Min. Lesezeit

ed25519 unter Linux, macOS und Windows, die cloud-init-Falle in /etc/ssh/sshd_config.d, Socket-Aktivierung unter Ubuntu 24.04, Nachweis per sudo sshd -T und der Rettungsweg über die Konsole.

Ein frisch aufgesetzter Server steht wenige Minuten nach der ersten Erreichbarkeit in den Listen der Scanner. Was dort ankommt, ist fast immer dasselbe: automatisiertes Durchprobieren von Benutzernamen und Passwörtern auf Port 22. Wer die Passwortanmeldung abschaltet und ausschließlich Schlüssel zulässt, nimmt dieser gesamten Angriffsklasse die Grundlage. Nicht abgeschwächt, sondern vollständig.

Die Grundschritte kennen die meisten. Was in den üblichen Anleitungen fehlt, ist der Teil danach: warum PasswordAuthentication no auf Cloud-Images regelmäßig wirkungslos bleibt, warum ein systemctl reload ssh auf einem Server mit aktivem ssh.socket nicht mehr das tut, was Sie erwarten, und wie Sie belegen statt hoffen, dass die Änderung greift. Genau darum geht es hier. Alle Angaben beziehen sich auf Debian 13, Debian 12, Ubuntu 24.04 und Ubuntu 22.04.

Die Regel, die alles rettet: zwei Sitzungen

Bevor Sie irgendetwas an der SSH-Konfiguration ändern, öffnen Sie ein zweites Terminalfenster und melden sich darin ebenfalls am Server an. Diese zweite Sitzung bleibt offen, bis Sie die neue Konfiguration mit einer dritten, komplett neuen Verbindung erfolgreich getestet haben.

Der Grund ist technisch: Ein Neustart des SSH-Dienstes beendet bestehende Sitzungen nicht. Laufende Verbindungen werden von bereits abgezweigten Kindprozessen bedient und überleben den Neustart des Elternprozesses. Eine kaputte Konfiguration merken Sie also erst beim nächsten Verbindungsaufbau, und dann ist die alte Sitzung Ihr einziger Weg zurück. Wer sie schließt, um "einmal sauber neu einzuloggen", bereut das mit einiger Regelmäßigkeit.

Prüfen Sie außerdem, welche OpenSSH-Version Sie vor sich haben, weil sich daran mehrere Details entscheiden:

ssh -V
SystemOpenSSHListener im Standard
Debian 13 (trixie)10.0p2ssh.service
Debian 12 (bookworm)9.2p1ssh.service
Ubuntu 24.04 LTS9.6p1ssh.socket
Ubuntu 22.04 LTS8.9p1ssh.service

Fehlt der Serverdienst überhaupt, etwa in einem minimalen Abbild, holen Sie ihn nach:

sudo apt update
sudo apt install -y openssh-server

Schlüssel erzeugen: ed25519 unter Linux, macOS und Windows

Nehmen Sie ed25519. Kurz, schnell zu prüfen, große Sicherheitsmarge, und jede hier behandelte OpenSSH-Version beherrscht ihn. RSA brauchen Sie nur noch für Altsysteme, die nichts anderes akzeptieren, und dann mit mindestens 4096 Bit.

Linux und macOS

ssh-keygen -t ed25519 -a 100 -C "hani@notebook" -f ~/.ssh/id_ed25519

-a 100 setzt die Anzahl der KDF-Runden für die Passphrase hoch und verteuert Offline-Angriffe auf die Schlüsseldatei erheblich. -C setzt einen Kommentar, der später in authorized_keys steht und Ihnen verrät, welcher Schlüssel von welchem Gerät stammt. Vergeben Sie eine Passphrase. Ein Schlüssel ohne Passphrase ist eine Datei, die jeder mitnehmen kann, der einmal kurz an Ihrem Rechner sitzt.

Damit Sie die Passphrase nicht bei jeder Verbindung eintippen, übernimmt der Agent das Zwischenspeichern:

eval "$(ssh-agent -s)" && ssh-add ~/.ssh/id_ed25519

Unter macOS legen Sie die Passphrase stattdessen in den Schlüsselbund. Der frühere Schalter -K heißt seit macOS 12 --apple-use-keychain:

ssh-add --apple-use-keychain ~/.ssh/id_ed25519

Damit das einen Neustart übersteht, gehört in ~/.ssh/config:

Host *
    UseKeychain yes
    AddKeysToAgent yes
    IdentityFile ~/.ssh/id_ed25519

Windows

Windows 10 ab Version 1809, Windows 11 und Windows Server ab 2019 bringen den OpenSSH-Client mit. In der PowerShell:

ssh -V
ssh-keygen -t ed25519 -a 100 -C "hani@windows"

Der Schlüssel landet in C:\Users\IhrName\.ssh\. Fehlt der Client, installieren Sie ihn als Windows-Funktion nach:

Add-WindowsCapability -Online -Name OpenSSH.Client~~~~0.0.1.0

Der Agent ist unter Windows ein Systemdienst und im Auslieferungszustand deaktiviert:

Get-Service ssh-agent | Set-Service -StartupType Automatic
Start-Service ssh-agent
ssh-add $env:USERPROFILE\.ssh\id_ed25519

Den öffentlichen Schlüssel auf den Server bringen

Auf den Server gehört ausschließlich die Datei mit der Endung .pub. Die Datei ohne Endung ist der private Schlüssel und verlässt Ihren Rechner nie.

Der bequeme Weg unter Linux

ssh-copy-id -i ~/.ssh/id_ed25519.pub root@203.0.113.10

ssh-copy-id legt ~/.ssh an, setzt die Rechte korrekt, hängt den Schlüssel an authorized_keys an und prüft dabei, ob er schon vorhanden ist. Unter macOS ist das Werkzeug nicht in jeder Version enthalten. Prüfen Sie kurz mit command -v ssh-copy-id und weichen Sie sonst auf den manuellen Weg aus.

Der Windows-Weg ohne ssh-copy-id

Der OpenSSH-Client von Microsoft enthält ssh-copy-id nicht. Das Original ist ein Shell-Skript und wurde nie portiert. Dasselbe Ergebnis erreichen Sie mit einer Pipe:

type $env:USERPROFILE\.ssh\id_ed25519.pub | ssh root@203.0.113.10 "mkdir -p ~/.ssh && chmod 700 ~/.ssh && cat >> ~/.ssh/authorized_keys && chmod 600 ~/.ssh/authorized_keys"

Hier lauert ein Detail, das viele Stunden kostet: Die PowerShell hängt beim Weiterreichen an ein externes Programm Zeilenenden im Windows-Format an. In authorized_keys steht dann ein unsichtbares Wagenrücklaufzeichen am Zeilenende. Solange Sie den Schlüssel mit -C kommentiert haben, landet dieses Zeichen im Kommentarfeld und stört nicht. Ohne Kommentar hängt es am Base64-Block, und die Anmeldung scheitert ohne brauchbare Meldung. Deshalb: immer einen Kommentar setzen, und im Zweifel auf dem Server einmal aufräumen.

sed -i 's/\r$//' ~/.ssh/authorized_keys

Der manuelle Weg, der überall funktioniert

mkdir -p ~/.ssh && chmod 700 ~/.ssh && touch ~/.ssh/authorized_keys && chmod 600 ~/.ssh/authorized_keys

Danach den Inhalt der .pub-Datei als eine einzige Zeile anhängen. Liegt die Datei bereits auf dem Server, etwa weil Sie sie hochgeladen haben, geht das direkt:

cat ~/.ssh/id_ed25519.pub >> ~/.ssh/authorized_keys

Kontrollieren Sie anschließend, was tatsächlich in der Datei gelandet ist:

ssh-keygen -lf ~/.ssh/authorized_keys

Die Ausgabe listet Fingerabdruck und Kommentar jedes gültigen Eintrags. Was hier nicht auftaucht, ist umgebrochen oder beschädigt. Vergleichen Sie den Fingerabdruck mit dem Ihres lokalen Schlüssels:

ssh-keygen -l -f ~/.ssh/id_ed25519.pub

Stimmen beide überein, ist der Transport sauber gelaufen. Testen Sie jetzt, bevor Sie irgendetwas abschalten, ob die Schlüsselanmeldung überhaupt funktioniert. Erst wenn eine neue Verbindung ohne Passwortabfrage durchgeht, geht es weiter.

Die Falle: /etc/ssh/sshd_config.d und cloud-init

Das ist die Stelle, an der die meisten Anleitungen aufhören, und der häufigste Grund für den Satz "ich habe es abgeschaltet, es geht trotzdem noch".

Seit Debian 11 und Ubuntu 22.04 steht ganz oben in /etc/ssh/sshd_config eine Zeile, die ein ganzes Verzeichnis einliest. Sehen Sie selbst nach, an welcher Position:

grep -n Include /etc/ssh/sshd_config

Auf allen vier hier behandelten Systemen steht die Include-Zeile am Anfang, nicht am Ende. Und jetzt kommt die Eigenheit von OpenSSH, die man aus fast keiner anderen Konfigurationssprache kennt: Es gewinnt der erste gefundene Wert, nicht der letzte. Was in einer Datei unter /etc/ssh/sshd_config.d/ steht, wird also vor der Hauptdatei gelesen und schlägt jede spätere Zeile in sshd_config.

Cloud-init nutzt genau dieses Verzeichnis. Beim ersten Start schreibt es /etc/ssh/sshd_config.d/50-cloud-init.conf, und je nach Bereitstellung steht dort PasswordAuthentication yes. Sie können danach in sshd_config so oft PasswordAuthentication no eintragen, wie Sie wollen: Die Passwortanmeldung bleibt offen. Verschaffen Sie sich zuerst einen Überblick:

ls -la /etc/ssh/sshd_config.d/
sudo grep -riE 'passwordauthentication|permitrootlogin|kbdinteractive' /etc/ssh/sshd_config /etc/ssh/sshd_config.d/

Daraus folgt die eigentliche Empfehlung: Fassen Sie sshd_config gar nicht erst an. Legen Sie stattdessen eine eigene Datei an, deren Name alphabetisch vor allem sortiert, was die Automatisierung dort ablegt. Die Dateien werden in sortierter Reihenfolge eingelesen, 01- kommt vor 50-, und weil der erste Wert gewinnt, kann cloud-init seine Datei danach beliebig oft neu schreiben, ohne Ihre Härtung auszuhebeln. Das ist der Unterschied zu der weit verbreiteten Empfehlung, eine 99-hardening.conf anzulegen: Die verliert gegen cloud-init, und zwar still. Dieselbe Mechanik kann sich allerdings auch gegen Sie wenden: Eine Datei mit kleinerer Nummer, etwa 00-cloud.conf, gewinnt gegen Ihre 01-, weil OpenSSH den zuerst gelesenen Wert nimmt. Ein Blick in das Verzeichnis lohnt sich deshalb auch nach der Härtung.

Die Härtung schreiben, mit Zeitzünder als Rückfalloption

Bauen Sie zuerst das Sicherheitsnetz. Der folgende Befehl entfernt Ihre neue Datei in zehn Minuten automatisch und startet SSH neu, falls Sie bis dahin nicht abgebrochen haben:

sudo systemd-run --on-active=10min --unit=ssh-rollback /bin/sh -c 'rm -f /etc/ssh/sshd_config.d/01-hardening.conf; systemctl try-restart ssh.socket ssh.service'

Jetzt die eigentliche Konfiguration:

sudo tee /etc/ssh/sshd_config.d/01-hardening.conf >/dev/null <<'EOF'
PubkeyAuthentication yes
PasswordAuthentication no
KbdInteractiveAuthentication no
PermitRootLogin prohibit-password
PermitEmptyPasswords no
MaxAuthTries 3
EOF
sudo chmod 644 /etc/ssh/sshd_config.d/01-hardening.conf

Zwei Zeilen verdienen eine Erklärung. KbdInteractiveAuthentication no ist kein Beiwerk: Bleibt sie auf yes, kann PAM die Passwortabfrage über den Umweg der interaktiven Tastatureingabe weiterhin anbieten, obwohl PasswordAuthentication auf no steht. Genau deshalb gibt es Server, die trotz abgeschalteter Passwortanmeldung nach einem Passwort fragen.

Und PermitRootLogin prohibit-password statt no: Damit bleibt der Zugang als root per Schlüssel erhalten, während Passwörter für root ausgeschlossen sind. Wenn Sie einen eigenen Benutzer mit sudo eingerichtet und dessen Schlüsselanmeldung nachweislich getestet haben, setzen Sie stattdessen PermitRootLogin no. Vorher nicht.

Was Sie nicht übernehmen sollten, obwohl es in älteren Anleitungen steht: ChallengeResponseAuthentication. Die Option ist seit OpenSSH 8.7 nur noch ein veralteter Aliasname für KbdInteractiveAuthentication und erzeugt in aktuellen Versionen eine Deprecated-Meldung im Log. Lassen Sie sie weg.

Syntaxprüfung vor dem Aktivieren, ausnahmslos:

sudo sshd -t

Keine Ausgabe heißt: Die Datei ist syntaktisch in Ordnung. Sie heißt nicht, dass sie inhaltlich tut, was Sie wollen. Dafür ist gleich sudo sshd -T zuständig.

Meldet der Test stattdessen Missing privilege separation directory: /run/sshd, lief sshd seit dem Start des Systems noch kein einziges Mal, denn dieses Verzeichnis entsteht erst mit ssh.service. Das trifft vor allem Ubuntu 24.04 mit Socket-Aktivierung und lässt sich mit sudo mkdir -p /run/sshd oder sudo systemctl start ssh.service ausräumen, auf einem Server, auf dem Sie gerade per SSH angemeldet sind, tritt es ohnehin nicht auf.

Aktivieren: ssh.service, ssh.socket und die Unterschiede je Distribution

Hier gehen die vier Systeme auseinander, und die alte Gewohnheit systemctl reload ssh ist überall dort die falsche Antwort, wo ssh.socket den Port hält.

Ubuntu setzt seit 22.10 auf Socket-Aktivierung, Ubuntu 24.04 liefert sie im Standard aus: Dort ist ssh.socket aktiviert und ssh.service deaktiviert. Debian macht es ab Werk genau umgekehrt. Debian 13 und Debian 12 liefern ssh.service aktiviert und ssh.socket deaktiviert aus, entgegen der verbreiteten Annahme, Debian 13 stelle bei einer Neuinstallation auf den Socket um. Bei Socket-Aktivierung lauscht systemd selbst auf Port 22 und startet erst bei einer eingehenden Verbindung einen frischen sshd. Das hat eine angenehme Nebenwirkung: Änderungen an sshd_config greifen bei der nächsten Verbindung ohnehin, weil jeder Verbindungsprozess die Konfiguration neu einliest. Ein Neuladen brauchen Sie nur für Einstellungen, die den Listener selbst betreffen, also Port und ListenAddress.

Raten Sie also nicht, sondern fragen Sie das System, welche Einheit bei Ihnen den Dienst versieht:

systemctl is-enabled ssh.socket ssh.service
Systemssh.socketssh.serviceBesonderheit
Ubuntu 24.04 LTSenableddisabledSocket-Aktivierung im Standard, ListenStream auf 0.0.0.0:22 und [::]:22
Debian 13 (trixie)disabledenabledAccept=no
Debian 12 (bookworm)disabledenabledAccept=no
Ubuntu 22.04 LTS (und ebenso Debian 11)disabledenabledAccept=yes, also ein eigener Prozess je Verbindung über ssh@.service

Und dann ein Befehl, der auf allen vier Systemen richtig ist:

sudo sshd -t && sudo systemctl try-restart ssh.socket ssh.service

try-restart startet eine Einheit nur neu, wenn sie tatsächlich aktiv ist, und lässt die andere unangetastet. Damit müssen Sie nicht raten. Beide Teile brauchen root: sshd liegt unter /usr/sbin und steht auf Debian nicht im PATH eines normalen Benutzers, und try-restart greift ohnehin auf systemd zu. Ohne sudo endet der Aufruf je nach System mit sshd: command not found oder mit sshd: no hostkeys available, weil die Hostschlüssel unter /etc/ssh nur für root lesbar sind.

Ebenso bewusst kein einzelnes systemctl restart ssh.socket, auch wenn dieser Befehl in vielen Anleitungen steht. Auf Debian 13 und Debian 12 bricht er mit Job failed. See journalctl -xe for details. ab, im Journal steht dazu ssh.socket: Socket service ssh.service already active, refusing. Die neue Konfiguration wird dabei nicht aktiv, der Gegentest meldet weiterhin Permission denied (publickey,password). Auf Ubuntu 22.04 und Debian 11 läuft er zwar ohne Fehlermeldung durch, stoppt dabei aber ssh.service und stellt den Host auf Socket-Aktivierung um. Weil ssh.socket dort deaktiviert bleibt, springt beim nächsten Neustart wieder ssh.service an, der Betriebsmodus wechselt also unbemerkt hin und her. try-restart auf beide Einheiten vermeidet beides.

Bewusst auch kein reload: Auf einem System, auf dem ssh.socket den Port hält, quittiert ein systemctl reload ssh mit

fatal: Cannot bind any address.

Danach steht der Dienst im Fehlerzustand und hat seinen Port losgelassen. Ein Neustart hat dieses Problem nicht und beendet bestehende Sitzungen ebenso wenig.

Wenn Sie den Port verlegen wollen, kommt die nächste Distributionsdifferenz. Ubuntu 24.04 erzeugt die Socket-Konfiguration über einen systemd-Generator aus sshd_config, dort genügt nach der Portänderung:

sudo systemctl daemon-reload
sudo systemctl try-restart ssh.socket ssh.service

Haben Sie auf Debian dagegen bewusst auf ssh.socket umgestellt, steht der Port in der Unit selbst und eine Änderung in sshd_config bleibt wirkungslos. Sie hinterlegen ihn per Ergänzungsdatei über sudo systemctl edit ssh.socket, mit einem leeren ListenStream= zum Zurücksetzen und einer zweiten Zeile mit dem neuen Wert. Kontrollieren Sie das Ergebnis danach an der Realität, nicht an der Konfiguration:

sudo ss -tlnp

Nachweis: sshd -T und der Gegentest

Ein Befehl, der ohne Fehler durchläuft, ist kein Beweis. Der Beweis ist die aufgelöste Gesamtkonfiguration, in die alle eingebundenen Dateien bereits eingerechnet sind:

sudo sshd -T | grep -E '^(passwordauthentication|kbdinteractiveauthentication|pubkeyauthentication|permitrootlogin|usepam|port|authorizedkeysfile)'

Erwartet wird eine Ausgabe in dieser Art:

port 22
permitrootlogin prohibit-password
pubkeyauthentication yes
passwordauthentication no
kbdinteractiveauthentication no
usepam yes
authorizedkeysfile .ssh/authorized_keys .ssh/authorized_keys2

Steht dort trotz Ihrer Datei passwordauthentication yes, liegt im Verzeichnis eine Datei, die alphabetisch vor Ihrer sortiert. Zurück zum Abschnitt über die Reihenfolge.

Für die Einzelabfrage genügt derselbe Befehl mit einem engeren Filter:

sudo sshd -T | grep -i passwordauthentication

Zwei Gründe sprechen für das sudo davor. Erstens liest sshd -T die Hostschlüssel, die unter /etc/ssh nur für root lesbar sind. Zweitens liegt sshd selbst unter /usr/sbin, und dieses Verzeichnis gehört auf Debian nicht zum PATH eines normalen Benutzers, weshalb der Aufruf ohne sudo dort mit sshd: command not found endet. Wer den Weg über sudo vermeiden will, schreibt den vollen Pfad /usr/sbin/sshd.

Ab OpenSSH 9.3, also auf Ubuntu 24.04 (9.6p1) und Debian 13 (10.0p2), gibt es zusätzlich sshd -G. Die Option wertet dieselbe Konfiguration aus, verlangt aber keine lesbaren Hostschlüssel und kein vorhandenes /run/sshd, was sie für Prüfungen in Automatisierung und Containern brauchbar macht. Auf Debian 12 (9.2p1), Ubuntu 22.04 (8.9p1) und Debian 11 (8.4p1) existiert der Schalter noch nicht, dort quittiert sshd ihn als unbekannte Option. Für eine Anleitung, die überall gilt, bleibt sudo sshd -T deshalb die richtige Wahl.

Nun der Gegentest, und zwar aus einem neuen Terminal, während die alte Sitzung offen bleibt. Erzwingen Sie eine Passwortanmeldung und schalten Sie Schlüssel für diesen Versuch ab:

ssh -o PubkeyAuthentication=no -o PreferredAuthentications=password,keyboard-interactive root@203.0.113.10

Richtig ist, wenn Sie sofort und ohne jede Passwortabfrage abgewiesen werden:

root@203.0.113.10: Permission denied (publickey).

Entscheidend ist der Klammerinhalt. Steht dort (publickey,password) oder erscheint eine Passwortabfrage, ist die Passwortanmeldung weiterhin offen. Erst wenn der Gegentest sauber scheitert und eine normale Schlüsselverbindung weiterhin gelingt, schließen Sie die alte Sitzung und stoppen den Zeitzünder:

sudo systemctl stop ssh-rollback.timer

Fehlermeldungen im Wortlaut

Permission denied (publickey). Der Server akzeptiert nur Schlüssel, und Ihrer passt nicht. Rufen Sie ssh -v auf und sehen Sie nach, welche Datei überhaupt angeboten wurde. Häufigste Ursachen: falscher Benutzername, Schlüssel in der authorized_keys des falschen Benutzers, oder Sie haben root gesperrt und melden sich weiterhin als root an.

Authentication refused: bad ownership or modes for directory /home/hani/.ssh Diese Zeile steht nicht auf Ihrem Bildschirm, sondern im Log des Servers, sichtbar über sudo journalctl -u ssh -n 50 --no-pager. Filtern Sie dabei nicht über -t sshd: Ab OpenSSH 9.8, auf Debian 13 also im Auslieferungszustand, laufen die Sitzungen im eigenen Prozess sshd-session, unter dem Tag sshd stehen dann nur noch Meldungen des Listeners und kein einziger Anmeldevorgang. Wer nach Tags filtern möchte, nimmt sudo journalctl -t sshd -t sshd-session -n 50 --no-pager. OpenSSH verweigert Schlüssel, wenn Heimatverzeichnis, .ssh oder authorized_keys für Gruppe oder andere schreibbar sind. Die Korrektur:

chmod go-w ~ && chmod 700 ~/.ssh && chmod 600 ~/.ssh/authorized_keys

WARNING: UNPROTECTED PRIVATE KEY FILE! beziehungsweise Load key "/home/hani/.ssh/id_ed25519": bad permissions. Dasselbe Problem auf der Clientseite. chmod 600 ~/.ssh/id_ed25519 löst es.

Too many authentication failures Ihr Agent bietet reihum alle geladenen Schlüssel an und überschreitet dabei MaxAuthTries. Beschränken Sie die Verbindung auf einen einzigen Schlüssel: ssh -o IdentitiesOnly=yes -i ~/.ssh/id_ed25519 hani@203.0.113.10.

sign_and_send_pubkey: no mutual signature supported Ein alter RSA-Schlüssel mit SHA-1-Signatur trifft auf einen Server, der das nicht mehr akzeptiert. Erzeugen Sie einen ed25519-Schlüssel, statt an PubkeyAcceptedAlgorithms herumzuschrauben.

Bad owner or permissions on C:\Users\hani\.ssh\config Der Windows-Client prüft die Zugriffsrechte seiner Konfigurationsdatei. Entfernen Sie in den Dateieigenschaften unter Sicherheit die Vererbung und alle Einträge außer Ihrem Benutzerkonto und SYSTEM.

WARNING: REMOTE HOST IDENTIFICATION HAS CHANGED! Der Hostschlüssel des Servers ist ein anderer als beim letzten Mal. Nach einer Neuinstallation ist das erwartbar, sonst nicht. Entfernen Sie den alten Eintrag gezielt mit ssh-keygen -R 203.0.113.10, und nur, wenn Sie den Grund kennen.

Ausgesperrt: der Weg über die Konsole im Kundenbereich

Wenn beide Sitzungen weg sind und keine Verbindung mehr aufgeht, ist das kein Datenverlust, sondern ein Umweg. Jeder KVM-Rootserver und jeder Dedicated Server bei KernelHost hat im Kundenbereich eine Konsole, die auf der Bildschirmausgabe des Systems sitzt und vom Netzwerkstapel des Servers unabhängig ist. Sie kommen also auch dann hinein, wenn SSH gar nicht mehr lauscht.

  1. Im Kundenbereich anmelden, den betroffenen Server öffnen und die Konsole starten.
  2. An der Anmeldeaufforderung als root mit dem Passwort anmelden, das bei der Bereitstellung vergeben wurde. Die Konsolenanmeldung läuft nicht über SSH und ist von PermitRootLogin nicht betroffen.
  3. Die Änderung zurücknehmen: sudo rm /etc/ssh/sshd_config.d/01-hardening.conf
  4. Prüfen und neu starten: sudo sshd -t && sudo systemctl try-restart ssh.socket ssh.service
  5. Läuft SSH gar nicht, helfen sudo systemctl status ssh.socket ssh.service und ein Blick in sudo journalctl -u ssh -n 50 --no-pager. Der Rückgabewert 3 bei status bedeutet nur, dass eine der beiden Einheiten inaktiv ist, auf Debian ist das mit dem deaktivierten ssh.socket der Normalfall.

Zwei Vorsichtsmaßnahmen ersparen Ihnen diesen Weg fast immer. Notieren Sie das root-Passwort, bevor Sie die Passwortanmeldung abschalten, denn die Konsole braucht es. Und prüfen Sie eine aktive Firewall, bevor Sie den SSH-Port verlegen. Ein Portwechsel ohne passende Freigabe sperrt genauso zuverlässig aus wie eine kaputte sshd_config, sieht aber anders aus: Statt Permission denied bekommen Sie Connection timed out.

Kurzfassung

  • Zweite Sitzung offen lassen, bis eine dritte, neue Verbindung nachweislich funktioniert.
  • ed25519 mit -a 100 und Passphrase, öffentlichen Schlüssel per ssh-copy-id, unter Windows per Pipe.
  • Schlüsselanmeldung testen, bevor die Passwortanmeldung fällt.
  • Härtung nach /etc/ssh/sshd_config.d/01-hardening.conf, nicht in sshd_config. Der erste gefundene Wert gewinnt, deshalb die niedrige Nummer.
  • KbdInteractiveAuthentication no nicht vergessen, sonst bleibt der PAM-Umweg offen.
  • Aktivieren mit sudo sshd -t && sudo systemctl try-restart ssh.socket ssh.service, weder mit reload noch mit einem einzelnen restart ssh.socket.
  • Vorher mit systemctl is-enabled ssh.socket ssh.service klären, welche Einheit überhaupt aktiv ist. Ubuntu 24.04 nutzt den Socket, Debian 13 und Debian 12 den Dienst.
  • Nachweis über sudo sshd -T und einen erzwungenen Passwortversuch aus einer neuen Sitzung.
  • Notfallweg ist die Konsole im Kundenbereich, dafür das root-Passwort bereithalten.

Die naheliegenden nächsten Schichten beschreiben unsere Beiträge zu fail2ban und zur UFW-Firewall. Wichtiger als beide ist das, was Sie gerade erledigt haben.

Häufige Fragen

Warum bleibt die Passwortanmeldung trotz PasswordAuthentication no aktiv?
Fast immer wegen einer Datei in /etc/ssh/sshd_config.d/, meist 50-cloud-init.conf. Die Include-Zeile steht in Debian und Ubuntu am Anfang von sshd_config, und OpenSSH übernimmt den ersten gefundenen Wert, nicht den letzten. Was im Verzeichnis liegt, gewinnt also gegen die Hauptdatei. Prüfen Sie mit sudo sshd -T, was tatsächlich gilt, und legen Sie Ihre eigene Datei als 01-hardening.conf an, damit sie vor allen automatisch erzeugten Dateien gelesen wird.
Muss ich nach einer Änderung an sshd_config den Dienst neu starten?
Auf Debian 13, Debian 12 und Ubuntu 22.04 ja, dort ist ab Werk ssh.service aktiviert und ssh.socket deaktiviert. Auf Ubuntu 24.04 lauscht systemd im Standard über ssh.socket und startet pro Verbindung einen neuen sshd, der die Konfiguration ohnehin neu einliest. Nur Port und ListenAddress betreffen den Listener selbst. Welche Einheit bei Ihnen aktiv ist, zeigt systemctl is-enabled ssh.socket ssh.service. Der Befehl sudo sshd -t && sudo systemctl try-restart ssh.socket ssh.service ist auf allen vier Systemen richtig, ein einzelnes systemctl restart ssh.socket dagegen nicht: Auf Debian 13 und Debian 12 schlägt es fehl und die neue Konfiguration wird nicht aktiv, auf Ubuntu 22.04 stellt es den Host unbemerkt auf Socket-Aktivierung um.
Warum sollte ich reload vermeiden?
Auf Systemen mit aktivem ssh.socket, im Standard also unter Ubuntu 24.04, bricht systemctl reload ssh mit der Meldung fatal: Cannot bind any address ab, der Dienst geht in den Fehlerzustand und gibt seinen Port frei. Ein Neustart hat dieses Problem nicht und beendet bestehende Sitzungen ebenso wenig, weil laufende Verbindungen von eigenen Kindprozessen bedient werden.
Wie bringe ich meinen Schlüssel von Windows aus auf den Server, wenn es ssh-copy-id dort nicht gibt?
Über eine Pipe: type $env:USERPROFILE\.ssh\id_ed25519.pub | ssh benutzer@server "mkdir -p ~/.ssh && chmod 700 ~/.ssh && cat >> ~/.ssh/authorized_keys && chmod 600 ~/.ssh/authorized_keys". Achten Sie darauf, den Schlüssel mit -C kommentiert zu haben, sonst kann ein von PowerShell angehängtes Wagenrücklaufzeichen den Base64-Block beschädigen. Auf dem Server räumt sed -i 's/\r$//' ~/.ssh/authorized_keys das auf.
Wie weise ich nach, dass die Passwortanmeldung wirklich zu ist?
Mit zwei Schritten. Erstens sudo sshd -T, das die aufgelöste Gesamtkonfiguration ausgibt und passwordauthentication no sowie kbdinteractiveauthentication no zeigen muss. Zweitens ein Gegentest aus einer neuen Sitzung: ssh -o PubkeyAuthentication=no -o PreferredAuthentications=password,keyboard-interactive benutzer@server muss sofort mit Permission denied (publickey). abgewiesen werden. Steht in der Klammer publickey,password, ist der Zugang noch offen.
Was tue ich, wenn ich mich ausgesperrt habe?
Melden Sie sich im Kundenbereich an, öffnen Sie den Server und starten Sie die Konsole. Sie hängt an der Bildschirmausgabe des Systems und ist von SSH unabhängig. Dort als root anmelden, die eigene Datei mit sudo rm /etc/ssh/sshd_config.d/01-hardening.conf entfernen, mit sudo sshd -t prüfen und mit sudo systemctl try-restart ssh.socket ssh.service neu starten. Halten Sie das root-Passwort bereit, bevor Sie die Passwortanmeldung abschalten.
Ist PermitRootLogin no oder prohibit-password die bessere Wahl?
prohibit-password erlaubt root weiterhin per Schlüssel und schließt nur Passwörter aus, was den Zugang bei Fehlkonfigurationen erhält. no ist strenger, setzt aber voraus, dass ein zweiter Benutzer mit sudo existiert und dessen Schlüsselanmeldung bereits nachweislich funktioniert. Stellen Sie erst um, wenn dieser Test bestanden ist.

SSH Serversicherheit Linux Debian Ubuntu OpenSSH ed25519 systemd cloud-init Tutorial