{"id":60,"date":"2026-06-11T16:21:29","date_gmt":"2026-06-11T16:21:29","guid":{"rendered":"https:\/\/shattered.io\/de\/2026\/06\/11\/ssh-key-erstellen-ed25519\/"},"modified":"2026-06-11T16:21:29","modified_gmt":"2026-06-11T16:21:29","slug":"ssh-key-erstellen-ed25519","status":"publish","type":"post","link":"https:\/\/shattered.io\/de\/2026\/06\/11\/ssh-key-erstellen-ed25519\/","title":{"rendered":"SSH-Key erstellen: ed25519 in 12 Schritten [2026]"},"content":{"rendered":"\n<p class=\"wp-block-paragraph\">Ein <strong>SSH-Key<\/strong> ersetzt das Passwort beim Anmelden auf einem Server durch ein kryptografisches Schl\u00fcsselpaar. Wer 2026 noch mit Passw\u00f6rtern arbeitet, l\u00e4dt Brute-Force-Angriffe geradezu ein: Die OpenSSH-L\u00fccke <em>regreSSHion<\/em> (CVE-2024-6387) hat 2024 gezeigt, wie schnell exponierte SSH-Dienste ins Visier geraten. Dieses Tutorial zeigt in 12 nachvollziehbaren Schritten, wie Sie einen <strong>SSH-Key erstellen<\/strong>, ihn sicher auf einen Server bringen, die Passwort-Anmeldung abschalten und optional Hardware-Schl\u00fcssel sowie Post-Quanten-Kryptografie aktivieren. Geplante Zeit: rund 30 Minuten.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Alle Befehle sind f\u00fcr Linux, macOS und Windows (mit OpenSSH-Client) getestet. Am Ende steht ein vollst\u00e4ndiges, lauff\u00e4higes Beispielprojekt: ein geh\u00e4rteter Zugang zu zwei Servern plus ein separater Deploy-Key f\u00fcr Git. Stand: 11. Juni 2026.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"ssh-key-erstellen-warum-ed25519-statt-rsa-der-standard-ist\">SSH-Key erstellen: Warum ed25519 statt RSA der Standard ist<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Bevor wir einen <strong>SSH-Key erstellen<\/strong>, lohnt der Blick auf das Schl\u00fcsselverfahren. OpenSSH unterst\u00fctzt mehrere Typen, doch in der aktuellen H\u00e4rtungspraxis 2026 ist <strong>ed25519<\/strong> die erste Wahl. Der Grund ist nicht Geschmack, sondern Mathematik: Ed25519 basiert auf der Edwards-Kurve Curve25519 und bietet ein Sicherheitsniveau, das grob einem 3072-Bit-RSA-Schl\u00fcssel entspricht, kommt dabei aber mit einem 256-Bit-Schl\u00fcssel aus. Der \u00f6ffentliche Schl\u00fcssel ist nur rund 68 Zeichen lang, passt also in eine einzige Zeile.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Drei praktische Vorteile sprechen f\u00fcr ed25519: Erstens ist die Schl\u00fcsselerzeugung deterministisch und unempfindlich gegen schwache Zufallszahlen, ein bekanntes Risiko bei RSA und DSA. Zweitens sind Signatur und Verifikation deutlich schneller, was bei vielen parallelen Verbindungen sp\u00fcrbar wird. Drittens f\u00e4llt die Konfiguration einfacher aus, weil es keine variable Schl\u00fcssell\u00e4nge gibt, \u00fcber die man nachdenken m\u00fcsste. RSA bleibt nur dort sinnvoll, wo ein sehr alter Server oder ein Legacy-Ger\u00e4t ed25519 schlicht nicht versteht.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Die folgende Tabelle vergleicht die in OpenSSH verf\u00fcgbaren Schl\u00fcsseltypen. Die Empfehlungen orientieren sich an aktuellen H\u00e4rtungsleitf\u00e4den sowie der BSI-Richtlinie TR-02102-4 zum Einsatz von Secure Shell.<\/p>\n\n\n\n<figure class=\"wp-table\"><table><thead><tr><th>Schl\u00fcsseltyp<\/th><th>Schl\u00fcssell\u00e4nge<\/th><th>Sicherheit<\/th><th>Empfehlung 2026<\/th><th>Einsatz<\/th><\/tr><\/thead><tbody>\n<tr><td>ed25519<\/td><td>256 Bit<\/td><td>\u2248 3072-Bit-RSA<\/td><td>Erste Wahl<\/td><td>Standard f\u00fcr neue Schl\u00fcssel<\/td><\/tr>\n<tr><td>ed25519-sk<\/td><td>256 Bit + Hardware<\/td><td>Sehr hoch<\/td><td>Empfohlen<\/td><td>FIDO2-Sicherheitsschl\u00fcssel<\/td><\/tr>\n<tr><td>ecdsa<\/td><td>256\u2013521 Bit<\/td><td>Hoch<\/td><td>Nur bei Bedarf<\/td><td>NIST-Kurven, Compliance<\/td><\/tr>\n<tr><td>rsa<\/td><td>\u2265 3072 Bit<\/td><td>Hoch<\/td><td>Nur als Fallback<\/td><td>Legacy-Systeme<\/td><\/tr>\n<tr><td>dsa<\/td><td>1024 Bit<\/td><td>Unsicher<\/td><td>Nicht nutzen<\/td><td>In OpenSSH entfernt<\/td><\/tr>\n<\/tbody><\/table><\/figure>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"voraussetzungen-openssh-version-und-werkzeuge\">Voraussetzungen: OpenSSH-Version und Werkzeuge<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Damit dieses Tutorial reibungslos l\u00e4uft, brauchen Sie eine aktuelle OpenSSH-Installation auf dem lokalen Rechner und Zugriff auf einen Zielserver (Cloud-VM, Raspberry Pi, NAS oder Webhosting mit Shell-Zugang). Die folgenden Versionen gelten als sicherer Stand f\u00fcr 2026:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>OpenSSH 10.x<\/strong> (aktuelle Serie 2026) auf Client und Server, mindestens jedoch <strong>9.8p1<\/strong>. Die Version 9.8p1 vom 1. Juli 2024 schlie\u00dft die kritische L\u00fccke <em>regreSSHion<\/em> (CVE-2024-6387), die alle portablen Versionen von 8.5p1 bis 9.7p1 auf glibc-basierten Linux-Systemen betraf.<\/li>\n<li><strong>Linux:<\/strong> ein beliebiger Paketmanager (apt, dnf, pacman) zum Aktualisieren von <code>openssh-client<\/code> und <code>openssh-server<\/code>.<\/li>\n<li><strong>macOS:<\/strong> integrierter OpenSSH-Client; f\u00fcr die neueste Version optional Homebrew.<\/li>\n<li><strong>Windows 10\/11:<\/strong> der optionale Client \u201eOpenSSH-Client\u201c unter Einstellungen, oder die mitgelieferte Version in der PowerShell.<\/li>\n<li>Ein Terminal mit Shell-Zugang sowie, optional, ein FIDO2-Sicherheitsschl\u00fcssel (YubiKey, Nitrokey, Token2) f\u00fcr Schritt 9.<\/li>\n<\/ul>\n\n\n\n<p class=\"wp-block-paragraph\">Aktualisieren Sie OpenSSH vor dem Start. Veraltete Versionen sind die h\u00e4ufigste Ursache f\u00fcr unerkl\u00e4rliche Verbindungsfehler und bekannte Sicherheitsl\u00fccken. Wer einen Hetzner-, IONOS- oder AWS-Server betreibt, sollte die Pakete des Anbieters einspielen, da diese die Sicherheits-Patches r\u00fcckportiert enthalten.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"schritt-1-openssh-version-pruefen\">Schritt 1: OpenSSH-Version pr\u00fcfen<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Pr\u00fcfen Sie zuerst, welche Version lokal installiert ist. \u00d6ffnen Sie ein Terminal und f\u00fchren Sie aus:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code># Lokale OpenSSH-Version anzeigen\nssh -V\n\n# Beispielausgabe (gew\u00fcnscht):\n# OpenSSH_10.0p1, OpenSSL 3.3.2 4 Jun 2024<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Liegt die Version unter 9.8p1, aktualisieren Sie sofort. Unter Debian oder Ubuntu gen\u00fcgt:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code># Paketquellen aktualisieren und OpenSSH einspielen\nsudo apt update\nsudo apt install --only-upgrade openssh-client openssh-server\n\n# Version nach dem Upgrade erneut pr\u00fcfen\nssh -V<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Auf dem Server pr\u00fcfen Sie dieselbe Version, sobald Sie sich anmelden k\u00f6nnen. Notieren Sie sich beide Versionsnummern. Unterscheiden sich Client und Server stark, kann das sp\u00e4ter bei modernen Algorithmen wie dem Post-Quanten-Schl\u00fcsselaustausch (Schritt 10) zu Aushandlungsproblemen f\u00fchren.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"schritt-2-ed25519-schluesselpaar-erzeugen\">Schritt 2: ed25519-Schl\u00fcsselpaar erzeugen<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Jetzt geht es ans Eigentliche. Mit <code>ssh-keygen<\/code> erzeugen Sie das Schl\u00fcsselpaar. Der private Schl\u00fcssel bleibt f\u00fcr immer auf Ihrem Rechner, der \u00f6ffentliche Schl\u00fcssel wandert auf den Server. Geben Sie diesen Befehl ein:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code># ed25519-Schl\u00fcsselpaar mit aussagekr\u00e4ftigem Kommentar erzeugen\nssh-keygen -t ed25519 -C \"sam@firma.de\" -f ~\/.ssh\/id_ed25519<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Die Optionen im Detail: <code>-t ed25519<\/code> w\u00e4hlt das Schl\u00fcsselverfahren, <code>-C<\/code> setzt einen Kommentar (meist E-Mail oder Rechnername zur sp\u00e4teren Zuordnung) und <code>-f<\/code> legt den Dateinamen fest. Die Ausgabe sieht so aus:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>Generating public\/private ed25519 key pair.\nEnter passphrase (empty for no passphrase):\nEnter same passphrase again:\nYour identification has been saved in \/home\/sam\/.ssh\/id_ed25519\nYour public key has been saved in \/home\/sam\/.ssh\/id_ed25519.pub\nThe key fingerprint is:\nSHA256:9kPq2v...Xa7Yd sam@firma.de\nThe key's randomart image is:\n+--[ED25519 256]--+\n|        .o+=B*o  |\n|       . o.=.o   |\n+----[SHA256]-----+<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Es entstehen zwei Dateien: <code>id_ed25519<\/code> (privater Schl\u00fcssel, streng geheim) und <code>id_ed25519.pub<\/code> (\u00f6ffentlicher Schl\u00fcssel, darf geteilt werden). Den Unterschied zwischen privatem und \u00f6ffentlichem Schl\u00fcssel erkl\u00e4ren wir ausf\u00fchrlicher im Beitrag zu <a href=\"\/de\/digital-signatures\/\">digitalen Signaturen<\/a>, denn das zugrunde liegende Prinzip ist identisch.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"schritt-3-passphrase-und-kdf-runden-richtig-setzen\">Schritt 3: Passphrase und KDF-Runden richtig setzen<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Ein privater Schl\u00fcssel ohne Passphrase ist eine Datei, die jeden Zugang gew\u00e4hrt, der sie kopiert. Setzen Sie immer eine Passphrase. Damit ein gestohlener Schl\u00fcssel auch bei schwacher Passphrase nicht im Sekundentakt durchprobiert werden kann, erh\u00f6ht OpenSSH die Anzahl der KDF-Runden (Key Derivation Function) mit der Option <code>-a<\/code>:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code># Schl\u00fcssel mit 100 KDF-Runden f\u00fcr st\u00e4rkere Passphrase-Streckung\nssh-keygen -t ed25519 -a 100 -C \"sam@firma.de\" -f ~\/.ssh\/id_ed25519<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Der Wert <code>-a 100<\/code> bedeutet 100 Runden der bcrypt-basierten KDF. Das macht das Entschl\u00fcsseln des privaten Schl\u00fcssels sp\u00fcrbar teurer f\u00fcr Angreifer, kostet beim eigenen Login aber nur Sekundenbruchteile. Wer die Passphrase eines bestehenden Schl\u00fcssels \u00e4ndern m\u00f6chte, ohne ein neues Paar zu erzeugen, nutzt:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code># Passphrase eines vorhandenen Schl\u00fcssels \u00e4ndern (-p) und KDF-Runden erh\u00f6hen\nssh-keygen -p -a 100 -f ~\/.ssh\/id_ed25519<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Die Philosophie hinter der KDF ist dieselbe wie bei modernen Passwort-Hashes. Wer verstehen will, warum absichtlich langsame Funktionen gegen Brute-Force sch\u00fctzen, findet die Details in unserer Anleitung zu <a href=\"\/de\/argon2-password-hashing-nodejs\/\">Argon2-Passwort-Hashing<\/a>.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"schritt-4-ssh-agent-einrichten-und-schluessel-laden\">Schritt 4: ssh-agent einrichten und Schl\u00fcssel laden<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Mit Passphrase m\u00fcssten Sie diese bei jeder Verbindung neu eintippen. Der <code>ssh-agent<\/code> h\u00e4lt den entschl\u00fcsselten Schl\u00fcssel im Speicher und erspart die Wiederholung. Starten Sie den Agenten und laden Sie den Schl\u00fcssel:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code># ssh-agent in der aktuellen Shell starten\neval \"$(ssh-agent -s)\"\n# Ausgabe: Agent pid 48213\n\n# Privaten Schl\u00fcssel zum Agenten hinzuf\u00fcgen (Passphrase wird einmal abgefragt)\nssh-add ~\/.ssh\/id_ed25519\n# Ausgabe: Identity added: \/home\/sam\/.ssh\/id_ed25519 (sam@firma.de)\n\n# Geladene Schl\u00fcssel auflisten\nssh-add -l<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Auf macOS integriert sich der Agent in den Schl\u00fcsselbund. F\u00fcgen Sie <code>ssh-add --apple-use-keychain ~\/.ssh\/id_ed25519<\/code> hinzu, damit die Passphrase dauerhaft im Schl\u00fcsselbund gespeichert wird. Unter Linux mit systemd-Desktop \u00fcbernimmt meist <code>gnome-keyring<\/code> oder <code>ssh-agent.service<\/code> diese Aufgabe automatisch. Auf Windows aktivieren Sie den Dienst \u201eOpenSSH Authentication Agent\u201c einmalig:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code># Windows PowerShell als Administrator\nSet-Service ssh-agent -StartupType Automatic\nStart-Service ssh-agent\nssh-add $env:USERPROFILE\\.ssh\\id_ed25519<\/code><\/pre>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"schritt-5-oeffentlichen-schluessel-auf-den-server-kopieren\">Schritt 5: \u00d6ffentlichen Schl\u00fcssel auf den Server kopieren<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Der \u00f6ffentliche Schl\u00fcssel muss in die Datei <code>~\/.ssh\/authorized_keys<\/code> des Zielkontos auf dem Server. Das erledigt <code>ssh-copy-id<\/code> in einem Schritt, inklusive korrekter Rechte:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code># \u00d6ffentlichen Schl\u00fcssel automatisch auf den Server \u00fcbertragen\nssh-copy-id -i ~\/.ssh\/id_ed25519.pub sam@server.firma.de\n\n# Ausgabe nach erfolgreicher \u00dcbertragung:\n# Number of key(s) added: 1\n# Now try logging into the machine, with: \"ssh sam@server.firma.de\"<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Beim ersten Mal fragt der Befehl noch nach dem Passwort des Kontos, weil ja noch kein Schl\u00fcssel hinterlegt ist. Falls <code>ssh-copy-id<\/code> fehlt (etwa auf Windows oder minimalen Images), \u00fcbertragen Sie den Schl\u00fcssel manuell:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code># Manuelle \u00dcbertragung ohne ssh-copy-id\ncat ~\/.ssh\/id_ed25519.pub | ssh sam@server.firma.de \\\n  \"mkdir -p ~\/.ssh && chmod 700 ~\/.ssh && cat >> ~\/.ssh\/authorized_keys && chmod 600 ~\/.ssh\/authorized_keys\"<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Testen Sie jetzt die Anmeldung: <code>ssh sam@server.firma.de<\/code>. Wenn alles stimmt, landen Sie ohne Passwort direkt auf dem Server, h\u00f6chstens die Passphrase des Agenten wird einmal abgefragt. Erst wenn dieser Login funktioniert, deaktivieren wir in Schritt 8 die Passwort-Anmeldung.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"schritt-6-dateirechte-korrekt-setzen\">Schritt 6: Dateirechte korrekt setzen<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">OpenSSH ist bei Dateirechten kompromisslos. Sind der Schl\u00fcssel oder das Verzeichnis zu offen, verweigert der Client oder der Server die Nutzung kommentarlos. Setzen Sie die Rechte sowohl lokal als auch auf dem Server:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code># Lokal und auf dem Server jeweils ausf\u00fchren\nchmod 700 ~\/.ssh                       # nur der Eigent\u00fcmer darf hinein\nchmod 600 ~\/.ssh\/id_ed25519            # privater Schl\u00fcssel: nur lesen\/schreiben f\u00fcr Eigent\u00fcmer\nchmod 644 ~\/.ssh\/id_ed25519.pub        # \u00f6ffentlicher Schl\u00fcssel darf lesbar sein\nchmod 600 ~\/.ssh\/authorized_keys       # auf dem Server\nchmod 600 ~\/.ssh\/config                # falls vorhanden (Schritt 7)<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Die Zahlen sind oktale Rechte: <code>700<\/code> hei\u00dft voller Zugriff f\u00fcr den Eigent\u00fcmer, nichts f\u00fcr Gruppe und andere. <code>600<\/code> erlaubt dem Eigent\u00fcmer Lesen und Schreiben, sonst nichts. Achten Sie zus\u00e4tzlich darauf, dass das Heimatverzeichnis selbst nicht f\u00fcr die Gruppe oder andere schreibbar ist, sonst lehnt ein strenger sshd die Schl\u00fcsselanmeldung ab.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"schritt-7-die-ssh-config-fuer-komfortable-verbindungen\">Schritt 7: Die ~\/.ssh\/config f\u00fcr komfortable Verbindungen<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Statt bei jeder Verbindung Benutzername, Host und Schl\u00fcssel anzugeben, definieren Sie pro Server einen Alias in <code>~\/.ssh\/config<\/code>. Das spart Tipparbeit und macht komplexe Setups \u00fcbersichtlich:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code># ~\/.ssh\/config\nHost produktiv\n    HostName server.firma.de\n    User sam\n    Port 22\n    IdentityFile ~\/.ssh\/id_ed25519\n    IdentitiesOnly yes\n    AddKeysToAgent yes\n\nHost backup\n    HostName 10.0.5.12\n    User admin\n    Port 2222\n    IdentityFile ~\/.ssh\/id_ed25519_backup\n    IdentitiesOnly yes<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Danach gen\u00fcgt <code>ssh produktiv<\/code> oder <code>ssh backup<\/code>. Die Option <code>IdentitiesOnly yes<\/code> ist wichtig: Sie verhindert, dass der Client wahllos alle geladenen Schl\u00fcssel durchprobiert, was bei vielen Schl\u00fcsseln zur Fehlermeldung \u201eToo many authentication failures\u201c f\u00fchrt. <code>AddKeysToAgent yes<\/code> l\u00e4dt den Schl\u00fcssel bei Bedarf automatisch in den Agenten.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"schritt-8-passwort-login-deaktivieren-und-sshd-haerten\">Schritt 8: Passwort-Login deaktivieren und sshd h\u00e4rten<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Jetzt der wichtigste Sicherheitsschritt. Solange Passw\u00f6rter erlaubt sind, n\u00fctzt der sch\u00f6nste Schl\u00fcssel wenig, weil Angreifer einfach Passw\u00f6rter raten. \u00d6ffnen Sie auf dem Server die Datei <code>\/etc\/ssh\/sshd_config<\/code> (oder besser eine Datei unter <code>\/etc\/ssh\/sshd_config.d\/<\/code>) und setzen Sie:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code># \/etc\/ssh\/sshd_config.d\/99-haertung.conf\nPasswordAuthentication no          # Passwort-Login komplett abschalten\nPermitRootLogin no                 # kein direkter Root-Login per SSH\nPubkeyAuthentication yes           # Schl\u00fcssel-Anmeldung erlauben\nKbdInteractiveAuthentication no    # interaktive Passwortabfrage aus\nPermitEmptyPasswords no\nMaxAuthTries 3                     # nach 3 Fehlversuchen trennen\nLoginGraceTime 20                  # 20 Sekunden bis zur erfolgreichen Anmeldung<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Pr\u00fcfen Sie die Syntax und starten Sie den Dienst neu, ohne die bestehende Sitzung zu schlie\u00dfen:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code># Konfiguration auf Syntaxfehler pr\u00fcfen\nsudo sshd -t\n\n# Dienst neu laden (bestehende Sitzungen bleiben offen)\nsudo systemctl reload ssh    # auf manchen Systemen: reload sshd<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\"><strong>Wichtig:<\/strong> Lassen Sie unbedingt die aktuelle SSH-Sitzung ge\u00f6ffnet und testen Sie den neuen Login in einem zweiten Terminal. Sperren Sie sich nicht selbst aus. Die Prinzipien hinter dieser Verschl\u00fcsselung und Server-Authentifizierung \u00e4hneln denen, die wir im Beitrag zu <a href=\"\/de\/https-tls-explained\/\">HTTPS und TLS<\/a> beschreiben.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"schritt-9-hardware-schluessel-mit-fido2-ed25519-sk\">Schritt 9: Hardware-Schl\u00fcssel mit FIDO2 (ed25519-sk)<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Ein rein softwarebasierter Schl\u00fcssel kann kopiert werden, sobald jemand Zugriff auf die Datei und die Passphrase hat. Hardware-Sicherheitsschl\u00fcssel nach FIDO2 l\u00f6sen das: Der geheime Teil verl\u00e4sst nie das Token. OpenSSH unterst\u00fctzt das mit dem Typ <code>ed25519-sk<\/code> (sk steht f\u00fcr \u201esecurity key\u201c). Stecken Sie Ihren YubiKey oder Nitrokey ein und erzeugen Sie:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code># Hardware-gebundenen ed25519-Schl\u00fcssel erzeugen\nssh-keygen -t ed25519-sk -O resident -O verify-required \\\n  -C \"sam-yubikey\" -f ~\/.ssh\/id_ed25519_sk\n\n# Sie werden aufgefordert, den Schl\u00fcssel zu ber\u00fchren (Touch)<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Die Optionen: <code>-O resident<\/code> speichert eine Referenz auf dem Token selbst, sodass Sie den Schl\u00fcssel auf einem neuen Rechner mit <code>ssh-keygen -K<\/code> wiederherstellen k\u00f6nnen. <code>-O verify-required<\/code> verlangt zus\u00e4tzlich eine PIN oder Biometrie, nicht nur eine Ber\u00fchrung. Den \u00f6ffentlichen Teil kopieren Sie wie gewohnt mit <code>ssh-copy-id<\/code> auf den Server. Bei jedem Login leuchtet das Token und verlangt eine Ber\u00fchrung, was Phishing und unbemerkten Fernzugriff praktisch ausschlie\u00dft.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Falls Ihr Server <code>ed25519-sk<\/code> nicht akzeptiert, ist sein OpenSSH zu alt (Unterst\u00fctzung gibt es seit OpenSSH 8.2). Aktualisieren Sie ihn oder nutzen Sie \u00fcbergangsweise den Typ <code>ecdsa-sk<\/code>, den auch \u00e4ltere FIDO2-Token unterst\u00fctzen.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"schritt-10-post-quanten-schluesselaustausch-aktivieren\">Schritt 10: Post-Quanten-Schl\u00fcsselaustausch aktivieren<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">SSH-Schl\u00fcssel selbst sind eine Sache, der Schl\u00fcsselaustausch beim Verbindungsaufbau eine andere. Hier droht das Szenario \u201ejetzt abfangen, sp\u00e4ter entschl\u00fcsseln\u201c: Ein Angreifer speichert heute verschl\u00fcsselten Verkehr und entschl\u00fcsselt ihn, sobald Quantencomputer leistungsf\u00e4hig genug sind. OpenSSH wehrt das mit hybriden Post-Quanten-Verfahren ab, die ein klassisches mit einem quantensicheren Verfahren kombinieren.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Zwei Methoden sind relevant: <code>sntrup761x25519-sha512<\/code> ist seit OpenSSH 9.0 der Standard, <code>mlkem768x25519-sha256<\/code> (auf Basis des NIST-standardisierten ML-KEM) kam mit OpenSSH 9.9 hinzu und ist in der Serie 10.x Standard. Erzwingen Sie die hybriden Verfahren explizit in Ihrer Konfiguration:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code># In ~\/.ssh\/config (Client) oder \/etc\/ssh\/sshd_config (Server)\nKexAlgorithms mlkem768x25519-sha256,sntrup761x25519-sha512,curve25519-sha256\n\n# Ausgehandelten Schl\u00fcsselaustausch einer Verbindung anzeigen\nssh -v produktiv 2>&1 | grep \"kex:\"\n# debug1: kex: algorithm: mlkem768x25519-sha256<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Warum das wichtig ist, vertiefen wir im \u00dcberblick zur <a href=\"\/de\/post-quantum-cryptography-2026\/\">Post-Quanten-Kryptografie<\/a>. Kurz gesagt: Der Schl\u00fcsselaustausch ist die verwundbarste Stelle gegen k\u00fcnftige Quantenangriffe, weil hier das gemeinsame Geheimnis ausgehandelt wird.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"schritt-11-rsa-als-fallback-fuer-legacy-systeme\">Schritt 11: RSA als Fallback f\u00fcr Legacy-Systeme<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Manche \u00e4lteren Ger\u00e4te, Netzwerk-Appliances oder Hosting-Panels verstehen ed25519 nicht. F\u00fcr solche F\u00e4lle erzeugen Sie einen RSA-Schl\u00fcssel mit mindestens 3072 Bit, dem aktuell empfohlenen Minimum:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code># RSA-Fallback mit 3072 Bit und 100 KDF-Runden\nssh-keygen -t rsa -b 3072 -a 100 -C \"sam-rsa-fallback\" -f ~\/.ssh\/id_rsa\n\n# F\u00fcr besonders langlebige Schl\u00fcssel optional 4096 Bit\nssh-keygen -t rsa -b 4096 -a 100 -f ~\/.ssh\/id_rsa_4096<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Verwenden Sie RSA wirklich nur dort, wo es n\u00f6tig ist, und ordnen Sie ihn in der <code>~\/.ssh\/config<\/code> gezielt dem betreffenden Host zu. Vermeiden Sie es, RSA aus Bequemlichkeit \u00fcberall einzusetzen. Ein gemischtes Setup mit ed25519 als Standard und RSA als Ausnahme ist die saubere L\u00f6sung.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"schritt-12-vollstaendiges-beispielprojekt-fuer-zwei-server-plus-git\">Schritt 12: Vollst\u00e4ndiges Beispielprojekt f\u00fcr zwei Server plus Git<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Zum Abschluss bauen wir ein realistisches, lauff\u00e4higes Setup: ein geh\u00e4rteter Hauptzugang, ein Backup-Server auf abweichendem Port und ein separater Deploy-Key, der nur f\u00fcr Git-Pushes auf GitHub gilt. Getrennte Schl\u00fcssel pro Zweck sind ein Grundprinzip: Wird einer kompromittiert, bleibt der Rest sicher.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code># 1. Drei Schl\u00fcssel f\u00fcr drei Zwecke erzeugen\nssh-keygen -t ed25519 -a 100 -C \"sam-produktiv\" -f ~\/.ssh\/id_ed25519\nssh-keygen -t ed25519 -a 100 -C \"sam-backup\"    -f ~\/.ssh\/id_ed25519_backup\nssh-keygen -t ed25519 -a 100 -C \"sam-github\"    -f ~\/.ssh\/id_github\n\n# 2. \u00d6ffentliche Schl\u00fcssel verteilen\nssh-copy-id -i ~\/.ssh\/id_ed25519.pub        sam@server.firma.de\nssh-copy-id -i ~\/.ssh\/id_ed25519_backup.pub admin@10.0.5.12 -p 2222\n# Den GitHub-Schl\u00fcssel im GitHub-Konto unter Settings > SSH Keys hinterlegen:\ncat ~\/.ssh\/id_github.pub<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Jetzt die zentrale Konfiguration, die alles verbindet:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code># ~\/.ssh\/config\nHost produktiv\n    HostName server.firma.de\n    User sam\n    IdentityFile ~\/.ssh\/id_ed25519\n    IdentitiesOnly yes\n    AddKeysToAgent yes\n    KexAlgorithms mlkem768x25519-sha256,sntrup761x25519-sha512\n\nHost backup\n    HostName 10.0.5.12\n    User admin\n    Port 2222\n    IdentityFile ~\/.ssh\/id_ed25519_backup\n    IdentitiesOnly yes\n\nHost github.com\n    HostName github.com\n    User git\n    IdentityFile ~\/.ssh\/id_github\n    IdentitiesOnly yes<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Testen Sie alle drei Verbindungen. Der GitHub-Test best\u00e4tigt die Authentifizierung, ohne eine Shell zu \u00f6ffnen:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>ssh produktiv \"hostname && uptime\"\nssh backup    \"hostname\"\nssh -T git@github.com\n# Hi sam! You've successfully authenticated, but GitHub does not provide shell access.<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Damit steht ein vollst\u00e4ndiges, geh\u00e4rtetes SSH-Setup mit drei zweckgebundenen Schl\u00fcsseln, deaktivierter Passwort-Anmeldung und Post-Quanten-Schl\u00fcsselaustausch. Dasselbe Prinzip sch\u00fctzt im \u00dcbrigen auch verschl\u00fcsselte Tunnel; ein Vergleich der VPN-Protokolle steht in unserem Beitrag <a href=\"\/de\/wireguard-vs-openvpn\/\">WireGuard vs OpenVPN<\/a>.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"haeufige-fehler-beim-ssh-key-erstellen-und-wie-sie-sie-vermeiden\">H\u00e4ufige Fehler beim SSH-Key erstellen und wie Sie sie vermeiden<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Diese Stolperfallen kosten erfahrungsgem\u00e4\u00df die meiste Zeit. Wer sie kennt, spart sich stundenlange Fehlersuche.<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>Privater Schl\u00fcssel ohne Passphrase:<\/strong> Wird die Datei kopiert, ist der Zugang offen. Setzen Sie immer eine Passphrase plus <code>-a 100<\/code>.<\/li>\n<li><strong>Falsche Dateirechte:<\/strong> Ist <code>~\/.ssh<\/code> oder der Schl\u00fcssel zu offen (etwa <code>777<\/code>), verweigert OpenSSH die Nutzung wortlos. <code>chmod 700<\/code> bzw. <code>600<\/code> setzen.<\/li>\n<li><strong>Passwort-Login zu fr\u00fch deaktiviert:<\/strong> Wer <code>PasswordAuthentication no<\/code> setzt, bevor der Schl\u00fcssel-Login getestet ist, sperrt sich aus. Immer erst im zweiten Terminal testen.<\/li>\n<li><strong>\u00d6ffentlichen mit privatem Schl\u00fcssel verwechselt:<\/strong> Auf den Server geh\u00f6rt nur die <code>.pub<\/code>-Datei. Den privaten Schl\u00fcssel niemals hochladen oder per E-Mail verschicken.<\/li>\n<li><strong>Schl\u00fcssel im falschen Verzeichnis:<\/strong> Liegt der Schl\u00fcssel nicht in <code>~\/.ssh<\/code> oder ist er nicht in der <code>config<\/code> referenziert, findet der Client ihn nicht. Mit <code>IdentityFile<\/code> explizit angeben.<\/li>\n<li><strong>Zu viele Schl\u00fcssel im Agenten:<\/strong> Ohne <code>IdentitiesOnly yes<\/code> probiert der Client alle Schl\u00fcssel durch und st\u00f6\u00dft an <code>MaxAuthTries<\/code>. Pro Host genau einen Schl\u00fcssel zuweisen.<\/li>\n<\/ul>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"troubleshooting-die-8-haeufigsten-ssh-fehler-beheben\">Troubleshooting: Die 8 h\u00e4ufigsten SSH-Fehler beheben<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Wenn der Login nicht klappt, hilft der ausf\u00fchrliche Modus <code>ssh -vvv host<\/code>, der jede Aushandlungsstufe protokolliert. Die folgende Tabelle ordnet die h\u00e4ufigsten Meldungen ihrer Ursache und L\u00f6sung zu.<\/p>\n\n\n\n<figure class=\"wp-table\"><table><thead><tr><th>Fehlermeldung<\/th><th>Ursache<\/th><th>L\u00f6sung<\/th><\/tr><\/thead><tbody>\n<tr><td>Permission denied (publickey)<\/td><td>Schl\u00fcssel nicht hinterlegt oder falscher Pfad<\/td><td>authorized_keys pr\u00fcfen, IdentityFile setzen<\/td><\/tr>\n<tr><td>Bad permissions \/ UNPROTECTED KEY FILE<\/td><td>Dateirechte zu offen<\/td><td>chmod 600 auf den privaten Schl\u00fcssel<\/td><\/tr>\n<tr><td>Too many authentication failures<\/td><td>Agent probiert zu viele Schl\u00fcssel<\/td><td>IdentitiesOnly yes setzen<\/td><\/tr>\n<tr><td>Agent admitted failure to sign<\/td><td>Schl\u00fcssel nicht im Agenten geladen<\/td><td>ssh-add ~\/.ssh\/id_ed25519 ausf\u00fchren<\/td><\/tr>\n<tr><td>Connection refused<\/td><td>sshd l\u00e4uft nicht oder falscher Port<\/td><td>Dienststatus und Port pr\u00fcfen<\/td><\/tr>\n<tr><td>no matching key exchange method<\/td><td>Algorithmen von Client und Server passen nicht<\/td><td>OpenSSH aktualisieren, KexAlgorithms anpassen<\/td><\/tr>\n<tr><td>Host key verification failed<\/td><td>Server-Fingerabdruck ge\u00e4ndert<\/td><td>Alten Eintrag in known_hosts entfernen<\/td><\/tr>\n<tr><td>sign_and_send_pubkey: signing failed<\/td><td>FIDO2-Token nicht ber\u00fchrt oder PIN fehlt<\/td><td>Token einstecken, ber\u00fchren, PIN eingeben<\/td><\/tr>\n<\/tbody><\/table><\/figure>\n\n\n\n<p class=\"wp-block-paragraph\">Ein konkretes Beispiel: Nach einem Server-Umzug mit gleicher IP, aber neuem Host-Schl\u00fcssel meldet SSH einen m\u00f6glichen Angriff. Entfernen Sie den veralteten Eintrag gezielt:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code># Veralteten Host-Schl\u00fcssel entfernen und neu verbinden\nssh-keygen -R server.firma.de\nssh produktiv   # akzeptiert den neuen Fingerabdruck nach Best\u00e4tigung<\/code><\/pre>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"profi-tipps-fuer-fortgeschrittene-ssh-setups\">Profi-Tipps f\u00fcr fortgeschrittene SSH-Setups<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Wer die Grundlagen beherrscht, hebt die Sicherheit mit diesen Techniken auf ein professionelles Niveau.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"ssh-zertifikate-statt-einzelner-schluessel\">SSH-Zertifikate statt einzelner Schl\u00fcssel<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">Bei vielen Servern wird das Pflegen einzelner <code>authorized_keys<\/code>-Dateien m\u00fchsam. Eine SSH-Zertifizierungsstelle (CA) signiert \u00f6ffentliche Schl\u00fcssel mit begrenzter G\u00fcltigkeit. Server vertrauen dann nur der CA, nicht jedem einzelnen Schl\u00fcssel:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code># CA-Schl\u00fcssel erzeugen und einen Nutzerschl\u00fcssel f\u00fcr 8 Stunden signieren\nssh-keygen -t ed25519 -f ~\/.ssh\/ca_key -C \"firmen-ca\"\nssh-keygen -s ~\/.ssh\/ca_key -I \"sam\" -n sam -V +8h ~\/.ssh\/id_ed25519.pub<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Die kurze G\u00fcltigkeit (<code>-V +8h<\/code>) bedeutet, dass ein abhandengekommener Schl\u00fcssel sich nach acht Stunden von selbst entwertet. Das langlebige Vertrauen einzelner Schl\u00fcssel entf\u00e4llt damit komplett.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"zugriff-pro-schluessel-einschraenken\">Zugriff pro Schl\u00fcssel einschr\u00e4nken<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">In der <code>authorized_keys<\/code> l\u00e4sst sich vor jedem Schl\u00fcssel festlegen, was er darf. So bindet man einen Deploy-Key auf genau einen Befehl und unterbindet die Port-Weiterleitung:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code># In ~\/.ssh\/authorized_keys auf dem Server\nrestrict,command=\"\/usr\/local\/bin\/deploy.sh\",no-pty ssh-ed25519 AAAAC3Nz...== sam-deploy<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Die Option <code>restrict<\/code> verbietet alles und gibt nur frei, was explizit erlaubt wird. So kann ein automatisierter Schl\u00fcssel ausschlie\u00dflich das Deploy-Skript starten, aber keine interaktive Shell \u00f6ffnen. Wer den Wert kryptografischer Verfahren grunds\u00e4tzlich vertiefen m\u00f6chte, findet eine Einordnung in unserer <a href=\"\/de\/security\/\">\u00dcbersicht zur Online-Sicherheit<\/a>.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"verbindungen-mit-controlmaster-beschleunigen\">Verbindungen mit ControlMaster beschleunigen<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">Wer oft denselben Server anspricht, kann eine bestehende Verbindung wiederverwenden, statt jedes Mal neu auszuhandeln. Das spart sp\u00fcrbar Zeit bei Skripten:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code># In ~\/.ssh\/config erg\u00e4nzen\nHost *\n    ControlMaster auto\n    ControlPath ~\/.ssh\/sockets\/%r@%h:%p\n    ControlPersist 600<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Legen Sie zuvor das Verzeichnis an: <code>mkdir -p ~\/.ssh\/sockets<\/code>. Nach der ersten Verbindung bleibt der Tunnel zehn Minuten (<code>600<\/code> Sekunden) offen und neue Verbindungen springen sofort darauf auf.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"ssh-schluessel-sichern-und-rotieren\">SSH-Schl\u00fcssel sichern und rotieren<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Ein Schl\u00fcssel ist kein Ewigkeitsobjekt. Planen Sie eine Rotation: Erzeugen Sie regelm\u00e4\u00dfig (etwa j\u00e4hrlich oder beim Verdacht einer Kompromittierung) neue Schl\u00fcssel, verteilen Sie die neuen \u00f6ffentlichen Teile und entfernen Sie die alten aus allen <code>authorized_keys<\/code>. Bewahren Sie den privaten Schl\u00fcssel niemals unverschl\u00fcsselt in einem Cloud-Backup auf. Wer ein Backup braucht, verschl\u00fcsselt es zus\u00e4tzlich, etwa mit GnuPG oder einem Passwortmanager, der Dateianh\u00e4nge unterst\u00fctzt.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Die folgende Tabelle fasst eine sinnvolle Rotationspolitik f\u00fcr verschiedene Schl\u00fcsselzwecke zusammen.<\/p>\n\n\n\n<figure class=\"wp-table\"><table><thead><tr><th>Schl\u00fcsselzweck<\/th><th>Typ<\/th><th>Rotation<\/th><th>Backup<\/th><th>Passphrase<\/th><\/tr><\/thead><tbody>\n<tr><td>Pers\u00f6nlicher Login<\/td><td>ed25519<\/td><td>J\u00e4hrlich<\/td><td>Verschl\u00fcsselt<\/td><td>Pflicht<\/td><\/tr>\n<tr><td>Hochsicherer Zugang<\/td><td>ed25519-sk (FIDO2)<\/td><td>Bei Verlust<\/td><td>Resident auf Token<\/td><td>PIN + Touch<\/td><\/tr>\n<tr><td>Deploy \/ CI<\/td><td>ed25519<\/td><td>Halbj\u00e4hrlich<\/td><td>Im Secret-Store<\/td><td>Optional, eingeschr\u00e4nkt<\/td><\/tr>\n<tr><td>Kurzzeit-Zugang<\/td><td>SSH-Zertifikat<\/td><td>St\u00fcndlich\/t\u00e4glich<\/td><td>Nicht n\u00f6tig<\/td><td>\u00dcber CA<\/td><\/tr>\n<tr><td>Legacy-System<\/td><td>rsa 3072<\/td><td>J\u00e4hrlich<\/td><td>Verschl\u00fcsselt<\/td><td>Pflicht<\/td><\/tr>\n<\/tbody><\/table><\/figure>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"ssh-key-erstellen-auf-windows-macos-und-linux\">SSH-Key erstellen auf Windows, macOS und Linux<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Die Befehle in diesem Tutorial sind plattform\u00fcbergreifend identisch, weil sie alle auf demselben OpenSSH-Client beruhen. Trotzdem gibt es bei der Einrichtung kleine Unterschiede, die immer wieder f\u00fcr Verwirrung sorgen. Wer auf einem Mac arbeitet und denselben Schl\u00fcssel sp\u00e4ter auf einem Windows-Rechner nutzen m\u00f6chte, profitiert davon, die Eigenheiten jeder Plattform zu kennen.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Unter <strong>Linux<\/strong> ist OpenSSH praktisch immer vorinstalliert. Das Verzeichnis <code>~\/.ssh<\/code> liegt im Heimatverzeichnis, der Agent l\u00e4uft meist \u00fcber systemd oder den Schl\u00fcsselbund der Desktop-Umgebung. Unter <strong>macOS<\/strong> bringt das System ebenfalls einen OpenSSH-Client mit, der sich tief in den Schl\u00fcsselbund integriert. Die Option <code>--apple-use-keychain<\/code> sorgt daf\u00fcr, dass die Passphrase nach der ersten Eingabe gespeichert bleibt, sodass selbst ein Neustart sie nicht erneut abfragt. Wer die jeweils neueste OpenSSH-Version braucht, etwa f\u00fcr die aktuellsten Post-Quanten-Algorithmen, installiert sie \u00fcber Homebrew parallel zur Systemversion.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Unter <strong>Windows 10 und 11<\/strong> ist der OpenSSH-Client als optionales Feature integriert. Das Schl\u00fcsselverzeichnis liegt unter <code>%USERPROFILE%\\.ssh<\/code>, also typischerweise <code>C:\\Users\\Name\\.ssh<\/code>. Der Authentifizierungs-Agent l\u00e4uft als Windows-Dienst, der erst aktiviert werden muss. Eine h\u00e4ufige Stolperfalle: die Zeilenenden. Wer eine <code>authorized_keys<\/code> unter Windows mit einem ungeeigneten Editor bearbeitet, f\u00fcgt unter Umst\u00e4nden Wagenr\u00fcckl\u00e4ufe (CRLF) ein, die der Server nicht akzeptiert. Nutzen Sie deshalb die PowerShell oder einen Editor, der reine Unix-Zeilenenden (LF) speichert.<\/p>\n\n\n\n<figure class=\"wp-table\"><table><thead><tr><th>Aspekt<\/th><th>Linux<\/th><th>macOS<\/th><th>Windows 10\/11<\/th><\/tr><\/thead><tbody>\n<tr><td>OpenSSH vorinstalliert<\/td><td>Ja<\/td><td>Ja<\/td><td>Optionales Feature<\/td><\/tr>\n<tr><td>Schl\u00fcsselverzeichnis<\/td><td>~\/.ssh<\/td><td>~\/.ssh<\/td><td>%USERPROFILE%\\.ssh<\/td><\/tr>\n<tr><td>Agent<\/td><td>systemd \/ gnome-keyring<\/td><td>Schl\u00fcsselbund<\/td><td>OpenSSH Authentication Agent<\/td><\/tr>\n<tr><td>Passphrase speichern<\/td><td>keyring<\/td><td>&#8211;apple-use-keychain<\/td><td>ssh-add im Dienst<\/td><\/tr>\n<tr><td>Typische Stolperfalle<\/td><td>Heimverzeichnis-Rechte<\/td><td>Agent-Neustart<\/td><td>CRLF-Zeilenenden<\/td><\/tr>\n<\/tbody><\/table><\/figure>\n\n\n\n<p class=\"wp-block-paragraph\">Der entscheidende Punkt: Der private Schl\u00fcssel funktioniert auf allen drei Systemen gleich, solange die Dateirechte stimmen. Sie k\u00f6nnen also auf dem Mac einen Schl\u00fcssel erzeugen und ihn auf einen Linux-Laptop kopieren, ohne ihn neu zu erstellen. Nur die Rechte m\u00fcssen Sie nach dem Kopieren erneut setzen, weil sie beim Transfer \u00fcber manche Dateisysteme verloren gehen.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"ssh-key-gegen-passwort-der-sicherheitsvergleich\">SSH-Key gegen Passwort: Der Sicherheitsvergleich<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Warum \u00fcberhaupt der Aufwand mit Schl\u00fcsseln, wenn ein Passwort doch schneller eingerichtet ist? Die Antwort liegt im Angriffsmodell. Ein Passwort ist ein gemeinsames Geheimnis, das bei jeder Anmeldung \u00fcber die Leitung muss und auf dem Server in irgendeiner Form \u00fcberpr\u00fcft wird. Es l\u00e4sst sich erraten, abfangen, per Phishing entlocken oder aus einem geleakten Datensatz wiederverwenden. SSH-Dienste, die Passw\u00f6rter erlauben, verzeichnen im offenen Internet permanent automatisierte Anmeldeversuche, oft Tausende pro Tag und Server.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Ein SSH-Schl\u00fcssel funktioniert grundlegend anders. Der private Teil verl\u00e4sst nie Ihren Rechner. Bei der Anmeldung beweist der Client dem Server kryptografisch, dass er den privaten Schl\u00fcssel besitzt, ohne ihn jemals zu \u00fcbertragen. Ein Angreifer, der den Netzwerkverkehr mitschneidet, lernt nichts Verwertbares. Selbst wenn die <code>authorized_keys<\/code>-Datei auf dem Server in falsche H\u00e4nde ger\u00e4t, enth\u00e4lt sie nur \u00f6ffentliche Schl\u00fcssel, mit denen sich niemand anmelden kann.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Die Gr\u00f6\u00dfenordnung des Unterschieds ist gewaltig. Ein ed25519-Schl\u00fcssel bietet ein Sicherheitsniveau von rund 128 Bit. Das bedeutet, ein Angreifer m\u00fcsste im Mittel in der Gr\u00f6\u00dfenordnung von 2 hoch 128 Operationen durchf\u00fchren, um ihn zu brechen. Diese Zahl ist so gro\u00df, dass kein heute existierender oder absehbarer klassischer Computer sie bew\u00e4ltigt. Ein typisches Nutzerpasswort dagegen l\u00e4sst sich, wenn es schwach gew\u00e4hlt ist, in Minuten oder Stunden durchprobieren. Kombiniert man den Schl\u00fcssel mit einem FIDO2-Token, kommt eine physische Komponente hinzu, die selbst ein kompromittierter Rechner nicht ersetzen kann.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">F\u00fcr Unternehmen kommt ein praktischer Vorteil hinzu: Nachvollziehbarkeit. Jeder Schl\u00fcssel l\u00e4sst sich einer Person oder einem Dienst zuordnen und einzeln widerrufen, ohne dass alle anderen Zug\u00e4nge ge\u00e4ndert werden m\u00fcssen. Bei gemeinsamen Passw\u00f6rtern ist das unm\u00f6glich. Genau deshalb schreiben viele Compliance-Rahmenwerke und auch die BSI-Empfehlungen die schl\u00fcsselbasierte Authentifizierung f\u00fcr administrative Zug\u00e4nge vor. Wer tiefer in die Frage einsteigen will, wie sichere Authentifizierung im Alltag aussieht, findet weitere Bausteine in unserer <a href=\"\/de\/security\/\">\u00dcbersicht zur Online-Sicherheit<\/a>.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"ssh-key-in-ci-cd-und-automatisierung-nutzen\">SSH-Key in CI\/CD und Automatisierung nutzen<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">In automatisierten Umgebungen wie GitHub Actions, GitLab CI oder einem Deployment-Skript gibt es keinen Menschen, der eine Passphrase eintippt. Hier braucht es ein durchdachtes Vorgehen, damit Automatisierung nicht zur Sicherheitsl\u00fccke wird. Der Schl\u00fcssel der Wahl ist ein dedizierter Deploy-Key, der nur das N\u00f6tigste darf und sich von Ihren pers\u00f6nlichen Schl\u00fcsseln vollst\u00e4ndig trennt.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Erzeugen Sie f\u00fcr die Pipeline einen eigenen Schl\u00fcssel, hinterlegen Sie den \u00f6ffentlichen Teil als read-only Deploy-Key im Repository oder auf dem Zielserver und legen Sie den privaten Teil als verschl\u00fcsseltes Secret im CI-System ab. Niemals den privaten Schl\u00fcssel im Repository selbst speichern, auch nicht in einem vermeintlich privaten. So sieht der Kern eines Deployment-Schritts aus:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code># Beispiel: Deployment-Schritt mit Schl\u00fcssel aus einem CI-Secret\nmkdir -p ~\/.ssh && chmod 700 ~\/.ssh\necho \"$DEPLOY_KEY\" > ~\/.ssh\/id_deploy\nchmod 600 ~\/.ssh\/id_deploy\n\n# Host-Schl\u00fcssel des Servers vorab eintragen, damit keine R\u00fcckfrage h\u00e4ngt\nssh-keyscan -t ed25519 server.firma.de >> ~\/.ssh\/known_hosts\n\n# Mit explizitem Schl\u00fcssel deployen, ohne Agent\nssh -i ~\/.ssh\/id_deploy -o IdentitiesOnly=yes sam@server.firma.de \\\n  \"cd \/var\/www\/app && git pull && systemctl --user restart app\"<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Der Befehl <code>ssh-keyscan<\/code> ist hier wichtig: Ohne vorher hinterlegten Host-Schl\u00fcssel w\u00fcrde die Verbindung auf eine interaktive Best\u00e4tigung warten, die in einer Pipeline nie kommt, und das Skript bliebe h\u00e4ngen. Beschr\u00e4nken Sie den Deploy-Key zus\u00e4tzlich serverseitig mit der in den Profi-Tipps gezeigten <code>command<\/code>-Option auf genau die erlaubte Aktion. Ein in einem CI-Log versehentlich ausgegebener, aber eingeschr\u00e4nkter Schl\u00fcssel richtet dann kaum Schaden an.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">F\u00fcr sehr sicherheitskritische Pipelines lohnt der Blick auf kurzlebige SSH-Zertifikate statt statischer Deploy-Keys. Die Pipeline holt sich dann zu Beginn ein nur wenige Minuten g\u00fcltiges Zertifikat von einer CA, und nach dem Lauf existiert kein dauerhaft g\u00fcltiger Zugang mehr. Das reduziert die Angriffsfl\u00e4che erheblich, weil ein geleaktes Zertifikat schnell wertlos wird.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"haeufig-gestellte-fragen-faq\">H\u00e4ufig gestellte Fragen (FAQ)<\/h2>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"wie-kann-ich-einen-ssh-key-erstellen-der-zu-github-und-meinem-server-passt\">Wie kann ich einen SSH-Key erstellen, der zu GitHub und meinem Server passt?<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">Erzeugen Sie f\u00fcr jeden Zweck einen eigenen ed25519-Schl\u00fcssel und ordnen Sie ihn in der <code>~\/.ssh\/config<\/code> dem jeweiligen Host zu. Ein Schl\u00fcssel f\u00fcr GitHub, ein anderer f\u00fcr den Server. So bleibt bei einem kompromittierten Schl\u00fcssel der Rest sicher, und Sie k\u00f6nnen einzelne Zug\u00e4nge gezielt widerrufen.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"ed25519-oder-rsa-was-soll-ich-2026-nehmen\">ed25519 oder RSA: Was soll ich 2026 nehmen?<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">Nehmen Sie ed25519. Es ist sicherer bei kleinerer Schl\u00fcssell\u00e4nge, schneller und unempfindlicher gegen schlechte Zufallszahlen. RSA mit mindestens 3072 Bit nutzen Sie nur, wenn ein altes System ed25519 nicht versteht.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"muss-ich-eine-passphrase-setzen\">Muss ich eine Passphrase setzen?<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">Ja. Ohne Passphrase ist der private Schl\u00fcssel eine Klartext-Eintrittskarte, sobald jemand die Datei kopiert. Der <code>ssh-agent<\/code> sorgt daf\u00fcr, dass Sie die Passphrase trotzdem nur einmal pro Sitzung eingeben m\u00fcssen.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"wo-wird-der-ssh-key-gespeichert\">Wo wird der SSH-Key gespeichert?<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">Standardm\u00e4\u00dfig im Verzeichnis <code>~\/.ssh<\/code>. Der private Schl\u00fcssel hei\u00dft <code>id_ed25519<\/code>, der \u00f6ffentliche <code>id_ed25519.pub<\/code>. Auf dem Server landet der \u00f6ffentliche Schl\u00fcssel in <code>~\/.ssh\/authorized_keys<\/code> des Zielkontos.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"wie-uebertrage-ich-meinen-schluessel-auf-einen-neuen-computer\">Wie \u00fcbertrage ich meinen Schl\u00fcssel auf einen neuen Computer?<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">Kopieren Sie das Verzeichnis <code>~\/.ssh<\/code> \u00fcber einen verschl\u00fcsselten Kanal (zum Beispiel <code>scp<\/code> oder einen verschl\u00fcsselten USB-Stick). Setzen Sie danach sofort wieder die Rechte mit <code>chmod 700 ~\/.ssh<\/code> und <code>chmod 600 ~\/.ssh\/id_ed25519<\/code>. Bei Hardware-Schl\u00fcsseln stecken Sie einfach das Token um und stellen residente Schl\u00fcssel mit <code>ssh-keygen -K<\/code> wieder her.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"schuetzt-ein-ssh-key-vor-quantencomputern\">Sch\u00fctzt ein SSH-Key vor Quantencomputern?<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">Der Schl\u00fcssel allein nicht direkt, aber der Schl\u00fcsselaustausch beim Verbindungsaufbau l\u00e4sst sich quantensicher machen. Aktivieren Sie hybride Verfahren wie <code>mlkem768x25519-sha256<\/code>, wie in Schritt 10 gezeigt. Das sch\u00fctzt gegen das Szenario, in dem heute abgefangener Verkehr sp\u00e4ter entschl\u00fcsselt wird.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"was-tue-ich-wenn-ich-die-passphrase-vergessen-habe\">Was tue ich, wenn ich die Passphrase vergessen habe?<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">Die Passphrase l\u00e4sst sich nicht wiederherstellen, das ist ihr Sinn. Erzeugen Sie ein neues Schl\u00fcsselpaar, verteilen Sie den neuen \u00f6ffentlichen Schl\u00fcssel auf alle Server und entfernen Sie den alten Eintrag aus den <code>authorized_keys<\/code>. Genau deshalb lohnt eine durchdachte Rotationspolitik.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"fazit-in-30-minuten-zum-sicheren-ssh-zugang\">Fazit: In 30 Minuten zum sicheren SSH-Zugang<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Wer einen <strong>SSH-Key erstellen<\/strong> und richtig einsetzen will, braucht keine Stunden. Die Kernschritte sind: ed25519-Schl\u00fcssel mit Passphrase und <code>-a 100<\/code> erzeugen, mit <code>ssh-copy-id<\/code> verteilen, Dateirechte setzen, in der <code>config<\/code> ordnen und schlie\u00dflich die Passwort-Anmeldung abschalten. Wer mehr Sicherheit will, erg\u00e4nzt einen FIDO2-Hardware-Schl\u00fcssel und den Post-Quanten-Schl\u00fcsselaustausch. Das Ergebnis ist ein Zugang, der gegen Brute-Force, gestohlene Passw\u00f6rter und sogar k\u00fcnftige Quantenangriffe gewappnet ist.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Der wichtigste Rat zum Schluss: Testen Sie jeden Schritt, bevor Sie den n\u00e4chsten gehen, und schlie\u00dfen Sie niemals Ihre letzte funktionierende Sitzung, bevor der neue Login best\u00e4tigt ist. Dann ist ein geh\u00e4rteter SSH-Zugang weniger Risiko und mehr Routine.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"verwandte-beitraege\">Verwandte Beitr\u00e4ge<\/h3>\n\n\n\n<ul class=\"wp-block-list\">\n<li><a href=\"\/de\/argon2-password-hashing-nodejs\/\">Argon2-Passwort-Hashing in Node.js: 11 Schritte<\/a><\/li>\n<li><a href=\"\/de\/https-tls-explained\/\">HTTPS und TLS erkl\u00e4rt: Was das Schloss-Symbol bedeutet<\/a><\/li>\n<li><a href=\"\/de\/post-quantum-cryptography-2026\/\">Post-Quanten-Kryptografie: 50 % des Web bereits sicher<\/a><\/li>\n<li><a href=\"\/de\/wireguard-vs-openvpn\/\">WireGuard vs OpenVPN: 892 vs 222 Mbit\/s im Test<\/a><\/li>\n<li><a href=\"\/de\/digital-signatures\/\">Digitale Signaturen erkl\u00e4rt: Wie sie funktionieren<\/a><\/li>\n<li><a href=\"\/de\/security\/\">Online-Sicherheit: Der praktische Leitfaden<\/a><\/li>\n<\/ul>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"externe-quellen\">Externe Quellen<\/h3>\n\n\n\n<ul class=\"wp-block-list\">\n<li><a href=\"https:\/\/www.openssh.com\/\" target=\"_blank\" rel=\"noopener\">OpenSSH Projekt-Website<\/a><\/li>\n<li><a href=\"https:\/\/www.openssh.com\/txt\/release-9.8\" target=\"_blank\" rel=\"noopener\">OpenSSH 9.8 Release Notes (regreSSHion-Fix)<\/a><\/li>\n<li><a href=\"https:\/\/www.ssh.com\/academy\/ssh\/keygen\" target=\"_blank\" rel=\"noopener\">SSH Academy: ssh-keygen Referenz<\/a><\/li>\n<li><a href=\"https:\/\/www.bsi.bund.de\/SharedDocs\/Downloads\/DE\/BSI\/Publikationen\/TechnischeRichtlinien\/TR02102\/BSI-TR-02102-4.html\" target=\"_blank\" rel=\"noopener\">BSI TR-02102-4: Verwendung von Secure Shell<\/a><\/li>\n<li><a href=\"https:\/\/www.openssh.com\/releasenotes.html\" target=\"_blank\" rel=\"noopener\">OpenSSH Release Notes (alle Versionen)<\/a><\/li>\n<\/ul>\n\n","protected":false},"excerpt":{"rendered":"<p>Ein SSH-Key ersetzt das Passwort beim Anmelden auf einem Server durch ein kryptografisches Schl\u00fcsselpaar. Wer 2026 noch mit Passw\u00f6rtern arbeitet, l\u00e4dt Brute-Force-Angriffe geradezu ein: Die OpenSSH-L\u00fccke regreSSHion (CVE-2024-6387) hat 2024\u2026<\/p>\n","protected":false},"author":4,"featured_media":61,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[3],"tags":[],"class_list":["post-60","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-security"],"_links":{"self":[{"href":"https:\/\/shattered.io\/de\/wp-json\/wp\/v2\/posts\/60","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/shattered.io\/de\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/shattered.io\/de\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/shattered.io\/de\/wp-json\/wp\/v2\/users\/4"}],"replies":[{"embeddable":true,"href":"https:\/\/shattered.io\/de\/wp-json\/wp\/v2\/comments?post=60"}],"version-history":[{"count":0,"href":"https:\/\/shattered.io\/de\/wp-json\/wp\/v2\/posts\/60\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/shattered.io\/de\/wp-json\/wp\/v2\/media\/61"}],"wp:attachment":[{"href":"https:\/\/shattered.io\/de\/wp-json\/wp\/v2\/media?parent=60"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/shattered.io\/de\/wp-json\/wp\/v2\/categories?post=60"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/shattered.io\/de\/wp-json\/wp\/v2\/tags?post=60"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}