SSH (Secure Shell) ist das meistgenutzte Protokoll zur Fernverwaltung von Linux- und Unix-Systemen.
Genau deshalb ist es auch eines der bevorzugten Angriffsziele im Internet. Wer einen Server mit
öffentlich erreichbarem SSH-Port betreibt, kann in den Log-Dateien innerhalb weniger Stunden
Tausende von fehlgeschlagenen Anmeldeversuchen beobachten. Diese Angriffe laufen vollautomatisch
ab: Botnetze scannen kontinuierlich den gesamten IPv4-Adressraum nach offenem Port 22 und probieren
anschließend massenhaft Benutzername-Passwort-Kombinationen durch.
Zwei Angriffsmethoden dominieren dabei: Brute-Force-Angriffe, bei denen systematisch
alle möglichen Passwörter ausprobiert werden, und Credential Stuffing, bei dem
geleakte Zugangsdaten aus anderen Datenpannen direkt gegen SSH-Server getestet werden. Letzteres
ist besonders gefährlich, weil viele Nutzer identische Passwörter auf mehreren Diensten verwenden.
Die gute Nachricht: Mit einer konsequenten Härtung des SSH-Dienstes lässt sich das Angriffspotenzial
drastisch reduzieren. Die meisten Maßnahmen sind in wenigen Minuten umgesetzt und erfordern kein
tiefes Sicherheitswissen. Dieser Artikel führt Schritt für Schritt durch die wichtigsten
Härtungsmaßnahmen – von der sshd_config über fail2ban bis hin zu fortgeschrittenen Techniken
wie Port Knocking und SSH-Zertifikaten.
Wichtiger Hinweis: Bevor Änderungen an der SSH-Konfiguration vorgenommen werden,
sollte immer eine zweite SSH-Sitzung geöffnet bleiben, um bei Konfigurationsfehlern nicht
ausgesperrt zu werden. Außerdem empfiehlt sich ein Test mit sshd -t vor dem
Neustart des Dienstes, um Syntaxfehler zu erkennen.
2. Schlüsseltypen und Key-Management
Die sicherste Authentifizierungsmethode für SSH ist die Public-Key-Authentifizierung. Anstelle
eines Passworts wird ein kryptografisches Schlüsselpaar verwendet: Der private Schlüssel verbleibt
auf dem Client, der öffentliche Schlüssel wird auf dem Server hinterlegt. Ein Angreifer, der das
Passwort kennt, kommt damit nicht weiter – er benötigt zusätzlich den privaten Schlüssel.
2.1 RSA vs. Ed25519
Aktuell sind zwei Schlüsseltypen für neue Schlüsselpaare empfehlenswert:
Ed25519 ist der bevorzugte Algorithmus. Er basiert auf elliptischen Kurven
(Edwards-curve Digital Signature Algorithm) und bietet bei sehr kurzen Schlüsseln (256 Bit)
eine hohe Sicherheit, schnelle Operationen und Resistenz gegen bestimmte Seitenkanalangriffe.
Ed25519 wird von allen modernen SSH-Implementierungen unterstützt.
RSA ist weit verbreitet und kompatibel mit älteren Systemen. Für RSA gilt
heute eine Mindestlänge von 4096 Bit. Schlüssel mit 1024 oder 2048 Bit
gelten als veraltet und sollten ersetzt werden. RSA-Schlüssel sind deutlich größer als
Ed25519-Schlüssel bei vergleichbarer oder geringerer Sicherheit.
ECDSA (Elliptic Curve DSA) ist ebenfalls verfügbar, wird aber gegenüber
Ed25519 nicht bevorzugt, da Ed25519 eine sicherere Kurve verwendet.
2.2 Schlüssel generieren
Ein neues Ed25519-Schlüsselpaar wird auf dem Client mit folgendem Befehl erzeugt:
# Ed25519 (empfohlen)
ssh-keygen -t ed25519 -C "kommentar@beispiel.de"
# RSA mit 4096 Bit (für Kompatibilität mit älteren Systemen)
ssh-keygen -t rsa -b 4096 -C "kommentar@beispiel.de"
Der Befehl fragt nach einem Speicherort (Standard: ~/.ssh/id_ed25519) und einer
Passphrase. Die Passphrase schützt den privaten Schlüssel zusätzlich, falls die Schlüsseldatei
in falsche Hände gerät. Sie sollte nie leer gelassen werden.
2.3 Öffentlichen Schlüssel auf den Server übertragen
# Komfortabler Weg mit ssh-copy-id
ssh-copy-id -i ~/.ssh/id_ed25519.pub benutzer@server
# Manueller Weg
cat ~/.ssh/id_ed25519.pub | ssh benutzer@server "mkdir -p ~/.ssh && cat >> ~/.ssh/authorized_keys"
2.4 authorized_keys verwalten
Die Datei ~/.ssh/authorized_keys enthält alle erlaubten öffentlichen Schlüssel,
einen pro Zeile. Wichtig sind korrekte Berechtigungen – ohne diese verweigert OpenSSH den
Zugang aus Sicherheitsgründen:
chmod 700 ~/.ssh
chmod 600 ~/.ssh/authorized_keys
Nicht mehr benötigte Schlüssel sollten regelmäßig aus der Datei entfernt werden.
In größeren Umgebungen empfiehlt sich der Einsatz von SSH-Zertifikaten (siehe Abschnitt 6),
um das Key-Management zu zentralisieren.
3. sshd_config härten
Die Hauptkonfigurationsdatei des SSH-Daemons liegt unter /etc/ssh/sshd_config.
Nach jeder Änderung muss der SSH-Dienst neu geladen werden:
# Konfiguration auf Syntaxfehler prüfen
sudo sshd -t
# Dienst neu laden (ohne bestehende Verbindungen zu trennen)
sudo systemctl reload sshd
3.1 Passwort-Authentifizierung deaktivieren
Sobald die Public-Key-Authentifizierung funktioniert, sollte die Passwort-Authentifizierung
vollständig deaktiviert werden. Das eliminiert Brute-Force- und Credential-Stuffing-Angriffe
auf einen Schlag.
PasswordAuthentication no
ChallengeResponseAuthentication no
UsePAM no
3.2 Root-Login verbieten
Der direkte Login als root über SSH sollte grundsätzlich verboten sein. Administratoren
melden sich als normaler Benutzer an und wechseln bei Bedarf mit sudo oder
su zu erhöhten Rechten.
PermitRootLogin no
Falls root-Zugang zwingend benötigt wird (z. B. für automatisierte Deployments), kann
alternativ PermitRootLogin prohibit-password gesetzt werden. Damit ist
nur Key-basierter root-Login erlaubt, aber keine Passwort-Anmeldung.
3.3 Erlaubte Benutzer und Gruppen einschränken
Mit AllowUsers und AllowGroups lässt sich festlegen, welche
Konten sich überhaupt per SSH anmelden dürfen. Alle anderen Konten werden pauschal abgewiesen,
selbst wenn die Authentifizierung erfolgreich wäre.
# Nur bestimmte Benutzer erlauben
AllowUsers alice bob deploy
# Oder: Nur Mitglieder einer bestimmten Gruppe erlauben
AllowGroups sshusers
3.4 Port ändern
Den SSH-Port von 22 auf einen anderen Wert zu setzen, ist eine Maßnahme der
"Security through Obscurity" und ersetzt keine echte Sicherheit. Sie reduziert
jedoch den automatisierten Scan-Traffic erheblich, da die meisten Bots ausschließlich
Port 22 scannen. Ein Port im Bereich 1024–65535 ist üblich.
Port 2222
Achtung: Firewalls und ggf. SELinux/AppArmor müssen angepasst werden.
Der neue Port muss in der Firewall freigegeben und der alte gesperrt werden.
# Maximale Fehlversuche pro Verbindung
MaxAuthTries 3
# Zeitfenster für einen Anmeldevorgang in Sekunden
LoginGraceTime 30
# Maximale gleichzeitige nicht-authentifizierte Verbindungen
MaxStartups 10:30:60
MaxStartups 10:30:60 bedeutet: Ab 10 offenen, nicht-authentifizierten
Verbindungen werden 30 % der neuen Verbindungen zufällig abgelehnt; ab 60 werden alle
abgelehnt. Das erschwert parallele Angriffe erheblich.
3.6 Protokollversion erzwingen
SSH Protocol 1 gilt als unsicher und sollte nie verwendet werden. Moderne OpenSSH-Versionen
unterstützen ausschließlich Protocol 2 – zur Sicherheit kann dies explizit erzwungen werden:
Protocol 2
3.7 Starke Kryptografie erzwingen
Mit den Direktiven Ciphers, MACs und KexAlgorithms
können veraltete und schwache Algorithmen ausgeschlossen werden. Die folgende Konfiguration
erlaubt nur moderne, als sicher geltende Algorithmen:
# Nur starke symmetrische Verschlüsselungsverfahren
Ciphers chacha20-poly1305@openssh.com,aes256-gcm@openssh.com,aes128-gcm@openssh.com,aes256-ctr,aes192-ctr,aes128-ctr
# Nur starke MAC-Algorithmen
MACs hmac-sha2-512-etm@openssh.com,hmac-sha2-256-etm@openssh.com,umac-128-etm@openssh.com
# Nur starke Schlüsselaustauschverfahren
KexAlgorithms curve25519-sha256,curve25519-sha256@libssh.org,diffie-hellman-group16-sha512,diffie-hellman-group18-sha512
Welche Algorithmen der eigene OpenSSH-Server unterstützt, lässt sich mit
ssh -Q cipher, ssh -Q mac und ssh -Q kex abfragen.
3.8 Weitere sinnvolle Einstellungen
# X11-Weiterleitung deaktivieren (sofern nicht benötigt)
X11Forwarding no
# TCP-Weiterleitung deaktivieren (sofern nicht benötigt)
AllowTcpForwarding no
# Agent-Weiterleitung deaktivieren
AllowAgentForwarding no
# SSH-Banner anzeigen (optionaler Hinweis auf unbefugten Zugriff)
Banner /etc/ssh/banner.txt
# Leerlauf-Timeout: Verbindung nach 5 Minuten Inaktivität trennen
ClientAliveInterval 300
ClientAliveCountMax 2
4. Zwei-Faktor-Authentifizierung
Auch wenn Public-Key-Authentifizierung bereits sehr sicher ist, lässt sich mit einem
zweiten Faktor (TOTP – Time-based One-Time Password) die Sicherheit weiter erhöhen.
Selbst ein kompromittierter privater Schlüssel reicht dann allein nicht mehr aus.
Die Integration erfolgt über das PAM-Modul libpam-google-authenticator,
das TOTP-fähige Apps wie Google Authenticator, Aegis oder Authy unterstützt.
4.1 libpam-google-authenticator installieren
sudo apt install libpam-google-authenticator
4.2 TOTP für einen Benutzer einrichten
Als der betreffende Benutzer (nicht als root) wird das Setup-Tool ausgeführt:
google-authenticator
Das Tool generiert einen QR-Code, der mit einer Authenticator-App gescannt wird.
Zusätzlich werden Notfall-Codes ausgegeben für den Fall, dass das zweite Gerät nicht
verfügbar ist. Diese Codes müssen sicher aufbewahrt werden, da jeder Code nur einmal
verwendbar ist.
4.3 PAM konfigurieren
In /etc/pam.d/sshd wird die Google-Authenticator-Integration aktiviert.
Die Zeile wird am Ende der Datei hinzugefügt:
Mit AuthenticationMethods publickey,keyboard-interactive müssen beide Faktoren
erfolgreich sein: zuerst der SSH-Key, danach der TOTP-Code. Wer nur TOTP ohne Key erzwingen
möchte, setzt stattdessen AuthenticationMethods keyboard-interactive. Nach der
Konfigurationsänderung den SSH-Dienst neu laden und die Funktion mit einer neuen Verbindung
testen, bevor die aktuelle Sitzung beendet wird.
5. fail2ban einrichten
fail2ban überwacht Log-Dateien auf verdächtige Muster und sperrt automatisch IP-Adressen,
die zu viele fehlgeschlagene Anmeldeversuche produzieren. Damit wird Brute-Force-Traffic
auf Netzwerkebene geblockt, bevor er den SSH-Daemon überhaupt erreicht.
Die Standardkonfiguration liegt in /etc/fail2ban/jail.conf. Eigene Anpassungen
gehören ausschließlich in /etc/fail2ban/jail.local, damit sie bei Paket-Updates
nicht überschrieben werden:
# Status aller Jails anzeigen
sudo fail2ban-client status
# Status des SSH-Jails
sudo fail2ban-client status sshd
# Eine gesperrte IP manuell freigeben
sudo fail2ban-client set sshd unbanip 203.0.113.42
# Eine IP manuell sperren
sudo fail2ban-client set sshd banip 203.0.113.42
5.4 Progressive Banzeiten
Für Systeme mit hohem Angriffsaufkommen empfiehlt sich eine progressiv ansteigende Banzeit.
fail2ban unterstützt dies ab Version 0.10 mit der Option bantime.increment.
Wiederholte Angreifer werden damit exponentiell länger gesperrt:
Port Knocking ist eine Technik, bei der der SSH-Port standardmäßig durch die Firewall
gesperrt ist und erst nach einer bestimmten Sequenz von Verbindungsversuchen auf definierten
Ports geöffnet wird. Ohne die korrekte Klopfsequenz ist der SSH-Port für außen vollständig
unsichtbar – auch ein Portscan zeigt keinen offenen Port.
Der Client öffnet den Port mit knock server 7000 8000 9000
und schließt ihn nach der Sitzung wieder mit der umgekehrten Sequenz.
Port Knocking bietet keinen absoluten Schutz – die Sequenz kann bei
unverschlüsseltem Netzwerktraffic mitgeschnitten werden –, erschwert
jedoch automatisiertes Scanning erheblich.
6.2 SSH-Zertifikate für skalierbare Umgebungen
In größeren Umgebungen mit vielen Servern und Benutzern wird das Verwalten von
authorized_keys-Dateien schnell unübersichtlich. Jeder neue Server
benötigt die Schlüssel aller Benutzer, und beim Entfernen eines Benutzers müssen
alle Server einzeln aktualisiert werden.
SSH-Zertifikate schaffen Abhilfe: Eine zentrale Certificate Authority (CA) signiert
Benutzerschlüssel, und Server vertrauen pauschal allen Schlüsseln, die von dieser CA
signiert wurden. Das ermöglicht zentrales Benutzer-Management ohne manuelle Key-Distribution.
Zusätzlich können Zertifikate mit einer Gültigkeitsdauer versehen werden.
# CA-Schlüsselpaar generieren (einmalig, sicher aufbewahren)
ssh-keygen -t ed25519 -f /etc/ssh/ssh_ca -C "SSH CA"
# Benutzerschlüssel signieren (gültig für 1 Tag, Principals: erlaubte Benutzernamen)
ssh-keygen -s /etc/ssh/ssh_ca -I "alice@company" -n alice -V +1d ~/.ssh/id_ed25519.pub
# In sshd_config auf jedem Server: CA als vertrauenswürdig markieren
TrustedUserCAKeys /etc/ssh/ssh_ca.pub
6.3 SSH-Jumphosts und Bastion Hosts
In sicherheitskritischen Infrastrukturen sind interne Server nicht direkt aus dem Internet
erreichbar. Stattdessen läuft der SSH-Zugang ausschließlich über einen dedizierten
Bastion Host (auch Jumphost genannt), der stark gehärtet, protokolliert
und überwacht ist. Alle anderen Server sind nur innerhalb des internen Netzwerks per SSH
erreichbar, was die Angriffsfläche drastisch reduziert.
# SSH-Verbindung über einen Jumphost in ~/.ssh/config konfigurieren
Host interner-server
HostName 10.0.1.50
User alice
ProxyJump bastion.beispiel.de
# Oder direkt auf der Kommandozeile ohne Konfigurationsdatei
ssh -J alice@bastion.beispiel.de alice@10.0.1.50
Der Bastion Host selbst sollte besonders restriktiv konfiguriert sein: kein Passwort-Login,
kein Root-Login, fail2ban aktiv, alle nicht benötigten Dienste deaktiviert, und
regelmäßige Überprüfung der Zugangslisten.
7. Monitoring und Log-Auswertung
Eine gehärtete SSH-Konfiguration sollte kontinuierlich überwacht werden. Log-Dateien
liefern wertvolle Informationen über Angriffsversuche, ungewöhnliche Aktivitäten und
erfolgreiche Anmeldungen. Anomalien fallen nur auf, wenn man aktiv hinschaut.
7.1 Wichtige Log-Quellen
# Klassische Syslog-Datei (Debian/Ubuntu)
/var/log/auth.log
# systemd Journal – Echtzeit-Monitoring des SSH-Daemons
sudo journalctl -u sshd -f
# Nur Fehler und Warnungen anzeigen
sudo journalctl -u sshd -p warning
# Letzte fehlgeschlagene Anmeldeversuche (alle Protokolle)
sudo lastb | head -30
# Aktuelle Anmeldungen und letzte erfolgreiche Logins
who
last | head -20
7.2 Brute-Force-Muster erkennen
Typische Brute-Force-Angriffe erzeugen in kurzer Zeit viele Einträge wie
Failed password for invalid user root from 203.0.113.42 oder
Invalid user admin from 198.51.100.7.
Die häufigsten angreifenden IP-Adressen lassen sich mit einfachen Shell-Befehlen
schnell identifizieren:
# Top 10 angreifende IPs aus auth.log
grep "Failed password" /var/log/auth.log | awk '{print $(NF-3)}' | sort | uniq -c | sort -rn | head -10
# Anzahl fehlgeschlagener Versuche insgesamt am heutigen Tag
grep "Failed password" /var/log/auth.log | grep "$(date '+%b %e')" | wc -l
# Alle verwendeten Benutzernamen bei Angriffen – zeigt gängige Ziele
grep "Invalid user" /var/log/auth.log | awk '{print $8}' | sort | uniq -c | sort -rn | head -20
7.3 Automatisiertes Monitoring mit logwatch
Für professionelle Umgebungen empfiehlt sich der Einsatz von zentralen Log-Management-Lösungen
wie dem ELK-Stack (Elasticsearch, Logstash, Kibana), Graylog oder Loki mit Grafana. Diese
ermöglichen Dashboards, Alerting bei ungewöhnlichen Anmeldemustern und langfristige Auswertungen
über mehrere Server hinweg.
Einfacher und für kleinere Setups ausreichend ist logwatch, das täglich
eine Zusammenfassung der Log-Aktivitäten per E-Mail verschickt:
sudo apt install logwatch
Anpassungen in /etc/logwatch/conf/logwatch.conf:
MailTo = admin@beispiel.de
Detail = Med
Range = yesterday
7.4 Sicherheits-Checkliste SSH-Härtung
Als abschließende Zusammenfassung die wichtigsten Punkte auf einen Blick: