SSH-Schlüssel erstellen und sicher verwenden – Schritt für Schritt
SSH (Secure Shell) ist das Standardprotokoll, um sich sicher mit entfernten Servern zu verbinden. Wer einmal SSH-Schlüssel eingerichtet hat, möchte nie wieder ohne: Kein Passwort eintippen, keine Brute-Force-Gefahr, und die Verbindung ist kryptographisch abgesichert.
Dieser Guide erklärt alles: Schlüssel erstellen, auf Server übertragen, ~/.ssh/config einrichten, und den Server absichern.
Wie SSH-Schlüssel funktionieren
SSH verwendet asymmetrische Kryptographie – du erzeugst ein Schlüsselpaar:
Privater Schlüssel (~/.ssh/id_ed25519) → nur auf DEINEM Rechner, niemals teilen!
Öffentlicher Schlüssel (~/.ssh/id_ed25519.pub) → wird auf Servern hinterlegt
Der Ablauf einer SSH-Verbindung:
1. Du verbindest dich mit einem Server
2. Server schickt eine Zufallsnachricht (Challenge)
3. Dein Client signiert diese mit deinem privaten Schlüssel
4. Server prüft die Signatur mit deinem öffentlichen Schlüssel
5. Passt: Verbindung wird aufgebaut – ohne Passwort!
Der private Schlüssel verlässt deinen Rechner nie. Der öffentliche Schlüssel auf dem Server allein reicht nicht aus, um sich einzuloggen.
Welcher Schlüsseltyp? Ed25519 vs. RSA
| Ed25519 | RSA | |
|---|---|---|
| Algorithmus | Elliptic Curve | RSA |
| Schlüssellänge | 256 Bit | 2048–4096 Bit |
| Sicherheit | sehr hoch | gut (ab 3072 Bit) |
| Performance | sehr schnell | langsamer |
| Kompatibilität | modern (OpenSSH 6.5+) | universell |
| Empfehlung 2026 | ✅ bevorzugt | Fallback für alte Systeme |
Empfehlung: Nutze immer Ed25519. Es ist kleiner, schneller und gilt als sicherer als RSA. Nur bei sehr alten Servern oder Geräten, die Ed25519 nicht unterstützen, greife auf RSA 4096 zurück.
Schlüsselpaar erstellen mit ssh-keygen
# Ed25519-Schlüsselpaar erstellen (empfohlen)
ssh-keygen -t ed25519 -C "deine-email@beispiel.de"
Der Befehl fragt nach:
Enter file in which to save the key (/home/andre/.ssh/id_ed25519):
→ Einfach Enter drücken für den Standardpfad. Oder eigenen Pfad/Namen angeben (z.B. ~/.ssh/mein-server).
Enter passphrase (empty for no passphrase):
Enter same passphrase again:
Passphrase – unbedingt verwenden!
Die Passphrase verschlüsselt den privaten Schlüssel auf der Festplatte. Kommt jemand an deine Schlüsseldatei, kann er ohne Passphrase nichts damit anfangen. Mit ssh-agent musst du die Passphrase trotzdem nur einmal pro Sitzung eingeben.
Ergebnis
ls -la ~/.ssh/
# -rw------- 1 andre andre 411 Feb 18 10:00 id_ed25519
# -rw-r--r-- 1 andre andre 98 Feb 18 10:00 id_ed25519.pub
id_ed25519– dein privater Schlüssel (chmod 600 – nur du darfst lesen!)id_ed25519.pub– dein öffentlicher Schlüssel (darf geteilt werden)
Öffentlichen Schlüssel anzeigen
cat ~/.ssh/id_ed25519.pub
# Ausgabe:
# ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAA... deine-email@beispiel.de
Diese Zeile kommt auf den Server.
RSA-Schlüssel (Fallback für ältere Systeme)
# RSA mit 4096 Bit (nur wenn ed25519 nicht unterstützt wird)
ssh-keygen -t rsa -b 4096 -C "deine-email@beispiel.de"
Öffentlichen Schlüssel auf Server übertragen
Methode 1: ssh-copy-id (einfachste Methode)
# Schlüssel auf Server kopieren (einmalig mit Passwort)
ssh-copy-id benutzername@server-ip
# Mit spezifischem Schlüssel
ssh-copy-id -i ~/.ssh/id_ed25519.pub benutzername@server-ip
# Mit anderem Port
ssh-copy-id -p 2222 benutzername@server-ip
ssh-copy-id fügt deinen Schlüssel zur Datei ~/.ssh/authorized_keys auf dem Server hinzu.
Methode 2: Manuell (wenn ssh-copy-id nicht verfügbar)
# Öffentlichen Schlüssel anzeigen und kopieren
cat ~/.ssh/id_ed25519.pub
# Auf dem Server: Verzeichnis erstellen und Schlüssel eintragen
ssh benutzername@server-ip
mkdir -p ~/.ssh
chmod 700 ~/.ssh
echo "HIER_DEINEN_OEFFENTLICHEN_SCHLUESSEL_EINFUEGEN" >> ~/.ssh/authorized_keys
chmod 600 ~/.ssh/authorized_keys
exit
Methode 3: Per Pipe (ohne manuelle Schritte)
cat ~/.ssh/id_ed25519.pub | ssh benutzername@server-ip \
"mkdir -p ~/.ssh && chmod 700 ~/.ssh && cat >> ~/.ssh/authorized_keys && chmod 600 ~/.ssh/authorized_keys"
Schlüssel bei Cloud-Providern
Bei Cloud-VMs (Hetzner, DigitalOcean, AWS, etc.) gibst du den öffentlichen Schlüssel direkt beim Erstellen der Instanz an – das ist einfacher und sicherer als nachträgliches Kopieren.
# Ausgabe des öffentlichen Schlüssels für Einfügen ins Web-Interface
cat ~/.ssh/id_ed25519.pub
SSH-Verbindung aufbauen
# Basisverbindung
ssh benutzername@server-ip
# Mit spezifischem Port
ssh -p 2222 benutzername@server-ip
# Mit spezifischem Schlüssel
ssh -i ~/.ssh/id_ed25519 benutzername@server-ip
# Verbose-Modus (für Debugging)
ssh -v benutzername@server-ip # mehr Details: -vv oder -vvv
# Einzelnen Befehl remote ausführen (ohne interaktive Shell)
ssh benutzername@server-ip 'uptime'
ssh benutzername@server-ip 'docker ps'
Dateien übertragen mit scp und rsync
# scp: einzelne Datei auf Server kopieren
scp datei.txt benutzername@server-ip:/remote/pfad/
# Verzeichnis übertragen
scp -r ordner/ benutzername@server-ip:/remote/pfad/
# Datei vom Server herunterladen
scp benutzername@server-ip:/remote/datei.txt ./lokal/
# rsync: effizienter für größere Mengen (nur Änderungen übertragen)
rsync -avz ./lokal/ benutzername@server-ip:/remote/pfad/
# Mit Fortschrittsanzeige
rsync -avz --progress ./lokal/ benutzername@server-ip:/remote/pfad/
# Löscht auf dem Ziel, was lokal nicht mehr existiert
rsync -avz --delete ./lokal/ benutzername@server-ip:/remote/pfad/
~/.ssh/config – SSH komfortabel konfigurieren
Statt jedes Mal die IP, den Benutzernamen und den Port einzutippen, kannst du Hosts in ~/.ssh/config definieren.
Config-Datei erstellen
touch ~/.ssh/config
chmod 600 ~/.ssh/config
Beispiel-Konfiguration
# ~/.ssh/config
# Allgemeine Einstellungen (für alle Hosts)
Host *
ServerAliveInterval 60
ServerAliveCountMax 3
AddKeysToAgent yes
IdentityFile ~/.ssh/id_ed25519
# Produktionsserver
Host prod
HostName 203.0.113.10
User deploy
Port 22
IdentityFile ~/.ssh/id_ed25519
# Staging-Server
Host staging
HostName 203.0.113.20
User deploy
Port 2222
IdentityFile ~/.ssh/id_ed25519
# Entwicklungs-Server mit Passwort-Authentifizierung (Ausnahme)
Host dev-alt
HostName 10.0.0.5
User admin
PreferredAuthentications password
# Jump Host / Bastion Host (Server hinter Firewall)
Host interne-db
HostName 10.10.0.5
User dba
ProxyJump prod
Mit konfigurierten Hosts verbinden
# Statt: ssh deploy@203.0.113.10
ssh prod
# Statt: ssh -p 2222 deploy@203.0.113.20
ssh staging
# Datei auf Prod-Server kopieren
scp datei.txt prod:/deploy/
# Durch Bastion Host verbinden
ssh interne-db
Wichtige Config-Optionen
| Option | Bedeutung |
|---|---|
Host |
Alias-Name für diesen Eintrag |
HostName |
IP oder Hostname des Servers |
User |
Benutzername auf dem Server |
Port |
SSH-Port (Standard: 22) |
IdentityFile |
Pfad zum privaten Schlüssel |
ProxyJump |
Verbindung über Bastion/Jump Host |
ServerAliveInterval |
Keep-Alive-Pakete alle X Sekunden |
ForwardAgent |
SSH-Agent-Forwarding (mit Vorsicht!) |
Compression |
Kompression für langsame Verbindungen |
ssh-agent – Passphrase nur einmal eingeben
Mit einer Passphrase wäre SSH lästig, wenn man sie bei jeder Verbindung eingeben müsste. Der ssh-agent hält den entschlüsselten Schlüssel im Speicher, sodass du die Passphrase nur einmal pro Sitzung eingibst.
# Agent starten (falls nicht automatisch gestartet)
eval "$(ssh-agent -s)"
# Schlüssel zum Agent hinzufügen (Passphrase einmalig eingeben)
ssh-add ~/.ssh/id_ed25519
# Geladene Schlüssel anzeigen
ssh-add -l
# Schlüssel aus dem Agent entfernen
ssh-add -D
# Alle Schlüssel entfernen
ssh-add -D
Automatisches Laden (in ~/.bashrc oder ~/.zshrc)
# ~/.bashrc oder ~/.zshrc am Ende hinzufügen:
if [ -z "$SSH_AUTH_SOCK" ]; then
eval "$(ssh-agent -s)"
ssh-add ~/.ssh/id_ed25519 2>/dev/null
fi
Unter GNOME und KDE wird ssh-agent oft automatisch gestartet und in ~/.ssh/config mit AddKeysToAgent yes automatisch befüllt.
Keychain (alternative Methode)
sudo apt install keychain
# In ~/.bashrc:
eval "$(keychain --eval --quiet ~/.ssh/id_ed25519)"
Server absichern (SSH Hardening)
Nach der Einrichtung von SSH-Schlüsseln solltest du den Server absichern. Die SSH-Konfiguration findest du unter /etc/ssh/sshd_config.
Wichtig: Bevor du die SSH-Konfiguration änderst, behalte eine aktive SSH-Session offen und teste alle Änderungen in einer zweiten Session. So kannst du bei einem Fehler korrigieren, ohne ausgesperrt zu werden.
Passwort-Authentifizierung deaktivieren
Sobald SSH-Schlüssel funktionieren, deaktiviere die Passwort-Anmeldung:
sudo nano /etc/ssh/sshd_config
Suche und setze (oder füge hinzu):
# Passwort-Login deaktivieren
PasswordAuthentication no
# Root-Login verbieten
PermitRootLogin no
# Leere Passwörter verbieten
PermitEmptyPasswords no
# X11-Weiterleitung deaktivieren (falls nicht gebraucht)
X11Forwarding no
# Maximale Verbindungsversuche
MaxAuthTries 3
# Verbindungszeit-Limit beim Login
LoginGraceTime 30
# Erlaubte Benutzer (optional, schränkt weiter ein)
AllowUsers deploy andre
Änderungen übernehmen:
# Konfiguration auf Fehler prüfen
sudo sshd -t
# SSH-Dienst neu laden (ohne laufende Verbindungen zu trennen)
sudo systemctl reload sshd
# In neuer Session testen, ob Login noch funktioniert!
ssh prod
SSH auf einen anderen Port verlegen (optional)
Viele Angreifer scannen Port 22. Ein anderer Port reduziert den „Scan-Lärm" in den Logs (Security through Obscurity – kein echter Schutz, aber nützlich gegen automatische Bots):
Port 2222
Hinweis: Firewall-Regeln müssen angepasst werden! Vergiss das nicht, sonst sperrst du dich aus.
# UFW Firewall-Regel für neuen Port (Ubuntu/Debian)
sudo ufw allow 2222/tcp
sudo ufw deny 22/tcp
# firewalld (Fedora/RHEL)
sudo firewall-cmd --permanent --add-port=2222/tcp
sudo firewall-cmd --permanent --remove-service=ssh
sudo firewall-cmd --reload
Fail2Ban – Brute-Force-Schutz
Fail2Ban überwacht Login-Versuche und sperrt IPs nach zu vielen Fehlversuchen:
sudo apt install fail2ban
# Konfiguration anpassen (immer .local-Dateien anlegen, nie .conf direkt bearbeiten)
sudo cp /etc/fail2ban/jail.conf /etc/fail2ban/jail.local
sudo nano /etc/fail2ban/jail.local
Relevante Einstellungen in [sshd]:
[sshd]
enabled = true
port = ssh # oder den neuen Port: 2222
filter = sshd
maxretry = 5 # Versuche bis Sperre
findtime = 600 # Zeitfenster in Sekunden (10 Min)
bantime = 3600 # Sperrzeit in Sekunden (1 Stunde)
sudo systemctl enable --now fail2ban
# Gesperrte IPs anzeigen
sudo fail2ban-client status sshd
# IP entsperren
sudo fail2ban-client set sshd unbanip 203.0.113.99
Mehrere Schlüssel verwalten
Für verschiedene Projekte, Server oder GitHub/GitLab empfehlen sich separate Schlüssel:
# Schlüssel für GitHub
ssh-keygen -t ed25519 -C "github-privat" -f ~/.ssh/id_github
# Schlüssel für Arbeitsprojekt
ssh-keygen -t ed25519 -C "arbeit-server" -f ~/.ssh/id_arbeit
In ~/.ssh/config gezielt zuordnen:
# GitHub (privat)
Host github.com
HostName github.com
User git
IdentityFile ~/.ssh/id_github
AddKeysToAgent yes
# GitLab (Arbeit)
Host gitlab.firma.de
HostName gitlab.firma.de
User git
IdentityFile ~/.ssh/id_arbeit
# Produktionsserver (Arbeit)
Host prod-arbeit
HostName 10.20.30.40
User deploy
IdentityFile ~/.ssh/id_arbeit
SSH-Keys zu GitHub / GitLab hinzufügen
# Öffentlichen Schlüssel anzeigen
cat ~/.ssh/id_github.pub
# Inhalt kopieren und auf GitHub einfügen:
# github.com → Settings → SSH and GPG keys → New SSH key
# Verbindung testen
ssh -T git@github.com
# Ausgabe: Hi username! You've successfully authenticated...
Häufige Fehler und Lösungen
Permission denied (publickey)
Permission denied (publickey).
Ursachen und Lösungen:
# 1. Schlüssel laden prüfen
ssh-add -l
# 2. Mit spezifischem Schlüssel probieren
ssh -i ~/.ssh/id_ed25519 user@server
# 3. Verbose-Modus für Details
ssh -vvv user@server
# 4. Berechtigungen auf dem Server prüfen
# Auf dem Server:
ls -la ~/.ssh/
# authorized_keys muss 600 sein, ~/.ssh muss 700 sein
chmod 700 ~/.ssh
chmod 600 ~/.ssh/authorized_keys
# 5. Inhalt von authorized_keys prüfen
cat ~/.ssh/authorized_keys
# Muss den öffentlichen Schlüssel enthalten
SSH-Agent enthält keine Schlüssel
The agent has no identities.
ssh-add ~/.ssh/id_ed25519
# Passphrase eingeben
ssh-add -l # jetzt sollte der Schlüssel erscheinen
Connection refused
ssh: connect to host server-ip port 22: Connection refused
Ursachen:
- SSH-Dienst läuft nicht auf dem Server
- Firewall blockiert Port 22
- Falscher Port
# Auf dem Server prüfen
sudo systemctl status sshd
# Firewall prüfen
sudo ufw status
# Port prüfen
sudo ss -ltnp | grep :22
Host key verification failed
WARNING: REMOTE HOST IDENTIFICATION HAS CHANGED!
Das bedeutet, der Server-Schlüssel hat sich verändert (nach Neuinstallation normal, sonst möglicher Man-in-the-Middle-Angriff!).
# Alten Eintrag entfernen (nur wenn du dir sicher bist)
ssh-keygen -R server-ip
# Dann neu verbinden – du wirst nach dem neuen Fingerprint gefragt
ssh user@server-ip
Rollback: SSH-Zugang wiederherstellen
Falls du dich ausgesperrt hast (z.B. falsche sshd_config ohne Test):
Option 1: Konsolen-Zugang (VPS/Cloud)
Cloud-Anbieter (Hetzner, DigitalOcean, AWS, etc.) bieten immer einen Web-Konsolen-Zugang ohne SSH. Nutze die Web-Konsole:
# SSH-Config reparieren
sudo nano /etc/ssh/sshd_config
# Syntax-Check
sudo sshd -t
# Dienst neu starten
sudo systemctl restart sshd
Option 2: Passwort-Login temporär wiederherstellen
Über Konsolen-Zugang in /etc/ssh/sshd_config:
PasswordAuthentication yes
sudo systemctl restart sshd
Dann per SSH mit Passwort verbinden und Problem beheben. Danach wieder auf no setzen.
Option 3: Neuen Schlüssel hinterlegen
Wenn der private Schlüssel verloren gegangen ist:
# Neues Schlüsselpaar erstellen
ssh-keygen -t ed25519 -f ~/.ssh/id_ed25519_neu
# Über Konsolen-Zugang öffentlichen Schlüssel auf Server setzen
cat ~/.ssh/id_ed25519_neu.pub
# Inhalt in ~/.ssh/authorized_keys auf dem Server eintragen
Fazit
SSH mit Schlüsseln ist der Standard für sichere Server-Kommunikation. Die Einrichtung dauert 10 Minuten und eliminiert danach Passwort-Eingaben und Brute-Force-Risiken.
Zusammenfassung der Best Practices:
- Ed25519-Schlüssel verwenden
- Passphrase auf den Schlüssel setzen
~/.ssh/configfür alle Server anlegen- Passwort-Login auf dem Server deaktivieren
- Root-Login deaktivieren (
PermitRootLogin no) - Fail2Ban installieren
- Schlüssel pro Projekt/Zweck trennen