
Linux Firewall mit nftables 2026 – Modernes Setup
Linux Firewall mit nftables 2026: Modernes Setup mit Sets, Maps, NAT und Docker-Integration – inkl. Migration von iptables, Performance-Werten und Praxis-Befehl
SSH ist der Standard-Fernzugang für praktisch jeden Linux-Server – und genau deshalb das Lieblingziel automatisierter Angriffe. Shodan listet dauerhaft über 20 Millionen erreichbare SSH-Endpunkte im öffentlichen IPv4-Raum. Ein frisch aufgesetzter VPS mit Port 22 offen und Passwort-Login aktiviert erhält im Schnitt innerhalb von 8 bis 15 Minuten die ersten Login-Versuche. Nach 24 Stunden sind 30.000 bis 120.000 fehlgeschlagene Authentifizierungen keine Seltenheit.
Die Angreifer arbeiten nicht mehr mit simplen Wörterbuch-Attacken aus einem einzigen Rechenzentrum. Moderne Botnets wie Mirai-Ableger oder die „SSH-Spray"-Kampagnen verteilen Versuche über zehntausende kompromittierte Router und IoT-Geräte. Jede IP probiert nur zwei bis fünf Credentials, bevor sie rotiert. Klassische IP-Blocklisten greifen hier kaum noch.
Parallel dazu hat sich die Bedrohungslage verschoben: Nicht der Brute-Force-Angriff auf schwache Passwörter ist 2026 das größte Risiko, sondern geleakte Private Keys. Wer seinen ~/.ssh/id_rsa unverschlüsselt auf dem Laptop, im Backup oder im Git-Repo liegen hat, verliert den Server in Sekunden – ohne dass Fail2ban je anschlägt. Genau deshalb kombiniert dieser Guide drei Ebenen: kryptografische Härtung, zweiter Faktor und Netzwerk-Obfuskation.
Der Aufwand hält sich in Grenzen. Ein vollständig gehärteter SSH-Zugang mit Keys, 2FA und Port-Knocking ist in rund 30 Minuten eingerichtet und kostet – abgesehen von optionaler Hardware – keinen Cent.
Bevor du Konfigurationen änderst, lohnt der Blick auf das reale Bedrohungsmodell. Es gibt fünf relevante Angriffsvektoren gegen SSH:
ForwardAgent yes kann ein kompromittierter Zwischenhost deinen SSH-Agent nutzen, um sich weiterzumelden.PermitRootLogin yes oder ein nachträglich installierter Dienst öffnet die Tür wieder.Die Gegenmaßnahmen sind entsprechend geschichtet. Passwort-Auth abschalten eliminiert Vektor 1 und 2 vollständig. Key-Passphrasen plus Hardware-Token eliminieren Vektor 3. ForwardAgent no und ProxyJump statt Agent-Forwarding eliminieren Vektor 4. Und Vektor 5 fängst du mit Konfigurationsmanagement und regelmäßigen Audits ab.
Eine wichtige Zahl zur Einordnung: Ein RSA-2048-Key gilt 2026 weiterhin als sicher, aber Ed25519 ist schneller, kürzer und resistenter gegen Seitenkanalangriffe. Wenn dein Server OpenSSH 6.5 oder neuer läuft – also praktisch jeder seit 2014 – nutze Ed25519.
Erzeuge den Key immer auf dem Client, niemals auf dem Server. Für Ed25519 mit starker KDF-Runde:
ssh-keygen -t ed25519 -a 100 -C "max@workstation-2026" -f ~/.ssh/id_ed25519_hostazar
Das -a 100 erhöht die Anzahl der Key-Derivation-Runden beim Passphrase-Check von 16 auf 100. Der Login dauert dadurch etwa 0,3 Sekunden länger – ein vernachlässigbarer Preis für massiv besseren Schutz gegen Offline-Brute-Force auf die Passphrase.
Falls du aus Kompatibilitätsgründen RSA brauchst (alte Appliances, Netzwerk-Hardware), dann mindestens 4096 Bit im neuen OpenSSH-Format:
ssh-keygen -t rsa -b 4096 -o -a 100 -C "max@workstation-2026"
Kopiere den Public Key auf den Server – bei mehreren Servern am besten über eine Schleife:
for h in web01 db01 game01; do ssh-copy-id -i ~/.ssh/id_ed25519_hostazar.pub root@$h; done
Prüfe anschließend die Rechte auf dem Server. OpenSSH verweigert den Login bei falschen Permissions kommentarlos:
chmod 700 ~/.ssh
chmod 600 ~/.ssh/authorized_keys
chown -R $USER:$USER ~/.ssh
Erstelle dir außerdem eine ~/.ssh/config auf dem Client, damit du nie wieder lange Flags tippst:
Host hostazar-web
HostName 203.0.113.42
User max
IdentityFile ~/.ssh/id_ed25519_hostazar
IdentitiesOnly yes
ForwardAgent no
ServerAliveInterval 30
Jetzt kommt der zentrale Teil. Öffne /etc/ssh/sshd_config und setze folgende Werte. Wichtig: Prüfe die Konfiguration immer mit sshd -t, bevor du den Dienst neustartest – ein Tippfehler kann dich aussperren.
| Direktive | Empfohlener Wert | Wirkung |
|---|---|---|
| PermitRootLogin | prohibit-password | Root nur per Key, nie per Passwort |
| PasswordAuthentication | no | Deaktiviert Passwort-Login komplett |
| KbdInteractiveAuthentication | no | Verhindert PAM-Passwort-Fallback |
| PubkeyAuthentication | yes | Key-Login aktiv |
| PermitEmptyPasswords | no | Blockt leere Passwörter |
| MaxAuthTries | 3 | Nach 3 Fehlversuchen Verbindungsabbruch |
| LoginGraceTime | 20 | 20 Sekunden zum Authentifizieren |
| ClientAliveInterval | 300 | Keepalive alle 5 Minuten |
| ClientAliveCountMax | 2 | Nach 10 Min Inaktivität trennen |
| X11Forwarding | no | Kein X11-Tunnel nötig |
| AllowAgentForwarding | no | Verhindert Agent-Missbrauch |
| AllowTcpForwarding | no | Nur wenn du keine Tunnel brauchst |
| AllowUsers | max deploy | Whitelist erlaubter Accounts |
| LogLevel | VERBOSE | Fingerprints im Log für Audit |
Ergänze die Krypto-Härtung, um veraltete Algorithmen auszuschließen:
KexAlgorithms curve25519-sha256,[email protected]
Ciphers [email protected],[email protected]
MACs [email protected],[email protected]
HostKeyAlgorithms ssh-ed25519,rsa-sha2-512
Teste und lade neu:
sshd -t && systemctl reload sshd
Wichtig: Öffne vor dem Reload eine zweite SSH-Session und lasse sie offen. Falls etwas schiefgeht, kannst du die Konfiguration über diese Session zurückrollen. Erst wenn der Login in einer dritten Session klappt, schließe die Rettungssession.
PasswordAuthentication ist jetzt aus – aber ein gestohlener Key reicht weiterhin. Der zweite Faktor schließt diese Lücke. Die einfachste Variante ist TOTP über eine Authenticator-App.
Installiere das PAM-Modul:
apt install libpam-google-authenticator # Debian/Ubuntu
dnf install google-authenticator # RHEL/Fedora
Führe es als der User aus, der sich einloggen soll:
google-authenticator -t -d -f -r 3 -R 30 -w 3
Die Flags bedeuten: -t TOTP statt HOTP, -d verhindert Wiederverwendung eines Codes, -f schreibt in ~/.google_authenticator, -r 3 -R 30 erlaubt 3 Logins pro 30 Sekunden, -w 3 akzeptiert Codes im Fenster von ±1 Intervall. Scanne den QR-Code mit Aegis, Bitwarden oder 1Password.
Aktiviere das Modul in PAM. In /etc/pam.d/sshd muss die Zeile stehen – und zwar vor den include-Zeilen:
auth required pam_google_authenticator.so nullok
Das nullok erlaubt Usern ohne eingerichtetes Secret den Login – entferne es, sobald alle Accounts konfiguriert sind. In /etc/ssh/sshd_config muss zusätzlich stehen:
KbdInteractiveAuthentication yes
AuthenticationMethods publickey,keyboard-interactive
Diese Zeile erzwingt Key UND TOTP – nicht „oder". Damit ist ein gestohlener Key allein wertlos. Nach sshd -t und systemctl restart sshd testest du erneut in einer Rettungssession.
TOTP ist gut, hat aber einen strukturellen Schwachpunkt: Der Code kann in Echtzeit abgefischt und weitergeleitet werden (Phishing-Proxy). Phishing-resistent ist nur FIDO2. OpenSSH unterstützt seit Version 8.2 Security-Keys direkt als Key-Typ.
Erzeuge einen ed25519-sk-Key mit deinem YubiKey 5 NFC (ca. 60 €) oder Nitrokey 3A NFC (ca. 60 €):
ssh-keygen -t ed25519-sk -O resident -O verify-required -C "max@yubikey-2026"
-O resident speichert den Key auf dem Token selbst – du kannst ihn an jedem Rechner mit ssh-keygen -K wiederherstellen. -O verify-required erzwingt zusätzlich die PIN-Eingabe. Der Private Key verlässt das Gerät nie; selbst ein vollständig kompromittierter Laptop kann den Schlüssel nicht exfiltrieren.
Für Flotten ab etwa 10 Servern lohnt sich eine SSH-Certificate-Authority. Statt jeden Public Key einzeln in authorized_keys zu pflegen, signiert die CA kurzlebige Zertifikate mit 8 bis 24 Stunden Gültigkeit:
ssh-keygen -t ed25519 -f /etc/ssh/ca_user_ca -C "Hostazar User CA"
ssh-keygen -s /etc/ssh/ca_user_ca -I "max@laptop" -n max,deploy -V +12h ~/.ssh/id_ed25519.pub
Auf dem Server steht dann nur noch TrustedUserCAKeys /etc/ssh/ca_user_ca.pub. Vorteile: kein Key-Rotation-Aufwand, sofortiger Entzug durch kurze Gültigkeit, zentrale Rechtevergabe über Principals. Tools wie step-ca oder Vault SSH Secrets Engine automatisieren das komplett.
Port-Knocking versteckt SSH hinter einer geschlossenen Firewall. Der Port öffnet sich erst, wenn eine definierte Abfolge von Verbindungsversuchen eintrifft. Scanner und Shodan sehen nichts – der Port ist schlicht „closed".
Installiere knockd und konfiguriere /etc/knockd.conf:
[options]
UseSyslog
Interface = eth0
[openSSH]
sequence = 7000,8000,9000
seq_timeout = 5
command = /usr/sbin/ufw allow from %IP% to any port 22
tcpflags = syn
[closeSSH]
sequence = 9000,8000,7000
seq_timeout = 5
command = /usr/sbin/ufw delete allow from %IP% to any port 22
tcpflags = syn
Der Client sendet die Sequenz mit einem Einzeiler:
for p in 7000 8000 9000; do nc -z -w1 203.0.113.42 $p; done; ssh [email protected]
Achtung: Klassisches Port-Knocking ist replay-anfällig – ein Angreifer, der den Traffic mitschneidet, kann die Sequenz wiederverwenden. Sicherer ist Single Packet Authorization (SPA) mit fwknop. Dabei wird ein einzelnes, kryptografisch signiertes UDP-Paket gesendet, das der Server verifiziert und dann HMAC-geschützt den Port öffnet. Replay ist durch Zeitstempel und Nonce ausgeschlossen.
apt install fwknop-server fwknop-client
fwknop --get-key http://203.0.113.42:62201/ # Key vom Server holen
fwknop -n hostazar-web -D 203.0.113.42 # SPA-Paket senden
Der praktische Nutzen: Deine Angriffsfläche im Internet sinkt auf null erreichbare SSH-Ports. Für Gameserver oder Webhosting-Panels, die öffentlich erreichbar sein müssen, kombinierst du SPA mit einer IP-Whitelist für das Admin-Panel.
Selbst mit deaktivierter Passwort-Auth wirst du Log-Spam und Ressourcenverbrauch durch Bots sehen. Fail2ban bleibt 2026 der Standard für einfache Setups. Installation und Jail-Konfiguration:
apt install fail2ban
cat > /etc/fail2ban/jail.local <<'EOF'
[DEFAULT]
bantime = 1h
findtime = 10m
maxretry = 3
backend = systemd
[sshd]
enabled = true
port = ssh
mode = aggressive
EOF
systemctl enable --now fail2ban
fail2ban-client status sshd
Der aggressive-Modus erkennt auch Login-Versuche mit nicht existierenden Usern. Prüfe die Bans mit fail2ban-client status sshd – bei einem exponierten VPS sind 200 bis 2000 aktive Bans normal.
CrowdSec ist die moderne Alternative mit einem entscheidenden Vorteil: Es ist ein kollaboratives System. Wenn ein Angreifer bei dir auffällt, landet seine IP in einem globalen Blocklist-Netzwerk, von dem alle Teilnehmer profitieren. Das ist der Grund, warum CrowdSec auch die oben beschriebenen verteilten Low-and-Slow-Angriffe erkennt, an denen Fail2ban scheitert.
curl -s https://install.crowdsec.net | sh
cscli collections install crowdsecurity/sshd
cscli bouncers add firewall-bouncer
apt install crowdsec-firewall-bouncer-iptables
systemctl restart crowdsec crowdsec-firewall-bouncer
Die Community-Blocklist ist kostenlos. Die CrowdSec Console bietet kostenlose Basisnutzung und Premium-Tarife ab etwa 19 €/Monat für Teams mit mehreren Servern. Für Einzeladministratoren reicht die kostenlose Variante vollständig aus.
Ein Tarpit wie Endlessh hält Angreifer absichtlich in einer endlosen SSH-Banner-Phase fest. Der Bot verschwendet Minuten bis Stunden pro Verbindung, während dein Server praktisch keine Ressourcen verbraucht. Läuft auf Port 22, während echtes SSH auf 2222 wandert.
apt install endlessh
cat > /etc/endlessh/config <<'EOF'
Port 22
Delay 10000
MaxLineLength 32
MaxClients 4096
LogLevel 1
EOF
systemctl enable --now endlessh
Für das Audit-Logging aktivierst du LogLevel VERBOSE und wertest die Logs regelmäßig aus. Relevante Befehle:
journalctl -u ssh --since "24 hours ago" | grep "Failed"
lastb | head -20
grep "Accepted publickey" /var/log/auth.log | awk '{print $11}' | sort | uniq -c
Der letzte Befehl zeigt dir, welche Key-Fingerprints sich in den letzten Tagen verbunden haben. Ein unbekannter Fingerprint ist ein sofortiger Alarm. Für ernsthafte Umgebungen leitest du die Logs an ein zentrales SIEM weiter – Wazuh (kostenlos, Self-Hosted) oder Grafana Loki mit Promtail.
Setze zusätzlich auditd auf die SSH-Konfiguration an, damit Änderungen an /etc/ssh/ protokolliert werden:
auditctl -w /etc/ssh/ -p wa -k ssh_config_change
Damit siehst du in ausearch -k ssh_config_change jede Modifikation inklusive User, Zeitstempel und geändertem Pfad.
Die folgende Reihenfolge verhindert Aussperrung und ist in der Praxis erprobt:
tmux oder zweites Terminal).ssh-copy-id verteilen, Login mit Key testen.sshd_config setzen (z. B. 2222) und Firewall-Regel ergänzen – beide Ports parallel offen lassen.sshd -t, dann systemctl reload sshd.nullok erst danach entfernen./root/ssh-hardening-2026/ kopieren.Nach Schritt 10 prüfst du mit einem externen Scanner, was noch sichtbar ist:
nmap -Pn -p 22,2222,80,443 203.0.113.42
ss -tlnp | grep sshd
Erwartetes Ergebnis: Port 22 zeigt einen SSH-Banner (Endlessh), Port 2222 ist nur nach Knocking erreichbar, alle anderen Ports sind filtered.
Die meisten Maßnahmen sind kostenlos. Kostenpflichtig sind nur Hardware-Token und – optional – kommerzielle Management-Lösungen.
| Maßnahme | Kosten | Schutz gegen | Aufwand |
|---|---|---|---|
| SSH-Keys (Ed25519) | 0 € | Brute-Force, Credential Stuffing | 5 Min |
| sshd_config-Härtung | 0 € | Alle Login-Angriffe | 10 Min |
| TOTP-2FA | 0 € | Key-Diebstahl | 10 Min |
| FIDO2-Token | ca. 60 €/Stück | Key-Diebstahl, Phishing | 15 Min |
| SSH-Zertifikate (step-ca) | 0 € | Key-Wildwuchs, Rotation | 2–4 h |
| Port-Knocking (knockd) | 0 € | Scanner, Shodan | 20 Min |
| fwknop SPA | 0 € | Scanner, Replay | 45 Min |
| Fail2ban | 0 € | Brute-Force | 10 Min |
| CrowdSec | 0 € (Premium ab 19 €/Mon.) | Verteilte Angriffe | 20 Min |
| Endlessh-Tarpit | 0 € | Bot-Ressourcenverbrauch | 10 Min |
Für den Hosting-Unterbau: Ein Hetzner CX22 (2 vCPU, 4 GB RAM, 40 GB NVMe) kostet 4,51 €/Monat, ein Netcup VPS 200 G11 liegt bei rund 3,50 €/Monat. Beide reichen für einen gehärteten Admin-Host mit CrowdSec und Monitoring problemlos aus. Wichtig ist, dass dein Provider eine KVM-Konsole oder ein Rescue-System anbietet – das ist deine letzte Rettung, falls du dich doch aussperrst.
Für Managed-Hosting-Kunden gilt: Prüfe vor dem Hardening, ob dein Anbieter eigene SSH-Zugänge für Support-Zwecke benötigt. Manche Panels (Plesk, cPanel) brechen, wenn du PasswordAuthentication no setzt, ohne die Panel-eigenen Keys zu hinterlegen.
Nur über die Notfallwege deines Hosters: KVM-/VNC-Konsole, Rescue-Mode oder ein Support-Ticket. Deshalb gehört ein zweiter, offline aufbewahrter Key (z. B. auf einem verschlüsselten USB-Stick) zur Grundausstattung. Alternativ hinterlegst du einen Backup-Key in authorized_keys, der nur von einem separaten Gerät genutzt wird.
Es ist Obscurity – aber nützliche. Ein Portwechsel auf 2222 reduziert die automatisierten Login-Versuche in der Praxis um 90 bis 98 %, weil die meisten Botnets nur Port 22 scannen. Als alleinige Maßnahme reicht es nicht, als Teil einer Schichtung (Keys + 2FA + Firewall) ist es ein kostenloser Gewinn. Verlass dich aber nie darauf, dass ein ungewöhnlicher Port „unfindbar" ist – ein gezielter Portscan findet ihn in Sekunden.
Ja, genau dafür ist es gemacht. Da die Firewall-Regel nur für die Quell-IP des Knock-Pakets geöffnet wird, funktioniert es mit jeder dynamischen IP. Auf iOS und Android gibt es Apps wie „KnockOnD" oder „Port Knocker", die Sequenzen und SPA-Pakete senden können. Bei fwknop ist die Konfiguration etwas aufwendiger, dafür replay-sicher.
Für einen einzelnen Server mit deaktivierter Passwort-Authentifizierung reicht Fail2ban völlig. Es geht dann nur noch um Log-Hygiene und Ressourcenschutz. Sobald du aber mehrere Server betreibst oder öffentlich erreichbare Dienste hostest, ist CrowdSec klar überlegen: Die kollaborative Blocklist erkennt verteilte Angriffe, die pro IP unter der Fail2ban-Schwelle bleiben.
Bei klassischen, statischen Keys: alle 12 Monate, oder sofort bei Verdacht auf Kompromittierung. Bei SSH-Zertifikaten mit 8- bis 24-stündiger Gültigkeit entfällt die Rotation komplett – sie ist eingebaut. Wenn du FIDO2-Token mit residenten Keys nutzt, ist Rotation praktisch unnötig, solange der Token physisch sicher ist und die PIN geheim bleibt.
Nutze die Konsole deines Hosters. Bei Hetzner, Netcup und Contabo startest du den Server in den Rescue-Mode, mountest die Root-Partition und korrigierst /etc/ssh/sshd_config direkt. Bei Cloud-Anbietern wie AWS oder Azure gibt es Session-Manager bzw. Run-Command, mit denen du ohne SSH auf die Instanz zugreifst. Richte dir diese Notfallwege ein, bevor du härte – nicht danach.