Ziel dieses Tutorials: Ein nach Best Practices abgesicherter Ubuntu-Server – minimierte Angriffsfläche, gehärteter SSH-Zugang, aktive Firewall, Brute-Force-Schutz, automatische Sicherheitsupdates, Kernel- und Dateisystem-Härtung sowie Logging und Auditing. Prinzipiell übertragbar auf Ubuntu 22.04 LTS und Debian.
ubuntu-server-hardening.md — 17 KB
1. Grundprinzipien & Vorbereitung
Bevor ein einziger Befehl läuft, gelten vier Grundregeln:
- Minimalismus: Was nicht installiert ist, kann nicht angegriffen werden.
- Least Privilege: Jeder Dienst und jeder Benutzer bekommt nur die Rechte, die er wirklich braucht.
- Defense in Depth: Nie auf eine einzelne Maßnahme verlassen – Firewall UND sichere SSH-Config UND Fail2ban.
- Nachvollziehbarkeit: Jede Änderung dokumentieren; Änderungen an Config-Dateien vorher sichern (sudo cp datei datei.bak).
Alle folgenden Befehle laufen als frisch angelegter Benutzer mit sudo-Rechten bzw. initial als root auf einem Neu-System.
Wichtig: Diese Schritte niemals ungetestet per Copy & Paste auf einem Produktivsystem ausführen. Bei Remote-Servern immer eine zweite SSH-Session offen halten, bevor Firewall- oder SSH-Änderungen aktiviert werden – sonst droht der Selbstausschluss.
2. System aktualisieren
Der erste Schritt nach jeder Installation: alle Pakete auf den neuesten Stand bringen, um bereits bekannte Lücken zu schließen.
sudo apt update && sudo apt full-upgrade -y
sudo apt autoremove -y
sudo reboot
- apt update aktualisiert die Paketlisten, full-upgrade installiert alle Updates inkl. Abhängigkeitsänderungen.
- autoremove entfernt verwaiste Abhängigkeiten.
- Der Reboot stellt sicher, dass ein eventuell aktualisierter Kernel auch geladen wird.
Nach dem Neustart prüfen, ob der aktuelle Kernel läuft:
uname -r
3. Benutzer- und Rechteverwaltung
3.1 Dedizierten Admin-Benutzer anlegen
Niemals dauerhaft als root arbeiten. Einen eigenen Benutzer anlegen und in die sudo-Gruppe aufnehmen:
sudo adduser deploy
sudo usermod -aG sudo deploy
- adduser legt Benutzer inkl. Home-Verzeichnis und Passwort an.
- Die Mitgliedschaft in der Gruppe sudo erlaubt das Ausführen von Admin-Befehlen mit eigenem Passwort.
3.2 Root-Login sperren
sudo passwd -l root
-l (lock) sperrt das Passwort; root kann weiterhin über sudo -i oder su von sudo-Berechtigten genutzt werden.
3.3 Passwort-Richtlinien erzwingen
sudo apt install libpam-pwquality -y
sudo nano /etc/security/pwquality.conf
Empfohlene Werte (Zeilen einkommentieren/anpassen):
minlen = 14
dcredit = -1
ucredit = -1
lcredit = -1
ocredit = -1
maxrepeat = 3
- Erzwingt mindestens 14 Zeichen sowie Groß-/Kleinbuchstaben, Ziffern und Sonderzeichen.
- Gilt für alle lokalen Passwortänderungen (passwd).
3.4 sudo absichern
sudo visudo
- visudo prüft die Syntax vor dem Speichern – ein Tippfehler in sudoers kann sonst alle Admins aussperren.
- Optional: Logging aller sudo-Befehle aktivieren, indem folgende Zeile ergänzt wird:
Defaults logfile="/var/log/sudo.log"
3.5 Umask verschärfen
sudo nano /etc/login.defs
Wert UMASK auf 027 setzen. Neue Dateien sind damit standardmäßig nur für Besitzer les-/schreibbar und für die Gruppe lesbar – nicht für die ganze Welt.
4. SSH absichern
SSH ist der häufigste Angriffsvektor auf Server. Die Konfiguration erfolgt sauber über eine Drop-in-Datei statt direkt in sshd_config.
4.1 Schlüsselbasierte Anmeldung einrichten
Auf dem lokalen Client (nicht auf dem Server):
ssh-keygen -t ed25519 -C "deploy@server"
ssh-copy-id deploy@SERVER-IP
- ed25519 ist der moderne Standard – schnell und sicher.
- ssh-copy-id überträgt den öffentlichen Schlüssel nach ~/.ssh/authorized_keys auf dem Server.
Erst nach erfolgreichem Schlüssel-Login weitermachen.
4.2 sshd härten
sudo nano /etc/ssh/sshd_config.d/99-hardening.conf
PermitRootLogin no
PasswordAuthentication no
PubkeyAuthentication yes
PermitEmptyPasswords no
MaxAuthTries 3
LoginGraceTime 20
AllowUsers deploy
X11Forwarding no
AllowTcpForwarding no
AllowAgentForwarding no
ClientAliveInterval 300
ClientAliveCountMax 2
- PermitRootLogin no – root darf sich nie direkt per SSH anmelden.
- PasswordAuthentication no – nur noch Schlüssel, keine Passwort-Brute-Force mehr möglich.
- AllowUsers deploy – nur dieser Benutzer darf sich per SSH anmelden (Whitelist).
- MaxAuthTries 3 / LoginGraceTime 20 – reduziert Brute-Force-Versuche.
- Deaktivierte Forwardings verhindern Missbrauch des Servers als Tunnel/Pivot.
4.3 Konfiguration testen und Dienst neu starten
sudo sshd -t
sudo systemctl restart ssh
- sshd -t validiert die Konfiguration, ohne den Dienst zu stoppen. Nur bei fehlerfreier Ausgabe neu starten.
- Zweite Session offen halten und in einem neuen Terminal testen: ssh deploy@SERVER-IP.
4.4 Optional: SSH-Port ändern
Port 2222
Das ist „Security by Obscurity" – es reduziert Log-Müll durch Scanner, ersetzt aber keine echte Absicherung. Bei Änderung den neuen Port in der Firewall freigeben (Kapitel 6), bevor man sich trennt.
5. Optional: Zwei-Faktor-Authentifizierung (2FA) für SSH
Zusätzliche Hürde: neben dem SSH-Schlüssel ein zeitbasiertes Einmalpasswort (TOTP) per Authenticator-App.
sudo apt install libpam-google-authenticator -y
google-authenticator
- google-authenticator als der SSH-Benutzer ausführen (nicht root) – es erzeugt einen QR-Code für die App (Aegis, Google Authenticator, …).
- Die angezeigten Notfall-Codes sicher verwahren.
Anschließend PAM und sshd konfigurieren:
auth required pam_google_authenticator.so
KbdInteractiveAuthentication yes
AuthenticationMethods publickey,keyboard-interactive
Danach sudo sshd -t und sudo systemctl restart ssh.
- AuthenticationMethods publickey,keyboard-interactive erzwingt beides: Schlüssel UND TOTP-Code.
6. Firewall mit UFW
UFW (Uncomplicated Firewall) ist das Frontend für nftables unter Ubuntu.
sudo apt install ufw -y
sudo ufw default deny incoming
sudo ufw default allow outgoing
sudo ufw allow OpenSSH
sudo ufw enable
sudo ufw status verbose
- deny incoming – alles Eingehende ist grundsätzlich verboten (Default-Deny).
- allow OpenSSH – öffnet Port 22 (bei geändertem Port: sudo ufw allow 2222/tcp).
- Für jede weitere Rolle nur gezielt freigeben, z. B. Webserver: sudo ufw allow 'Nginx Full', sudo ufw allow 443/tcp.
Sicherheitssteigerung für SSH (Rate-Limiting statt blanket allow):
sudo ufw limit ssh
limit blockiert IPs temporär, die mehr als 6 Verbindungen in 30 Sekunden aufbauen – einfacher Brute-Force-Schutz auf Firewall-Ebene.
Regeln prüfen/löschen:
sudo ufw status numbered
sudo ufw delete 3
7. Fail2ban – Brute-Force-Schutz
Fail2ban wertet Logdateien aus und sperrt Angreifer-IPs dynamisch per Firewall.
sudo apt install fail2ban -y
sudo nano /etc/fail2ban/jail.local
[DEFAULT]
bantime = 1h
findtime = 10m
maxretry = 5
backend = systemd
[sshd]
enabled = true
port = ssh
logpath = %(sshd_log)s
- Nie die mitgelieferte jail.conf bearbeiten – lokale Anpassungen gehören in jail.local (update-sicher).
- bantime 1h – gesperrte IP bleibt 1 Stunde draußen; maxretry 5 – nach 5 Fehlversuchen in 10 Minuten greift die Sperre.
Dienst aktivieren und prüfen:
sudo systemctl enable --now fail2ban
sudo fail2ban-client status sshd
fail2ban-client status sshd zeigt aktuell gesperrte IPs und Statistiken.
8. Automatische Sicherheitsupdates
sudo apt install unattended-upgrades -y
sudo dpkg-reconfigure --priority=low unattended-upgrades
Konfiguration prüfen/anpassen:
sudo nano /etc/apt/apt.conf.d/50unattended-upgrades
Unattended-Upgrade::Automatic-Reboot "false";
Unattended-Upgrade::Remove-Unused-Dependencies "true";
- Installiert täglich automatisch Sicherheitsupdates aus den -security-Repositories.
- Automatischer Reboot bleibt auf Servern meist deaktiviert (false) – stattdessen regelmäßig prüfen:
ls /var/run/reboot-required
Existiert die Datei, steht ein Neustart an (z. B. nach Kernel-Update) – im Wartungsfenster einplanen.
9. Netzwerk-Härtung (Kernel-Parameter per sysctl)
sudo nano /etc/sysctl.d/99-hardening.conf
# IP-Spoofing-Schutz (Reverse Path Filtering)
net.ipv4.conf.all.rp_filter = 1
net.ipv4.conf.default.rp_filter = 1
# Source Routing verbieten
net.ipv4.conf.all.accept_source_route = 0
net.ipv6.conf.all.accept_source_route = 0
# ICMP-Redirects ignorieren/verwerfen (kein Router!)
net.ipv4.conf.all.accept_redirects = 0
net.ipv4.conf.default.accept_redirects = 0
net.ipv4.conf.all.secure_redirects = 0
net.ipv4.conf.all.send_redirects = 0
net.ipv6.conf.all.accept_redirects = 0
# SYN-Flood-Schutz
net.ipv4.tcp_syncookies = 1
# Pakete mit unmöglichen Absenderadressen loggen
net.ipv4.conf.all.log_martians = 1
# Fehlerhafte ICMP-Pakete ignorieren
net.ipv4.icmp_ignore_bogus_error_responses = 1
Aktivieren ohne Neustart:
sudo sysctl --system
- rp_filter verwirft Pakete mit gefälschten Absender-IPs.
- send_redirects = 0 ist Pflicht auf Servern – nur Router dürfen ICMP-Redirects senden.
- tcp_syncookies schützt vor SYN-Flood-DoS-Angriffen.
IPv6: Wird IPv6 im Netz nicht verwendet, sollte es komplett deaktiviert werden (weniger Angriffsfläche): net.ipv6.conf.all.disable_ipv6 = 1 ergänzen. Wird es genutzt, muss die Firewall (UFW regelt das automatisch mit) und die sysctl-Härtung auch IPv6 abdecken.
10. Dienste und Software minimieren
Jeder laufende Dienst ist potenzielle Angriffsfläche.
10.1 Offene Ports inventarisieren
sudo ss -tulpen
Zeigt alle lauschenden TCP/UDP-Ports inkl. Prozess. Alles Unbekannte recherchieren und deaktivieren.
10.2 Unnötige Dienste deaktivieren
systemctl list-unit-files --state=enabled
sudo systemctl disable --now DIENSTNAME
Typische Kandidaten auf Servern: cups (Druckdienst), avahi-daemon (mDNS), bluetooth, ModemManager.
10.3 Unnötige Pakete entfernen
sudo apt purge --auto-remove PAKETNAME
sudo apt clean
purge entfernt Paket inkl. Konfigurationsdateien.
10.4 Ubuntu Pro / Livepatch (optional)
sudo pro attach TOKEN
Kostenloses Ubuntu-Pro-Token (bis 5 Maschinen) liefert erweiterte Sicherheitsupdates (ESM) und Kernel-Livepatching ohne Reboot: sudo pro enable livepatch.
11. Dateisystem-Berechtigungen & Mount-Optionen
11.1 /tmp absichern
sudo nano /etc/fstab
tmpfs /tmp tmpfs defaults,noexec,nosuid,nodev 0 0
- noexec – keine Ausführung von Binaries aus /tmp (klassischer Ablageort für Malware).
- nosuid / nodev – keine SUID-Bits und Gerätedateien.
- Einhängen mit: sudo mount /tmp bzw. nach Reboot aktiv.
11.2 Problematische Berechtigungen finden
Welt-schreibbare Verzeichnisse ohne Sticky-Bit:
sudo find / -xdev -type d -perm -0002 ! -perm -1000 -ls 2>/dev/null
SUID/SGID-Dateien inventarisieren:
sudo find / -xdev -type f \( -perm -4000 -o -perm -2000 \) -ls 2>/dev/null
Ergebnis mit dem Auslieferungszustand vergleichen – unbekannte SUID-Binaries sind ein Alarmsignal (Privilegieneskalation).
12. AppArmor – Mandatory Access Control
AppArmor schränkt Programme auf ihre erlaubten Aktionen ein – selbst bei erfolgreicher Kompromittierung.
sudo apt install apparmor apparmor-utils -y
sudo aa-status
- aa-status zeigt geladene Profile (enforce = aktiv, complain = nur Logging).
- Ubuntu bringt für viele Dienste fertige Profile mit; zusätzliche Profile liegen in /usr/share/apparmor/extra-profiles/.
Profil scharf schalten:
sudo aa-enforce /etc/apparmor.d/PROFILNAME
13. Kernel-Härtung
Weitere sysctl-Parameter in /etc/sysctl.d/99-hardening.conf ergänzen:
# Kernel-Pointer im Userspace verbergen
kernel.kptr_restrict = 2
# Kernel-Logs (dmesg) nur für root
kernel.dmesg_restrict = 1
# Hardlink/Symlink-Schutz
fs.protected_hardlinks = 1
fs.protected_symlinks = 1
# Keine Core-Dumps von SUID-Programmen
fs.suid_dumpable = 0
Danach sudo sysctl --system.
Nicht benötigte Dateisystem-/Protokoll-Module sperren:
install cramfs /bin/true
install freevxfs /bin/true
install hfs /bin/true
install hfsplus /bin/true
install jffs2 /bin/true
install squashfs /bin/true
install udf /bin/true
install dccp /bin/true
install sctp /bin/true
install rds /bin/true
install tipc /bin/true
Verhindert das Nachladen exotischer Kernelmodule, die auf einem Server nichts zu suchen haben (Angriffsfläche im Kernel reduzieren).
USB-Speicher komplett verbieten (nur für High-Security-Umgebungen):
install usb-storage /bin/true
14. Logging, Auditing & Monitoring
14.1 Journald persistent machen
sudo mkdir -p /var/log/journal
sudo nano /etc/systemd/journald.conf
Storage=persistent
SystemMaxUse=500M
sudo systemctl restart systemd-journald
Standardmäßig flüchtig (RAM). Persistent = Logs überleben Neustarts – Pflicht für forensische Auswertung.
14.2 Audit-Daemon
sudo apt install auditd -y
sudo systemctl enable --now auditd
Beispiel-Regeln für kritische Dateien (/etc/audit/rules.d/hardening.rules):
-w /etc/passwd -p wa -k user_changes
-w /etc/shadow -p wa -k credential_changes
-w /etc/ssh/sshd_config -p wa -k sshd_changes
-w /var/log/ -p wa -k log_changes
Aktivieren und auswerten:
sudo augenrules --load
sudo ausearch -k sshd_changes
Überwacht Schreib-/Attribut-Zugriffe auf Benutzerdatenbank, SSH-Config und Logs.
14.3 Log-Auswertung automatisieren
sudo apt install logwatch -y
sudo logwatch --detail High --mailto admin@example.com --range today
Tägliche Zusammenfassung auffälliger Log-Einträge per Mail (MTA vorausgesetzt).
14.4 Remote-Logging (Empfehlung)
Logs zusätzlich auf einen zentralen Syslog-Server schieben – bei einer Kompromittierung können Angreifer sonst ihre Spuren löschen. In /etc/rsyslog.d/remote.conf:
*.* @@LOGSERVER-IP:514
15. Zeitsynchronisation
Korrekte Zeit ist Voraussetzung für auswertbare Logs und funktionierende Zertifikate.
sudo apt install chrony -y
timedatectl status
chronyc sources
- chrony ersetzt das einfachere systemd-timesyncd und ist robuster.
- chronyc sources zeigt die aktiven Zeitserver.
16. Backups
Härtung ersetzt keine Backups – ohne getestete Wiederherstellung ist alles nichts.
3-2-1-Regel: 3 Kopien, 2 verschiedene Medien, 1 Kopie extern/offsite.
Einfaches Beispiel mit rsync (Konfigurationsverzeichnisse sichern):
sudo rsync -aAX --delete /etc /home /var/log /mnt/backup/$(date +%F)/
- -aAX erhält Berechtigungen, ACLs und erweiterte Attribute.
- Wichtig: Backups verschlüsseln (z. B. mit restic oder borgbackup) und regelmäßig Restore-Tests durchführen.
17. Abschließender Sicherheits-Check: Lynis
Lynis auditiert das System automatisch und liefert einen Hardening-Index mit konkreten Empfehlungen.
sudo apt install lynis -y
sudo lynis audit system
- Am Ende steht ein Hardening Index (Ziel: 80+) plus Liste von „Suggestions".
- Regelmäßig (z. B. monatlich per Cron) wiederholen und den Index im Blick behalten.
Alternativ/ergänzend für CIS-konforme Audits: OpenSCAP mit dem CIS-Ubuntu-24.04-Benchmark.
Checkliste (TL;DR)
# 1. Updates
sudo apt update && sudo apt full-upgrade -y && sudo reboot
# 2. Admin-User, root sperren
sudo adduser deploy && sudo usermod -aG sudo deploy
sudo passwd -l root
# 3. SSH: Key-Auth, kein root, kein Passwort
sudo nano /etc/ssh/sshd_config.d/99-hardening.conf # PermitRootLogin no, PasswordAuthentication no, AllowUsers deploy
sudo sshd -t && sudo systemctl restart ssh
# 4. Firewall
sudo ufw default deny incoming && sudo ufw default allow outgoing
sudo ufw limit ssh && sudo ufw enable
# 5. Fail2ban
sudo apt install fail2ban -y && sudo systemctl enable --now fail2ban
# 6. Auto-Updates
sudo apt install unattended-upgrades -y
# 7. Kernel/Netz härten
sudo nano /etc/sysctl.d/99-hardening.conf && sudo sysctl --system
# 8. Dienste prüfen
sudo ss -tulpen
# 9. Audit
sudo apt install lynis -y && sudo lynis audit system
Merksatz: Erst Firewall und SSH absichern (mit offener Fallback-Session!), dann alles andere. Jede Änderung dokumentieren, regelmäßig Lynis laufen lassen und Backups testen.
Links: Ubuntu Security https://ubuntu.com/security · CIS Benchmarks https://www.cisecurity.org · Lynis https://cisofy.com/lynis/ · Fail2ban https://github.com/fail2ban/fail2ban