SSH-Hardening 2026 auf Debian 13 — Moderne Best Practices

SSH-Server auf Debian 13 nach modernen Best Practices absichern: Key-only-Login, Cipher-Suite-Hardening, Port-Wechsel, fail2ban-Integration und Audit-Logging. Kein Brute-Force-Angriff hat eine Chance.

SSH-Server auf Debian 13 nach modernen Best Practices absichern: Key-only-Login, Cipher-Suite-Hardening, Port-Wechsel, fail2ban-Integration und Audit-Logging. Kein Brute-Force-Angriff hat eine Chance.

💡 Hinweis: Dieses Tutorial setzt voraus, dass du einen normalen Benutzer mit sudo-Rechten verwendest — wie im Tutorial Debian 13 Server absichern beschrieben. Wir gehen jetzt deutlich tiefer als der Basis-Härtungsguide.

Einleitung — Warum SSH 2026 anders absichern?

SSH ist seit 1995 das Standard-Tool für Remote-Server-Verwaltung. Das heißt aber auch: Es ist seit 30 Jahren das primäre Angriffsziel auf Server. Innerhalb weniger Minuten nach dem Start eines neuen Servers landen die ersten Brute-Force-Versuche. Bots scannen kontinuierlich auf offene SSH-Ports und probieren Standard-Credentials.

Ein Server mit root:password und Port 22 wird nicht vielleicht kompromittiert — er wird kompromittiert, wenn er lange genug online ist. Der einzige Schutz: SSH systematisch härten.

Dieser Guide geht deutlich über das hinaus, was die meisten „10 SSH Tipps“-Artikel zeigen. Wir nehmen den 2026er Stand der Technik:

  • Modernste Cipher-Suites (Quantum-resistent vorbereiten)
  • Match-Blöcke für rollenbasierte Zugriffe
  • Audit-Logging mit auditd
  • Crowdsec / fail2ban Integration
  • Centralized SSH mit OIDC (Stretch-Goal)

Was wir konkret absichern

  • Key-only Login — keine Passwörter
  • Modernste Algorithmen — kein RSA-1024, kein DH-Group1
  • Port-Wechsel — reduziert Bot-Traffic massiv
  • Rate-Limiting auf SSH-Port
  • Audit-Trail für jede Session
  • Multi-Faktor-Auth mit Hardware-Token (optional)

Voraussetzungen

  • Debian 13 Server mit funktionierendem SSH-Zugang
  • Lokaler SSH-Client (Linux, macOS oder Windows mit WSL/PuTTY)
  • Root oder sudo-Rechte
  • Sicherer Backup-Zugang — z.B. Console-Access beim Hoster, falls SSH versehentlich kaputtkonfiguriert wird

⚠️ Wichtig: Behaltet immer eine zweite SSH-Session offen, während ihr Hardening-Schritte umsetzt. Wenn ein Tippfehler euch aussperrt, könnt ihr in der zweiten Session schnell zurückrollen — sonst wird’s haarig.


Schritt 1: SSH-Key-Pair generieren (modern)

Auf eurem lokalen Rechner — nicht auf dem Server!

ssh-keygen -t ed25519 -a 100 -C "marius@laptop-2026"

Was die Parameter bedeuten:

  • -t ed25519 — Modernste, sicherste Key-Art (besser als RSA-4096)
  • -a 100 — 100 Hashing-Runden gegen Brute-Force der Passphrase
  • -C — Kommentar, hilft bei Identifikation

Speicherort: Default ~/.ssh/id_ed25519 ist okay. Setzt eine starke Passphrase — der Schlüssel ohne Passphrase ist ein Sicherheitsrisiko bei verlorenem Laptop.

Public Key auf den Server kopieren

ssh-copy-id -i ~/.ssh/id_ed25519.pub user@euer-server

Anschließend testen, ob Login mit Key funktioniert:

ssh user@euer-server

Wenn das ohne Passwort-Prompt durchläuft (nur Passphrase fürs Key wird gefragt), seid ihr bereit für die nächsten Schritte.

⚠️ Wichtig: Erst wenn Key-Login zuverlässig funktioniert, das Passwort-Login deaktivieren. Reihenfolge ist entscheidend — sonst sperrt ihr euch aus.


Schritt 2: sshd_config — die zentrale Datei

sudo cp /etc/ssh/sshd_config /etc/ssh/sshd_config.bak
sudo nano /etc/ssh/sshd_config

Wir gehen die wichtigen Einstellungen durch — alle anderen Defaults aus Debian 13 sind okay.

Hauptkonfiguration

# Standard-Port wechseln (siehe Schritt 3)
Port 2222

# Nur IPv4 oder IPv6 explizit binden
AddressFamily any

# OpenSSH-Version nicht in Banner zeigen
DebianBanner no

# Maximaler Authentifizierungs-Versuche pro Verbindung
MaxAuthTries 3

# Session-Timeouts
LoginGraceTime 30
ClientAliveInterval 300
ClientAliveCountMax 2

# Maximum gleichzeitige Login-Sessions
MaxSessions 5
MaxStartups 10:30:60

# Keine root-Logins, niemals
PermitRootLogin no

# Passwort-Login komplett aus
PasswordAuthentication no
ChallengeResponseAuthentication no
KbdInteractiveAuthentication no

# PAM-Auth nur für Account-Management, nicht für Auth
UsePAM yes

# Nur Public-Key-Auth
PubkeyAuthentication yes
AuthorizedKeysFile .ssh/authorized_keys

# X11-Forwarding nur, wenn ihr es wirklich braucht
X11Forwarding no

# Forwarding generell einschränken (außer für Tunnel-Use-Cases)
AllowAgentForwarding no
AllowTcpForwarding no
GatewayPorts no
PermitTunnel no

# Subsystem für SFTP
Subsystem sftp /usr/lib/openssh/sftp-server -f AUTHPRIV -l INFO

# Logging detaillierter
LogLevel VERBOSE

# AuthorizedKeys-Modi
StrictModes yes

# Keine User-Environment-Variablen
PermitUserEnvironment no

Schritt 3: Modernste Algorithmen erzwingen

Hier wird’s spezifisch. Standardmäßig erlaubt OpenSSH eine breite Palette — auch ältere Algorithmen für Kompatibilität. Wir reduzieren auf das, was 2026 sicher ist.

Am Ende der sshd_config ergänzen:

# Modern Crypto Only — Stand 2026
KexAlgorithms sntrup761x25519-sha512@openssh.com,curve25519-sha256,curve25519-sha256@libssh.org,diffie-hellman-group18-sha512,diffie-hellman-group16-sha512

Ciphers chacha20-poly1305@openssh.com,aes256-gcm@openssh.com,aes128-gcm@openssh.com,aes256-ctr,aes192-ctr,aes128-ctr

MACs hmac-sha2-512-etm@openssh.com,hmac-sha2-256-etm@openssh.com,umac-128-etm@openssh.com

HostKeyAlgorithms ssh-ed25519,ssh-ed25519-cert-v01@openssh.com,rsa-sha2-512,rsa-sha2-256

PubkeyAcceptedAlgorithms ssh-ed25519,ssh-ed25519-cert-v01@openssh.com,rsa-sha2-512,rsa-sha2-256

💡 Hinweis: sntrup761x25519-sha512@openssh.com ist ein Quantum-Computer-resistenter Key-Exchange. OpenSSH 9.0+ unterstützt das — es ist die Vorbereitung auf „Q-Day“ (wenn Quantencomputer aktuelle Krypto knacken können). Bei modernen Clients ist es Default.

Host-Keys auf moderne Algorithmen reduzieren

# Alte Host-Keys (RSA und ECDSA) löschen
sudo rm /etc/ssh/ssh_host_rsa_key /etc/ssh/ssh_host_rsa_key.pub
sudo rm /etc/ssh/ssh_host_ecdsa_key /etc/ssh/ssh_host_ecdsa_key.pub

# Nur Ed25519 behalten (war schon da)
ls -l /etc/ssh/ssh_host_*

In sshd_config darauf hinweisen:

HostKey /etc/ssh/ssh_host_ed25519_key

⚠️ Wichtig: Nach dem Löschen der alten Host-Keys werden eure Clients beim nächsten Connect ein neues Host-Key-Fingerprint melden. Das ist normal — bestätigen, fertig. Falls ihr ein Konfigurations-Management (Ansible) nutzt, dort auch updaten.


Schritt 4: Port von 22 wechseln

Port 2222 haben wir schon gesetzt. Vor dem Restart Firewall anpassen:

sudo ufw allow 2222/tcp comment 'SSH (custom port)'
sudo ufw status

Erst dann den alten Port schließen — und das nicht jetzt, sondern erst nach erfolgreichem Test:

# Noch NICHT ausführen!
# sudo ufw delete allow 22/tcp

💡 Hinweis: Port-Wechsel ist Security through Obscurity — also keine echte Sicherheit, aber er reduziert den Bot-Traffic gegen euren Server um >99%. Ein Bot, der Port 22 scannt, sieht eure Maschine nicht. Das spart Logs, Bandbreite und Crowdsec/fail2ban-Last.


Schritt 5: Match-Blöcke für rollenbasierte Zugriffe

Mit Match-Blöcken könnt ihr Konfiguration pro User oder Gruppe variieren.

Am Ende der sshd_config:

# Backup-User darf nur SFTP, kein Shell-Zugriff
Match User backup
    ForceCommand internal-sftp
    ChrootDirectory /var/backups/incoming
    AllowTcpForwarding no
    X11Forwarding no
    PasswordAuthentication no

# Admin-Gruppe — nur von Heimnetz aus
Match Group admin Address 192.168.1.0/24,10.0.0.0/8
    PermitRootLogin no
    PubkeyAuthentication yes

# Deploy-User für CI/CD — nur Key, sehr eingeschränkt
Match User deploy
    AuthenticationMethods publickey
    PermitTTY no
    AllowAgentForwarding no
    PermitOpen none

💡 Tipp: Match-Blöcke sind extrem mächtig — pro User, Gruppe, IP-Range oder Kombination andere Regeln. Damit baut ihr ein vollständiges RBAC ohne externe Tools.


Schritt 6: Konfiguration testen — bevor Restart!

sudo sshd -t

Wenn nichts ausgegeben wird, ist die Config syntaktisch okay. Bei Fehlern: korrigieren, nicht den SSH-Service neustarten, sonst Lockout.

Detaillierter Test:

sudo sshd -T | grep -E '^(port|kexalgorithms|ciphers|macs|passwordauth|pubkeyauth)'

Zeigt euch die effektiv aktiven Werte.


Schritt 7: SSH neu starten — vorsichtig!

Ihr habt eine zweite SSH-Session offen? Ja? Dann weiter.

sudo systemctl restart sshd

Im anderen Terminal (oder neuem) testet ihr den Login auf den neuen Port:

ssh -p 2222 user@euer-server

Wenn das funktioniert, könnt ihr alten Port schließen:

sudo ufw delete allow 22/tcp

Geschafft! Euer SSH ist auf modernem Stand. Aber wir sind noch nicht fertig — Brute-Force-Schutz und Audit kommen jetzt.


Schritt 8: SSH-Brute-Force-Schutz mit Crowdsec

Statt fail2ban empfehlen wir Crowdsec (siehe Crowdsec-Tutorial). Crowdsec hat eine SSH-Collection eingebaut.

sudo cscli collections list | grep ssh

Sollte crowdsecurity/sshd als installed zeigen. Falls nicht:

sudo cscli collections install crowdsecurity/sshd
sudo systemctl restart crowdsec

Test — Failed-Logins simulieren:

# Auf einem zweiten Rechner
for i in {1..6}; do ssh -p 2222 wrong@euer-server; done

Im Server:

sudo cscli alerts list
sudo cscli decisions list

Eure Test-IP sollte gebannt sein.

fail2ban als Alternative

Falls ihr Crowdsec nicht nutzen wollt:

sudo apt install -y fail2ban
sudo nano /etc/fail2ban/jail.local

Inhalt:

[sshd]
enabled = true
port = 2222
filter = sshd
logpath = /var/log/auth.log
maxretry = 3
bantime = 3600
findtime = 600
ignoreip = 127.0.0.1 192.168.1.0/24
sudo systemctl restart fail2ban
sudo fail2ban-client status sshd

Schritt 9: Audit-Logging

Standard-SSH-Logs (/var/log/auth.log) sind okay, aber für forensische Untersuchung zu wenig. Wir aktivieren auditd für komplette Kommando-Aufzeichnung.

sudo apt install -y auditd
sudo systemctl enable --now auditd

Audit-Regeln für SSH

sudo nano /etc/audit/rules.d/ssh-audit.rules

Inhalt:

# SSH-Konfigurationsänderungen
-w /etc/ssh/sshd_config -p wa -k sshd_config
-w /etc/ssh/sshd_config.d/ -p wa -k sshd_config

# Alle SSH-Verbindungen
-w /var/log/auth.log -p wa -k auth_log

# Authorized Keys
-w /root/.ssh/ -p wa -k root_ssh
-w /home/ -p wa -k home_ssh

# sudo-Kommandos
-w /var/log/sudo.log -p wa -k sudo_log
-a always,exit -F arch=b64 -S execve -F euid=0 -k root_commands
sudo systemctl restart auditd
sudo auditctl -l

Audit-Logs auswerten

# Alle SSH-Konfigurationsänderungen
sudo ausearch -k sshd_config

# Alle Root-Kommandos heute
sudo ausearch -k root_commands -ts today

# Login-Versuche
sudo aureport --auth

⚠️ Best Practice: Audit-Logs müssen regelmäßig ausgewertet werden, sonst sind sie wertlos. Richtet einen automatischen Bericht per E-Mail oder Discord ein — z.B. einmal pro Woche zusammengefasste Login-Aktivität.


Schritt 10: Multi-Faktor-Auth mit Hardware-Token (optional)

Für maximale Sicherheit: SSH plus YubiKey/Hardware-Token.

sudo apt install -y libpam-u2f

YubiKey registrieren (auf eurem Laptop):

mkdir -p ~/.config/Yubico
pamu2fcfg > ~/.config/Yubico/u2f_keys
scp ~/.config/Yubico/u2f_keys user@euer-server:~/.config/Yubico/

Auf dem Server in /etc/pam.d/sshd, vor @include common-auth:

auth required pam_u2f.so

In sshd_config:

ChallengeResponseAuthentication yes
AuthenticationMethods publickey,keyboard-interactive
sudo systemctl restart sshd

Beim nächsten SSH-Login werdet ihr nach einem YubiKey-Touch gefragt.

💡 Tipp: YubiKey + SSH-Key ist Hochsicherheits-Setup. Aber: Habt immer einen Backup-YubiKey — sonst bei Verlust totale Aussperrung.


Zusammenfassung & Checkliste

SchrittStatus
Modernen ed25519-Key generiert
Public Key auf Server kopiert
Key-Login getestet (vor Hardening!)
sshd_config.bak als Backup erstellt
PermitRootLogin no
PasswordAuthentication no
Port von 22 gewechselt
Moderne Algorithmen erzwungen
Alte Host-Keys (RSA, ECDSA) gelöscht
Match-Blöcke für Rollen (optional)
sshd -t ohne Fehler
Zweite SSH-Session zur Sicherheit offen
Restart durchgeführt, neuer Port funktioniert
Alter Port in Firewall geschlossen
Crowdsec oder fail2ban aktiv
auditd mit SSH-Regeln läuft
Hardware-Token (optional)

Troubleshooting

Lockout — kein Login mehr möglich

  • Hoster bietet Console-Access? (Hetzner Robot, OVH KVM, AWS Session Manager)
  • Damit sshd_config.bak zurückspielen: sudo cp /etc/ssh/sshd_config.bak /etc/ssh/sshd_config && sudo systemctl restart sshd

„Permission denied (publickey)“

  • Public Key auf Server in ~/.ssh/authorized_keys?
  • Permissions korrekt? chmod 700 ~/.ssh && chmod 600 ~/.ssh/authorized_keys
  • SELinux/AppArmor aktiv? sudo journalctl -u sshd -f zeigt Details

Client kann sich nicht verbinden — „no matching algorithm“

  • Eurer SSH-Client ist zu alt für die modernen Algorithmen
  • Update auf OpenSSH 9.x
  • Alternativ: weniger strikte Algorithmen erlauben (Kompromiss)

sshd -T zeigt unerwartete Werte

  • Mehrere sshd_config.d/*.conf Files werden parallel gelesen
  • sudo cat /etc/ssh/sshd_config.d/*.conf zeigt sie
  • Reihenfolge: erstes Match gewinnt

Crowdsec bannt eure eigene IP

sudo cscli decisions delete --ip EURE_IP

Whitelist erweitern — siehe Crowdsec-Tutorial.

Audit-Logs explodieren das Disk

auditd schreibt viel. In /etc/audit/auditd.conf

max_log_file = 50
num_logs = 5
max_log_file_action = ROTATE

Nächste Schritte

  • Centralized SSH mit OIDC — SSH-CA mit Authentik oder Vault
  • 2FA mit TOTP statt YubiKey (App-basiert, kein Hardware-Token)
  • Bastion-Host-Setup — Ein zentraler SSH-Hop für alle Server
  • SSH-CA Signing Keys — Statt authorized_keys zertifizierte Keys
  • Logwatch / Logwatch-Reports — Tägliche SSH-Aktivität per E-Mail

Habt ihr Fragen oder Probleme? Schreibt es in die Kommentare — ich helfe gerne!

Kommentar hinterlassen