SSH Hardening: Linux-Server Schritt für Schritt absichern

SSH-Server nach Best Practices absichern: Passwort-Auth deaktivieren, root-Login verbieten, Port ändern, Fail2ban einrichten, 2FA mit TOTP, SSH-Audit durchführen – mit Checkliste.

8 min Lesezeit

SSH Hardening: Linux-Server Schritt für Schritt absichern

Ein frisch aufgesetzter Server mit SSH auf Port 22 und Standard-Konfiguration ist innerhalb von Minuten das Ziel von automatisierten Brute-Force-Scans. Die gute Nachricht: Mit den richtigen Maßnahmen lässt sich die Angriffsfläche drastisch reduzieren – ohne den Komfort zu verlieren.

Dieser Guide geht systematisch vor: von der Grundkonfiguration bis zu 2FA und automatisiertem Audit.

Wichtig: Behalte während aller Änderungen eine aktive SSH-Session offen und teste in einer zweiten Session. So sperrst du dich nicht aus.


Voraussetzungen und Vorsichtsmaßnahmen

Bevor du beginnst:

# 1. SSH-Schlüssel eingerichtet? (Pflicht vor Passwort-Deaktivierung)
ssh-add -l
ls ~/.ssh/authorized_keys   # auf dem Server

# 2. Aktuelle sshd_config sichern
sudo cp /etc/ssh/sshd_config /etc/ssh/sshd_config.backup

# 3. Root-Zugang sichern (Notfall-Konsole kennen)
# Cloud-Provider: Hetzner, DigitalOcean, AWS → Web-Konsole notieren

# 4. Syntax-Check vor jedem Neustart
sudo sshd -t   # 0 = keine Syntaxfehler

Arbeitsweise: Nie live testen ohne Backup-Session

# Session 1 (bleibt offen):
ssh user@server   # diese Session läuft weiter

# Session 2 (zum Testen nach Änderungen):
ssh user@server   # neue Verbindung zum Testen öffnen

SSH-Schlüssel: Grundlage des Hardenings

Ohne SSH-Schlüssel kannst du Passwort-Auth nicht sicher deaktivieren.

# Auf dem Client: Ed25519-Schlüssel erstellen (falls noch nicht vorhanden)
ssh-keygen -t ed25519 -C "server-name-$(date +%Y)" -f ~/.ssh/id_server

# Auf den Server kopieren
ssh-copy-id -i ~/.ssh/id_server.pub user@server

# Testen: Login mit Schlüssel
ssh -i ~/.ssh/id_server user@server

# Erst jetzt Passwort-Auth deaktivieren!

sshd_config: Die wichtigsten Einstellungen

sudo nano /etc/ssh/sshd_config

Essentielle Einstellungen

# === Authentifizierung ===

# Passwort-Login deaktivieren (NUR wenn Schlüssel funktionieren!)
PasswordAuthentication no

# Leere Passwörter verbieten
PermitEmptyPasswords no

# Root-Login deaktivieren
PermitRootLogin no

# Maximale Auth-Versuche pro Verbindung
MaxAuthTries 3

# Zeit bis Login abgeschlossen sein muss
LoginGraceTime 30s

# Challenge-Response deaktivieren (kein PAM-Passwort-Fallback)
ChallengeResponseAuthentication no
KbdInteractiveAuthentication no   # OpenSSH 8.7+

# PAM-Modul (für 2FA benötigt, sonst kann es auf no)
UsePAM yes   # Für 2FA: yes; ohne 2FA: no

# === Zugriff einschränken ===

# Nur erlaubte Benutzer (Trennzeichen: Leerzeichen)
AllowUsers deploy andre

# Oder: Nur bestimmte Gruppen
# AllowGroups sshusers sudo

# === Verbindungsoptimierung ===

# Keep-Alive: Verbindungen sauber halten
ClientAliveInterval 120
ClientAliveCountMax 2

# Maximale gleichzeitige unauth. Verbindungen begrenzen
MaxStartups 10:30:60
# Format: start:rate:full
# start: ab welcher Anzahl zu droppen beginnen
# rate: Wahrscheinlichkeit in Prozent
# full: ab wann alle neuen blockieren

# === Features deaktivieren ===

# X11-Forwarding (GUI-Anwendungen über SSH)
X11Forwarding no   # nur aktivieren wenn benötigt

# TCP-Forwarding (Port-Tunneling)
AllowTcpForwarding no   # nur aktivieren wenn benötigt

# Agent-Forwarding
AllowAgentForwarding no

# SFTP statt SCP (sicherer)
# Subsystem sftp /usr/lib/openssh/sftp-server  # bleibt aktiv

# === Protokoll und Verschlüsselung ===

# Nur SSH Protokoll 2 (ist Standard, zur Sicherheit explizit)
Protocol 2

# Moderne Algorithmen (OpenSSH >=8.2 verwendet diese standardmäßig)
# Diese Zeilen sind optional wenn du aktuelles OpenSSH nutzt:
# KexAlgorithms curve25519-sha256,curve25519-sha256@libssh.org
# Ciphers chacha20-poly1305@openssh.com,aes256-gcm@openssh.com,aes128-gcm@openssh.com
# MACs hmac-sha2-512-etm@openssh.com,hmac-sha2-256-etm@openssh.com

Änderungen übernehmen

# Syntax-Check IMMER vor Reload!
sudo sshd -t
# (keine Ausgabe = alles ok)

# Reload (laufende Verbindungen bleiben)
sudo systemctl reload sshd

# In zweiter Session verbinden und testen!

Fail2ban: Brute-Force-Schutz

Fail2ban überwacht Logs und sperrt IPs nach zu vielen Fehlversuchen automatisch.

# Installieren
sudo apt install fail2ban          # Ubuntu/Debian
sudo dnf install fail2ban          # Fedora

# Konfiguration: IMMER .local-Dateien anlegen (nicht .conf bearbeiten!)
sudo cp /etc/fail2ban/jail.conf /etc/fail2ban/jail.local
sudo nano /etc/fail2ban/jail.local

Grundkonfiguration

[DEFAULT]
# Eigene IP nicht sperren (kommagetrennte Liste, CIDR erlaubt)
ignoreip = 127.0.0.1/8 ::1 192.168.1.0/24

# Zeitfenster für Fehlversuche (10 Minuten)
findtime = 600

# Maximale Fehlversuche in findtime
maxretry = 5

# Sperrzeit (1 Stunde)
# -1 = dauerhaft
bantime = 3600

# Progressiver Anstieg: jeder weitere Ban verdoppelt die Zeit
bantime.increment = true
bantime.factor = 24      # 24h nach mehrfachem Ban
bantime.maxtime = 604800 # max. 7 Tage

# Gesperrte IPs per UFW oder iptables
banaction = ufw
# Alternative: iptables-multiport

[sshd]
enabled = true
port    = 22        # anpassen wenn anderer Port!
filter  = sshd
logpath = /var/log/auth.log   # Ubuntu/Debian
# Fedora: logpath = /var/log/secure

maxretry = 3        # SSH: strengerer Wert
# Starten und aktivieren
sudo systemctl enable --now fail2ban

# Status prüfen
sudo systemctl status fail2ban

# Gesperrte IPs anzeigen
sudo fail2ban-client status sshd
# Status for the jail: sshd
# |- Filter
# |  |- Currently failed: 2
# |  |- Total failed: 47
# `- Actions
#    |- Currently banned: 1
#    |- Total banned: 5
#    `- Banned IP list: 203.0.113.99

# IP manuell sperren
sudo fail2ban-client set sshd banip 203.0.113.99

# IP entsperren
sudo fail2ban-client set sshd unbanip 203.0.113.99

# Jail-Status aller aktiven Jails
sudo fail2ban-client status

Fail2ban-Logs

sudo journalctl -u fail2ban -f
sudo tail -f /var/log/fail2ban.log

Port-Änderung: Weniger Scan-Lärm

Das Ändern des SSH-Ports ist kein echter Sicherheitsgewinn gegen gezielte Angriffe, aber es reduziert automatisierte Port-22-Scans drastisch.

# In /etc/ssh/sshd_config:
Port 2222
# oder einen anderen Port > 1024

# ZUERST: Firewall-Regel für neuen Port setzen!
sudo ufw allow 2222/tcp    # Ubuntu/Debian
sudo firewall-cmd --permanent --add-port=2222/tcp   # Fedora
sudo firewall-cmd --reload

# DANN: sshd neu starten
sudo sshd -t && sudo systemctl restart sshd

# In zweiter Session mit neuem Port testen
ssh -p 2222 user@server

# ERST DANN: Port 22 in der Firewall schließen
sudo ufw delete allow OpenSSH
sudo ufw delete allow 22/tcp
# Fedora:
sudo firewall-cmd --permanent --remove-service=ssh
sudo firewall-cmd --reload

# SELinux: neuen Port erlauben (Fedora/RHEL)
sudo semanage port -a -t ssh_port_t -p tcp 2222

~/.ssh/config anpassen

Host mein-server
    HostName server-ip
    User deploy
    Port 2222
    IdentityFile ~/.ssh/id_server

AllowUsers/AllowGroups: Zugang einschränken

# In /etc/ssh/sshd_config:

# Nur bestimmte Benutzer (sicherste Methode)
AllowUsers deploy andre backup-bot

# Nur Mitglieder der Gruppe "sshusers"
AllowGroups sshusers

# Kombination: Benutzer aus bestimmter IP
AllowUsers deploy@192.168.1.0/24   # deploy nur aus internem Netz
AllowUsers andre                    # andre von überall

# Service-Accounts von SSH ausschließen
DenyUsers www-data mysql redis postgres
# Gruppe erstellen und User hinzufügen
sudo groupadd sshusers
sudo usermod -aG sshusers deploy
sudo usermod -aG sshusers andre

# Prüfen
getent group sshusers

2FA mit TOTP (optional, empfohlen)

Zwei-Faktor-Authentifizierung mit TOTP (Time-based One-Time Password) – kompatibel mit Google Authenticator, Authy, Bitwarden.

# Google Authenticator PAM installieren
sudo apt install libpam-google-authenticator   # Ubuntu/Debian
sudo dnf install google-authenticator          # Fedora

# Als der Benutzer (nicht root!) konfigurieren
google-authenticator
Do you want authentication tokens to be time-based? y

# QR-Code erscheint → mit Authenticator-App scannen
# Backup-Codes notieren!

Do you want me to update your "~/.google_authenticator" file? y
Do you want to disallow multiple uses of the same authentication
token? y
By default, a new token is generated every 30 seconds... do you want to
extend the window? n
Do you want to enable rate-limiting? y

PAM konfigurieren

sudo nano /etc/pam.d/sshd

Am Anfang der Datei (vor @include common-auth):

# 2FA: TOTP-Code erforderlich
auth required pam_google_authenticator.so

sshd_config für 2FA anpassen

sudo nano /etc/ssh/sshd_config
# Schlüssel + TOTP (empfohlen)
AuthenticationMethods publickey,keyboard-interactive

# Keyboard-Interactive aktivieren (für TOTP-Abfrage)
KbdInteractiveAuthentication yes

UsePAM yes
sudo sshd -t && sudo systemctl restart sshd

# Testen: Login sollte Schlüssel + TOTP-Code verlangen
ssh -o PreferredAuthentications=publickey,keyboard-interactive user@server

Backup-Plan: Wenn du 2FA vergisst oder die App verlierst → Cloud-Konsole nutzen und ~/.google_authenticator löschen.


Firewall-Integration

# UFW (Ubuntu/Debian)

# SSH erlauben (wenn Port 22)
sudo ufw allow OpenSSH

# SSH auf eigenem Port
sudo ufw allow 2222/tcp

# SSH nur aus bestimmtem Netz (sicherste Option für Server)
sudo ufw allow from 192.168.1.0/24 to any port 22 proto tcp

# Rate-Limiting gegen Brute-Force (zusätzlich zu Fail2ban)
sudo ufw limit 22/tcp

# firewalld (Fedora)
sudo firewall-cmd --permanent --add-service=ssh
sudo firewall-cmd --permanent --add-rich-rule='rule family="ipv4" source address="192.168.1.0/24" service name="ssh" accept'
sudo firewall-cmd --reload

SSH-Audit durchführen

ssh-audit (Tool)

# Installieren
sudo apt install ssh-audit   # Ubuntu 22.04+
# oder:
pip3 install ssh-audit

# Server auditieren
ssh-audit localhost
ssh-audit server-ip

# Ausgabe:
# (gen) banner: SSH-2.0-OpenSSH_9.8p1 Ubuntu-3ubuntu0.7
# (kex) curve25519-sha256                          -- [info] available since OpenSSH 7.4, Dropbear SSH 2018.76
# (kex) ...
# [WARNING] ...
# [CRITICAL] ...

Manueller Konfigurations-Check

# OpenSSH-Version prüfen (sollte aktuell sein)
sshd -V
ssh -V

# Aktive Konfiguration anzeigen
sudo sshd -T | grep -E "permitrootlogin|passwordauthentication|pubkeyauthentication|maxauthtries|logingracetime|allowusers|x11forwarding"

# Alle lauschenden Ports
sudo ss -tlnp | grep sshd

# Aktive SSH-Verbindungen
sudo ss -tnp | grep :22
who   # eingeloggte User
w     # eingeloggte User + Aktivität
last  # Login-History

Regelmäßige Überprüfung

# Fehlgeschlagene Login-Versuche (letzte 24h)
sudo journalctl _COMM=sshd --since "24 hours ago" | grep "Failed\|Invalid" | \
  awk '{print $(NF-3)}' | sort | uniq -c | sort -rn | head -10

# Erfolgreiche Logins
sudo journalctl _COMM=sshd --since "7 days ago" | grep "Accepted"

# Login-Zeiten pro User
last | grep -v "wtmp\|reboot" | head -20

Hardening-Checkliste

SSH Hardening Checkliste – Stand: 2026-02-18
============================================

Basis-Sicherheit:
[ ] SSH-Schlüssel (Ed25519) eingerichtet und getestet
[ ] PasswordAuthentication no
[ ] PermitRootLogin no
[ ] PermitEmptyPasswords no
[ ] MaxAuthTries 3
[ ] LoginGraceTime 30s

Zugriffskontrolle:
[ ] AllowUsers oder AllowGroups gesetzt
[ ] X11Forwarding no (wenn nicht benötigt)
[ ] AllowTcpForwarding no (wenn nicht benötigt)

Brute-Force-Schutz:
[ ] Fail2ban installiert und aktiv
[ ] maxretry ≤ 5
[ ] bantime ≥ 3600
[ ] bantime.increment aktiviert
[ ] Eigene IP in ignoreip

Optional (empfohlen):
[ ] Port geändert (nicht 22)
[ ] 2FA (TOTP) aktiviert
[ ] ssh-audit durchgeführt
[ ] Firewall: SSH nur aus bekannten IPs (wenn möglich)

Monitoring:
[ ] Fail2ban-Logs aktiv
[ ] journalctl -u sshd regelmäßig prüfen
[ ] last und w regelmäßig prüfen

Fazit

SSH-Hardening ist keine einmalige Aufgabe, sondern ein kontinuierlicher Prozess. Die drei wichtigsten Maßnahmen mit dem größten Sicherheitsgewinn:

  1. Passwort-Auth deaktivieren → eliminiert Passwort-Brute-Force
  2. Fail2ban → stoppt automatisierte Scan-Angriffe
  3. AllowUsers → begrenzt potenzielle Angriffspunkte

Für sensible Server: 2FA als zusätzliche Schicht – selbst bei kompromittiertem Schlüssel ist der Angriff gescheitert.

War dieser Artikel hilfreich?