Abstrakte Darstellung eines gehärteten Servers mit Firewall, sicherem Administrationszugang und Schutzebenen

Server Hardening mit Ubuntu 26.04 LTS: die Admin-Referenz

Security 5. Okt. 2026

Ich härte einen Server nicht, weil ich glaube, damit einen „unknackbaren“ Zustand herstellen zu können. Den gibt es nicht. Ich härte ihn, um Angriffsfläche zu reduzieren, unnötige Privilegien zu entfernen, Missbrauch schwieriger zu machen, Angriffe früher zu erkennen und die Folgen eines erfolgreichen Angriffs zu begrenzen.

Als Referenz nehme ich hier Ubuntu Server 26.04 LTS. Die Version ist bewusst gewählt: Ubuntu 26.04 LTS ist seit April 2026 veröffentlicht, bringt unter anderem OpenSSH 10.2 und AppArmor 5.0 mit und ist damit eine aktuelle LTS-Basis. Die offiziellen Release Notes stehen unter https://documentation.ubuntu.com/release-notes/26.04/.

Der Beitrag ist als Arbeits- und Nachschlagereferenz gedacht. Nicht jede Einstellung passt auf jeden Server. Ein Router braucht andere Kernel- und Firewall-Einstellungen als ein Webserver, ein Datenbankserver andere Freigaben als ein Backup-Ziel. Ich behandle Hardening deshalb nicht als Copy-and-paste-Ritual, sondern als kontrollierten Prozess: erst verstehen, dann reduzieren, anschließend prüfen und dauerhaft betreiben.

Wichtig: Vor Änderungen an SSH, Firewall, PAM, Netzwerk oder Boot-Konfiguration halte ich immer einen zweiten administrativen Zugang beziehungsweise eine Provider-/KVM-/Konsolenmöglichkeit bereit. Eine Sicherheitsmaßnahme, die mich selbst dauerhaft aussperrt, ist kein erfolgreicher Hardening-Schritt.

1. Was Server Hardening tatsächlich bedeutet

Für mich beginnt Hardening mit einer einfachen Frage: Was muss dieser Server wirklich können?

Alles, was darüber hinausgeht, ist zunächst verdächtig. Ein nicht benötigter Dienst ist zusätzlicher Code. Ein zusätzlicher Port ist eine weitere erreichbare Schnittstelle. Ein unnötiges Paket kann eine weitere Schwachstelle mitbringen. Ein überprivilegierter Prozess vergrößert den Schaden, den ein erfolgreicher Exploit anrichten kann.

NIST beschreibt dieses Prinzip seit Jahren als „least functionality“: nicht benötigte Dienste, Anwendungen und Protokolle sollen entfernt oder deaktiviert werden. Die grundlegende NIST-Serverreferenz ist zwar älter, das Prinzip selbst ist zeitlos und findet sich auch in aktuellen Hardening-Benchmarks wieder: https://csrc.nist.gov/pubs/sp/800/123/final.

MITRE ATT&CK liefert die Angriffsperspektive dazu. Bei Network Service Discovery (T1046) suchen Angreifer gezielt nach erreichbaren Diensten und offenen Ports. MITRE nennt als Gegenmaßnahme ausdrücklich das Schließen unnötiger Ports und Dienste: https://attack.mitre.org/techniques/T1046/.

Das bedeutet für mich:

  • Ich installiere nur, was ich brauche.
  • Ich starte nur, was ich brauche.
  • Ich veröffentliche nur, was erreichbar sein muss.
  • Ich vergebe nur die Rechte, die notwendig sind.
  • Ich sammle genug Telemetrie, um Missbrauch erkennen zu können.
  • Ich halte Software aktuell.
  • Ich plane Wiederherstellung und Notfallzugang mit ein.

Hardening ist damit keine einzelne sshd_config, sondern eine Eigenschaft der gesamten Betriebsweise.

2. Die Ausgangslage: minimal, aktuell, nachvollziehbar

Ich beginne möglichst mit einer minimalen Ubuntu-Server-Installation und dokumentiere, welche Rolle der Host erfüllen soll. Je weniger Software bereits vorhanden ist, desto kleiner ist die Ausgangsfläche.

Zuerst verschaffe ich mir einen Überblick:

cat /etc/os-release
uname -a
dpkg-query -W -f='${binary:Package}\t${Version}\n' | less
systemctl --type=service --state=running
systemctl list-unit-files --state=enabled
ss -lntup

ss -lntup ist dabei einer meiner wichtigsten ersten Checks. Ich möchte nicht nur wissen, welche Pakete installiert sind, sondern welche Prozesse tatsächlich auf Netzwerk-Sockets lauschen.

Danach aktualisiere ich das System:

sudo apt update
sudo apt full-upgrade
sudo reboot

Ob ein Reboot notwendig ist, kann ich zusätzlich prüfen:

test -f /var/run/reboot-required && cat /var/run/reboot-required

Pakete, die ich nicht brauche, entferne ich bewusst und nicht blind:

apt-mark showmanual
sudo apt autoremove --purge

Bei Servern mit klar definierter Rolle lohnt sich eine Soll-Liste: Welche Pakete, Dienste, Benutzer, Ports und Timer dürfen vorhanden sein? Damit wird aus einer einmaligen Installation eine überprüfbare Baseline.

3. Benutzer, Root und sudo

Ein Angreifer braucht nicht zwingend einen Exploit. Gestohlene oder missbrauchte gültige Konten sind ein eigener, sehr relevanter Angriffsweg. MITRE führt das als Valid Accounts (T1078): https://attack.mitre.org/techniques/T1078/.

Ich vermeide deshalb gemeinsame Administratorkonten. Jeder Administrator sollte – soweit organisatorisch möglich – einen eigenen Account verwenden. Root bleibt ein technisches Konto; administrative Aktionen erfolgen nachvollziehbar über sudo.

Konten prüfe ich beispielsweise so:

getent passwd
getent group sudo
sudo passwd -S root
sudo lastlog
last -a

Interaktive Shells lassen sich gezielter betrachten:

awk -F: '$7 !~ /(nologin|false)$/ {print $1 ":" $7}' /etc/passwd

Ein neues Administratorkonto könnte ich so anlegen:

sudo adduser adminuser
sudo usermod -aG sudo adminuser

Bevor ich einen alten Zugang entferne, teste ich den neuen Zugang vollständig – inklusive sudo.

Für sudo-Änderungen verwende ich visudo:

sudo visudo

oder besser eine dedizierte Drop-in-Datei:

sudo visudo -f /etc/sudoers.d/admins

Ich vermeide pauschale NOPASSWD: ALL-Regeln. Wo Automatisierung einzelne privilegierte Aktionen benötigt, beschränke ich sie auf exakt die notwendigen Befehle.

Passwort-Policies bleiben relevant, selbst wenn SSH-Passwortlogin abgeschaltet ist: lokale Konsole, sudo, Recovery oder andere Dienste können weiterhin Passwörter verwenden. Für lokale Passwortqualität kann libpam-pwquality eingesetzt werden. Eine lokale Policy gehört in eine Drop-in-Konfiguration und muss zur Organisation passen; lange Passphrasen sind wichtiger als künstliche Sonderzeichen-Rituale.

Beispiel:

sudo apt install libpam-pwquality
sudoedit /etc/security/pwquality.conf.d/99-local.conf
minlen = 14

Das ist bewusst nur ein Ausgangspunkt. Kontensperren, zentrale Identitäten oder MFA müssen zum konkreten Authentifizierungsmodell passen.

4. SSH: der wichtigste administrative Zugang

Ubuntu 26.04 LTS liefert OpenSSH 10.2. Die Release Notes nennen unter anderem den hybriden Post-Quantum-Key-Exchange mlkem768x25519-sha256, der standardmäßig verfügbar ist, die Entfernung von DSA-Unterstützung und PerSourcePenalties: https://documentation.ubuntu.com/release-notes/26.04/summary-for-lts-users/.

SSH ist gleichzeitig ein typisches Ziel. MITRE beschreibt Remote Services: SSH (T1021.004) als Möglichkeit, mit gültigen Accounts auf entfernte Systeme zuzugreifen: https://attack.mitre.org/techniques/T1021/004/.

Ich härte SSH deshalb an drei Stellen: Erreichbarkeit, Authentifizierung und Fähigkeiten der Sitzung.

Ubuntu/Debian unterstützen Drop-ins unter /etc/ssh/sshd_config.d/. Das ist für lokale Regeln besser als ein unnötig großer Umbau der Paketdatei.

Dabei ist die OpenSSH-Präzedenz entscheidend: Für die meisten Direktiven gilt der zuerst gelesene Wert. Ubuntu bindet /etc/ssh/sshd_config.d/*.conf am Anfang der Hauptkonfiguration ein. Deshalb prüfe ich vorhandene Snippets, bevor ich ein eigenes anlege:

sudo ls -la /etc/ssh/sshd_config.d/
sudo grep -RniE '^(PermitRootLogin|PasswordAuthentication|KbdInteractiveAuthentication|PubkeyAuthentication|AllowGroups|X11Forwarding|PermitEmptyPasswords|PermitUserEnvironment|MaxAuthTries|LoginGraceTime|MaxSessions|ClientAliveInterval|ClientAliveCountMax|LogLevel|AllowAgentForwarding|AllowTcpForwarding|PermitTunnel)[[:space:]]' /etc/ssh/sshd_config /etc/ssh/sshd_config.d/ 2>/dev/null

Eine spätere Datei wie 60-hardening.conf überschreibt also nicht automatisch einen Wert, den ein früher gelesenes Snippet bereits gesetzt hat. Entscheidend ist anschließend immer die effektive Ausgabe von sshd -T. Die OpenSSH-Manpage dokumentiert das First-Value-Verhalten: https://man.openbsd.org/sshd_config.5.

Ein bewusst konservatives Beispiel für einen Server, der ausschließlich per Schlüssel administriert wird:


PermitRootLogin no
PasswordAuthentication no
KbdInteractiveAuthentication no
PubkeyAuthentication yes

AllowGroups ssh-admins

X11Forwarding no
PermitEmptyPasswords no
PermitUserEnvironment no

MaxAuthTries 3
LoginGraceTime 30
MaxSessions 4

ClientAliveInterval 300
ClientAliveCountMax 2

LogLevel VERBOSE

Dazu lege ich eine eigene Gruppe an:

sudo groupadd --system ssh-admins
sudo usermod -aG ssh-admins adminuser

Ob AllowTcpForwarding, AllowAgentForwarding und Tunneling abgeschaltet werden können, hängt von der Nutzung ab. Wenn ich sie nicht benötige, schränke ich sie ein:

AllowAgentForwarding no
AllowTcpForwarding no
PermitTunnel no

Das darf ich aber nicht gedankenlos auf Hosts anwenden, auf denen SSH-Port-Forwarding bewusst Teil des Betriebs ist.

Vor jedem Reload prüfe ich Syntax und effektive Konfiguration:

sudo sshd -t
sudo sshd -T | less

Erst wenn sshd -t ohne Fehler endet, lade ich neu:

sudo systemctl reload ssh.service

Die bestehende SSH-Sitzung bleibt geöffnet. In einem zweiten Terminal teste ich eine vollständige neue Anmeldung und sudo. Erst danach schließe ich die alte Sitzung.

Die effektive Konfiguration ist wichtiger als das, was ich in einer einzelnen Datei zu sehen glaube. Genau dafür ist sshd -T so wertvoll.

Versionsbanner

Informationsminimierung ist sinnvoll, aber kein Patch-Ersatz. Canonical dokumentiert, dass OpenSSH immer mindestens einen Teil seiner Version preisgibt. Der Ubuntu-spezifische Teil kann mit DebianBanner no unterdrückt werden: https://documentation.ubuntu.com/security/security-features/network/version-banners/openssh-server/.

DebianBanner no

Ich betrachte das als Reconnaissance-Reduktion, nicht als Sicherheitsgrenze. Ein verwundbarer SSH-Dienst bleibt verwundbar, auch wenn der Scanner die genaue Distribution nicht im Banner sieht.

5. SSH-Schlüssel sicher erzeugen und verwalten

Für neue administrative Schlüssel bevorzuge ich Ed25519, sofern keine spezielle Kompatibilitäts- oder Compliance-Anforderung dagegen spricht.

Auf dem Client:

ssh-keygen -t ed25519 -a 100 -f ~/.ssh/id_ed25519_admin -C "admin-key"

Ich verwende eine starke Passphrase. Der private Schlüssel bleibt privat und wird nicht auf den Server kopiert.

Den Public Key übertrage ich beispielsweise mit:

ssh-copy-id -i ~/.ssh/id_ed25519_admin.pub [email protected]

Oder ich pflege authorized_keys kontrolliert. Die Rechte sollten passen:

chmod 700 ~/.ssh
chmod 600 ~/.ssh/authorized_keys

Fingerprints prüfe ich mit:

ssh-keygen -lf ~/.ssh/id_ed25519_admin.pub

Bei höherem Schutzbedarf sind hardwaregestützte FIDO-Schlüssel interessant. OpenSSH unterstützt ed25519-sk und ecdsa-sk; ob sie in der konkreten Umgebung praktikabel sind, hängt von Clients, Recovery-Konzept und Administrationsprozess ab.

Schlüssel sind Credentials. Deshalb gehören zu einem guten Betrieb auch Ablauf und Widerruf: Wer besitzt welchen Schlüssel? Auf welchen Hosts ist er autorisiert? Wie entferne ich ihn bei Geräteverlust oder Personalwechsel?

6. SSH-Cipher, KEX und MACs im Jahr 2026

Bei SSH-Kryptografie vermeide ich eine typische Hardening-Falle: starre Listen aus alten Blogposts.

Ubuntu 26.04 bringt OpenSSH 10.2 mit. OpenSSH entwickelt seine Defaults weiter. Deshalb prüfe ich zuerst, was die installierte Version unterstützt und tatsächlich verwendet:

ssh -V
ssh -Q cipher
ssh -Q kex
ssh -Q mac
sudo sshd -T | grep -E '^(ciphers|kexalgorithms|macs) '

Die aktuellen OpenSSH-Manpages stehen unter https://man.openbsd.org/sshd_config.5.

Bereich Aktuelle starke Beispiele Einordnung
Cipher [email protected] moderner AEAD-Cipher
Cipher [email protected], [email protected] AES-GCM / AEAD
Cipher aes128-ctr, aes192-ctr, aes256-ctr weiterhin Bestandteil aktueller Defaults
KEX mlkem768x25519-sha256 hybrider Post-Quantum-Key-Exchange, in Ubuntu 26.04/OpenSSH 10.2 standardmäßig verfügbar
KEX sntrup761x25519-sha512 hybrider KEX
KEX curve25519-sha256 moderner klassischer KEX
MAC [email protected], [email protected] Encrypt-then-MAC; OpenSSH bewertet -etm als sicherer
MAC [email protected] Encrypt-then-MAC

Ich setze nicht automatisch eigene Ciphers, KexAlgorithms oder MACs. Eine selbst gepflegte Allowlist friert Kryptografie ein und kann nach einem Upgrade schlechter sein als der neue Distribution-/OpenSSH-Default.

Wenn eine Compliance-Vorgabe bestimmte Algorithmen fordert, dokumentiere ich die Abweichung, teste Kompatibilität und kontrolliere nach jedem OpenSSH-Upgrade erneut die effektiven Werte.

7. Admin-Zugang über WireGuard oder Management-Netze

Die wirksamste SSH-Härtung kann darin bestehen, SSH gar nicht öffentlich erreichbar zu machen.

Ein mögliches Modell ist ein dediziertes Management-Netz über WireGuard. Dann ist aus dem Internet nur der VPN-Endpunkt erreichbar; SSH akzeptiert Verbindungen ausschließlich aus dem Management-Netz beziehungsweise lauscht nur dort.

WireGuard selbst dokumentiert Installation und Schlüsselerzeugung unter https://www.wireguard.com/install/ und https://www.wireguard.com/quickstart/.

Installation:

sudo apt update
sudo apt install wireguard

Schlüssel mit restriktiver Umask:

umask 077
wg genkey | tee privatekey | wg pubkey > publickey

Ein stark vereinfachtes Serverbeispiel:


[Interface]
Address = 10.10.10.1/24
ListenPort = 51820
PrivateKey = <SERVER_PRIVATE_KEY>

[Peer]
PublicKey = <ADMIN_PUBLIC_KEY>
AllowedIPs = 10.10.10.2/32

Die Schlüsselwerte gehören selbstverständlich nicht in Dokumentation, Git oder Tickets.

Anschließend kann die Host-Firewall SSH beispielsweise nur aus 10.10.10.0/24 erlauben. Noch enger ist eine Bindung von sshd an die Management-Adresse – allerdings nur, wenn die Adressierung und Recovery sauber geplant sind.

Ein VPN macht Administration nicht automatisch sicher. MITRE führt externe Remote Services einschließlich VPNs als möglichen Initial-Access-/Persistence-Weg (T1133) auf: https://attack.mitre.org/techniques/T1133/. WireGuard-Schlüssel müssen deshalb wie hochprivilegierte Zugangsdaten behandelt werden.

Ich plane außerdem einen Break-Glass-Zugang. Wenn WireGuard durch Routing-, Firewall- oder Schlüsselprobleme ausfällt, brauche ich einen kontrollierten Notfallweg – etwa Provider-Konsole, KVM/IPMI in einem getrennten Management-Netz oder einen dokumentierten Recovery-Prozess.

8. Ports, Dienste und Firewall

Mein Grundsatz lautet: Default deny für eingehende Verbindungen, danach nur explizit benötigte Freigaben.

Ubuntu nutzt den Linux-Netfilter-Stack. Canonical beschreibt nftables als Nachfolger von iptables; UFW ist die einfachere Abstraktion für viele typische Serverfälle: https://documentation.ubuntu.com/security/security-features/network/firewall/.

Variante A: UFW

Für einen einfachen Server ist UFW oft ausreichend:

sudo apt install ufw

sudo ufw default deny incoming
sudo ufw default allow outgoing

sudo ufw allow from 10.10.10.0/24 to any port 22 proto tcp
sudo ufw allow 80/tcp
sudo ufw allow 443/tcp

sudo ufw enable
sudo ufw status verbose

Die SSH-Regel setze ich vor dem Aktivieren der Firewall.

Variante B: nftables

Bei komplexeren Regelwerken bevorzuge ich häufig nftables, weil Chains, Sets und Regeln expliziter modellierbar sind.

Ein minimales Beispiel für einen klassischen Host:

#!/usr/sbin/nft -f

flush ruleset

table inet filter {
    chain input {
        type filter hook input priority 0;
        policy drop;

        ct state established,related accept
        iif "lo" accept

        ip protocol icmp accept
        meta l4proto ipv6-icmp accept

        ip saddr 10.10.10.0/24 tcp dport 22 accept
        tcp dport { 80, 443 } accept
    }

    chain forward {
        type filter hook forward priority 0;
        policy drop;
    }

    chain output {
        type filter hook output priority 0;
        policy accept;
    }
}

Vor dem Laden prüfe ich:

sudo nft -c -f /etc/nftables.conf

Danach:

sudo systemctl enable --now nftables.service
sudo nft list ruleset

Das Beispiel ist keine universelle Firewall. Router, Docker-/Kubernetes-Hosts, VPN-Gateways, NAT, asymmetrisches Routing und Provider-Netze benötigen andere Regeln.

Für ICMPv6 verwende ich hier bewusst meta l4proto ipv6-icmp statt ip6 nexthdr ipv6-icmp: meta l4proto läuft durch mögliche IPv6-Extension-Header bis zum tatsächlichen Transportprotokoll. Die nftables-Dokumentation warnt ausdrücklich davor, ip6 nexthdr für diesen Zweck als gleichwertig zu behandeln: https://netfilter.org/projects/nftables/manpage.html.

Was ich zusätzlich prüfe

ss -lntup
sudo nft list ruleset
sudo ufw status verbose

Von einem externen Testsystem prüfe ich anschließend, welche Ports wirklich erreichbar sind. Ich verlasse mich nicht allein auf die lokale Konfiguration.

9. IPv6 gehört zum Hardening dazu

IPv6 einfach abzuschalten, weil die Firewall nur für IPv4 geplant wurde, ist für mich kein sauberes Sicherheitskonzept.

Wenn ein Host IPv6 besitzt, muss ich IPv6 genauso inventarisieren, filtern und überwachen. nftables kann IPv4 und IPv6 gemeinsam in einer inet-Tabelle behandeln. Bei UFW prüfe ich, ob IPv6 aktiviert und die Regeln entsprechend wirksam sind.

Wichtig ist außerdem ICMPv6. IPv6 benötigt bestimmte ICMPv6-Nachrichten für grundlegende Netzwerkfunktionen. Ein pauschales „ICMPv6 komplett blockieren“ kann das Netz beschädigen.

Wenn IPv6 wirklich nicht verwendet werden soll, entscheide ich das bewusst auf Architektur-Ebene – nicht als Notlösung für ein unvollständiges Firewall-Regelwerk.

10. Kernel- und sysctl-Härtung

Ubuntu bringt bereits zahlreiche Kernel-Schutzmechanismen mit. Canonical dokumentiert unter anderem ASLR, ptrace-Einschränkungen, nicht ausführbaren Speicher und weitere Prozess-/Speicherschutzfunktionen: https://documentation.ubuntu.com/security/security-features/process-memory/.

Ich überschreibe deshalb nicht hunderte sysctls aus einem fremden Gist. Ich ändere nur Parameter, deren Wirkung ich verstehe und die zur Serverrolle passen.

Lokale systemd-sysctl-Konfiguration gehört unter /etc/sysctl.d/. Die Ubuntu-26.04-Manpage beschreibt Priorität und Format: https://manpages.ubuntu.com/manpages/resolute/man5/sysctl.d.5.html.

Ein vorsichtiges Beispiel:


kernel.kptr_restrict = 2
kernel.dmesg_restrict = 1

kernel.yama.ptrace_scope = 1

fs.protected_hardlinks = 1
fs.protected_symlinks = 1

net.ipv4.conf.all.accept_redirects = 0
net.ipv4.conf.default.accept_redirects = 0
net.ipv6.conf.all.accept_redirects = 0
net.ipv6.conf.default.accept_redirects = 0

net.ipv4.conf.all.send_redirects = 0
net.ipv4.conf.default.send_redirects = 0

Prüfen und laden:

sudo sysctl --system
sysctl kernel.kptr_restrict
sysctl kernel.dmesg_restrict
sysctl kernel.yama.ptrace_scope

Parameter wie rp_filter, IP-Forwarding, BPF-Einschränkungen oder Router-spezifische Werte setze ich nicht pauschal. Sie können VPN, Multihoming, Container-Netze oder Routing beeinflussen.

Die richtige Frage ist nicht „Welche 100 sysctls finde ich online?“, sondern: Welche Kernel-Funktion benötigt meine Serverrolle – und welche nicht?

11. Dateisystem, Mounts, Rechte und SUID/SGID

Dateirechte sind eine zweite Sicherheitsgrenze nach der Authentifizierung.

Ich suche regelmäßig nach ungewöhnlichen weltbeschreibbaren Dateien und SUID-/SGID-Binaries:

sudo find / -xdev -type f -perm -0002 -ls
sudo find / -xdev -type f \( -perm -4000 -o -perm -2000 \) -ls

Diese Befehle bedeuten nicht, dass jeder Treffer falsch ist. Sie erzeugen eine Prüfliste.

Bei separaten Dateisystemen können Mount-Optionen wie nodev, nosuid und noexec sinnvoll sein, beispielsweise für Datenbereiche, in denen keine Geräte, SUID-Binaries oder Programme benötigt werden. Ich setze sie jedoch nicht blind auf Verzeichnisse, deren Software Ausführung oder spezielle Semantik erwartet.

Konfiguration:

UUID=<uuid> /srv/data ext4 defaults,nodev,nosuid 0 2

Vor einem Reboot:

sudo mount -a
findmnt -o TARGET,SOURCE,FSTYPE,OPTIONS

Besonders wichtig sind Secrets und private Schlüssel:

chmod 600 /path/to/private-key
chown root:root /path/to/private-key

Ich kontrolliere außerdem, welche Prozesse überhaupt als root laufen und ob sie diese Rechte benötigen.

12. AppArmor: Schaden nach einem Exploit begrenzen

Ubuntu 26.04 führt AppArmor 5.0. Canonical dokumentiert AppArmor als Linux Security Module für Mandatory Access Control. Es ist auf Ubuntu standardmäßig installiert und geladen: https://documentation.ubuntu.com/server/how-to/security/apparmor/index.html.

Status:

sudo aa-status

Ein AppArmor-Profil beschreibt, auf welche Dateien, Fähigkeiten und Ressourcen ein Prozess zugreifen darf. Das ist besonders wertvoll bei netzwerkexponierten Diensten: Ein erfolgreicher Exploit im Dienst soll nicht automatisch freien Zugriff auf das gesamte System erhalten.

Zusätzliche Werkzeuge:

sudo apt install apparmor-utils

Profile können zunächst im Lern-/Complain-Modus entwickelt und danach in Enforce gesetzt werden:

sudo aa-complain /path/to/program
sudo aa-enforce /path/to/program

Nach Änderungen:

sudo apparmor_parser -r /etc/apparmor.d/profile.name

Ubuntu 26.04 übernimmt eine ausgeweitete Menge an AppArmor-Profilen. Canonical weist ausdrücklich darauf hin, dass stärkere Profile legitime Nutzung beeinträchtigen können; Denials müssen deshalb ausgewertet werden. Die 26.04-Release Notes dokumentieren diesen Punkt: https://documentation.ubuntu.com/release-notes/26.04/summary-for-lts-users/.

Ich deaktiviere AppArmor nicht, nur weil eine Anwendung einen Denial erzeugt. Ich untersuche zuerst, ob die Anwendung tatsächlich eine legitime zusätzliche Berechtigung braucht.

13. systemd-Dienste zusätzlich sandboxen

Viele Dienste lassen sich zusätzlich über systemd einschränken. Ein guter Einstieg ist:

systemd-analyze security
systemd-analyze security nginx.service

systemd-analyze security bewertet die von systemd angebotenen Sandbox-Einstellungen und liefert einen Exposure-Wert. Die Dokumentation warnt zu Recht: Ein hoher Wert beweist keine Verwundbarkeit, ein niedriger Wert keine vollständige Sicherheit. Er zeigt lediglich, wie stark die systemd-eigenen Mechanismen genutzt werden: https://www.man7.org/linux/man-pages/man1/systemd-analyze.1.html.

Typische Optionen für eigene Dienste sind:

[Service]
NoNewPrivileges=yes
PrivateTmp=yes
PrivateDevices=yes
ProtectSystem=strict
ProtectHome=yes
ProtectKernelTunables=yes
ProtectKernelModules=yes
ProtectControlGroups=yes
RestrictSUIDSGID=yes

NoNewPrivileges=yes verhindert beispielsweise, dass der Prozess oder seine Kinder über execve() neue Privilegien durch setuid/setgid oder File Capabilities erhalten. ProtectSystem=strict macht den Dateisystembaum für den Dienst weitgehend read-only. Die systemd-Dokumentation steht unter https://www.freedesktop.org/software/systemd/man/latest/systemd.exec.html.

Aber auch hier gilt: nicht blind kopieren. Ein Dienst, der Daten schreiben, Geräte verwenden oder Kernel-Funktionen verwalten muss, benötigt gezielte Ausnahmen.

Für Paketdienste erstelle ich Overrides statt die Unit-Datei des Pakets direkt zu verändern:

sudo systemctl edit example.service

Nach dem Speichern lasse ich systemd die Konfiguration neu einlesen und prüfe die tatsächlich zusammengesetzte Unit:

sudo systemctl daemon-reload
systemctl cat example.service
systemd-analyze security example.service
sudo systemctl restart example.service
sudo systemctl status example.service

systemd-analyze verify ist für die Offline-Prüfung von Unit-Dateien gedacht. Ein mit systemctl edit erzeugtes Drop-in behandle ich deshalb nicht isoliert wie eine vollständige Unit-Datei; maßgeblich ist die aus Haupt-Unit und Drop-ins zusammengesetzte Konfiguration.

14. Updates, Security Patches und Lifecycle

Hardening ohne Patchmanagement veraltet.

Canonical veröffentlicht Security Updates für unterstützte Ubuntu-Releases und dokumentiert CVEs unter https://ubuntu.com/security/cves. Die Security-Update-Dokumentation erklärt außerdem, dass Ubuntu Sicherheitskorrekturen häufig als Backports bereitstellt; eine scheinbar ältere Upstream-Versionsnummer bedeutet daher nicht automatisch, dass ein Ubuntu-Paket ungepatcht ist: https://documentation.ubuntu.com/security/security-updates/.

unattended-upgrades ist auf Ubuntu Server standardmäßig vorgesehen, um Security Updates automatisch einzuspielen. Ich prüfe trotzdem den realen Zustand:

systemctl status apt-daily.timer apt-daily-upgrade.timer
apt-config dump | grep -i unattended
grep -R "Allowed-Origins" /etc/apt/apt.conf.d/

Simulation:

sudo unattended-upgrade --dry-run --debug

Logs:

sudo less /var/log/unattended-upgrades/unattended-upgrades.log

Eigene Anpassungen gehören in eine separate Drop-in-Datei unter /etc/apt/apt.conf.d/; Canonical rät davon ab, die Paketdatei 50unattended-upgrades direkt zu editieren.

Beispiel:

// /etc/apt/apt.conf.d/60local-unattended-upgrades

Unattended-Upgrade::Automatic-Reboot "false";

Ob ich automatisch rebooten lasse, hängt von der Umgebung ab. Kritisch ist nicht die eine richtige Einstellung, sondern dass ich Reboots, Kernelwechsel und Service-Restarts bewusst behandle und nicht monatelang einen gepatchten Datenträger mit ungepatchten laufenden Prozessen verwechsle.

Drittanbieter-Repositories und PPAs sind ein eigener Supply-Chain-Risikofaktor. Ich verwende so wenige wie möglich, prüfe deren Herkunft und Lifecycle und entferne nicht mehr benötigte Quellen.

15. Fail2ban: nützlich, aber kein Ersatz für starke Authentifizierung

Fail2ban beobachtet Logereignisse und kann nach wiederholten Fehlversuchen Quelladressen temporär sperren. Das hilft gegen automatisiertes Credential Guessing und reduziert Lograuschen.

Es ersetzt aber weder SSH-Keys noch Firewall, MFA, VPN oder saubere Account-Policies.

Installation:

sudo apt install fail2ban

Die Upstream-Dokumentation empfiehlt, die ausgelieferte jail.conf nicht direkt zu verändern, sondern lokale Overrides zu verwenden: https://github.com/fail2ban/fail2ban/blob/master/config/jail.conf.

Beispiel:


[sshd]
enabled = true
backend = systemd
bantime = 1h
findtime = 10m
maxretry = 5

Danach:

sudo systemctl enable --now fail2ban
sudo fail2ban-client status
sudo fail2ban-client status sshd

Mit systemd-Backend wird das Journal ausgewertet; dafür ist kein logpath vorgesehen. Die Fail2ban-Manpage beschreibt das ausdrücklich: https://github.com/fail2ban/fail2ban/blob/master/man/jail.conf.5.

Ich teste Fail2ban kontrolliert und achte darauf, Management-/Monitoring-Systeme nicht versehentlich auszusperren. ignoreip ist kein Ort für großzügige ganze Netze, nur weil es bequem ist.

Wenn SSH ausschließlich über ein kleines WireGuard-Managementnetz erreichbar ist, sinkt der Nutzen eines öffentlich wirksamen SSH-Fail2ban-Jails deutlich. Genau deshalb muss die Maßnahme zur Architektur passen.

16. Logging, Journald, rsyslog und zentrale Logs

Ein Angreifer, der Root erreicht, kann lokale Logs manipulieren oder löschen. Deshalb möchte ich wichtige Security- und Betriebslogs möglichst vom betroffenen Host wegbringen.

Zuerst prüfe ich das lokale Journal:

journalctl --disk-usage
journalctl -p warning..alert
journalctl -u ssh.service

Für zentrale Syslog-Übertragung kann rsyslog eingesetzt werden. Bei sensiblen Netzen verwende ich keine ungeschützte UDP-Weiterleitung, wenn eine authentisierte TLS-Verbindung möglich ist. Die offizielle rsyslog-TLS-Dokumentation steht unter https://docs.rsyslog.com/doc/tutorials/tls.html.

Ein schematisches TLS-Forwarding – Zertifikatsnamen und Pfade müssen an die eigene PKI angepasst werden:


global(
  DefaultNetstreamDriver="gtls"
  DefaultNetstreamDriverCAFile="/etc/ssl/certs/ca-certificates.crt"
)

action(
  type="omfwd"
  target="log.example.com"
  port="6514"
  protocol="tcp"
  StreamDriver="gtls"
  StreamDriverMode="1"
  StreamDriverAuthMode="x509/name"
  StreamDriverPermittedPeers="log.example.com"

  queue.type="LinkedList"
  action.resumeRetryCount="-1"
)

Vor Neustart:

sudo rsyslogd -N1

Danach:

sudo systemctl restart rsyslog
logger "hardening-test $(date --iso-8601=seconds)"

Anschließend prüfe ich am zentralen Ziel, ob das Testereignis angekommen ist.

Wichtig ist die Transport-Queue: Ein zentraler Logserver kann ausfallen. Logging darf dann nicht einfach unbemerkt verschwinden oder den Host blockieren. Queue-, Speicher- und Retention-Konzept gehören deshalb zur Logging-Architektur.

17. auditd und nachvollziehbare Änderungen

auditd ist die Userspace-Komponente des Linux Audit Systems. Es schreibt Audit Records; Regeln können über auditctl beziehungsweise persistent über /etc/audit/rules.d/ geladen werden. Für Ubuntu 26.04 dokumentiert die aktuelle auditctl-Manpage Syntax und Verhalten unter https://manpages.ubuntu.com/manpages/resolute/man8/auditctl.8.html.

Installation:

sudo apt install auditd audispd-plugins
sudo systemctl enable --now auditd

Status:

sudo auditctl -s
sudo auditctl -l

Ein bewusst kleines Beispiel für einen x86_64-Host, das Schreib- und Attributänderungen an sudoers-Dateien beobachtet:

-a always,exit -F arch=b64 -F path=/etc/sudoers -F perm=wa -k sudoers_changes
-a always,exit -F arch=b64 -F dir=/etc/sudoers.d/ -F perm=wa -k sudoers_changes

Die ältere -w-Watch-Syntax verwende ich hier bewusst nicht: Die aktuelle Ubuntu-26.04-auditctl-Manpage kennzeichnet sie als veraltet und empfiehlt syscall-basierte Regeln. Auf Systemen, die zusätzlich relevante 32-Bit-Syscalls unterstützen und auditieren sollen, muss die Architektur entsprechend berücksichtigt werden; ich übernehme dafür keine fremde Regelmenge blind.

Regeln laden:

sudo augenrules --load

Suchen:

sudo ausearch -k sudoers_changes

Audit-Regeln können sehr viel Last und Logvolumen erzeugen. Ich baue deshalb keine riesige Regelmenge aus dem Internet ein, ohne zu verstehen, welche Ereignisse sie erzeugt und wie sie ausgewertet werden.

Audit ist außerdem kein SIEM. Es erzeugt relevante Telemetrie; Korrelation, Alarmierung und langfristige Analyse benötigen weitere Komponenten.

18. Zeit ist ein Security-Thema

Falsche Zeit zerstört Korrelation. Wenn Firewall, Server, SIEM und Authentifizierungsdienst unterschiedliche Zeitstände haben, wird Incident Response unnötig schwer. Zertifikate und andere kryptografische Verfahren sind ebenfalls zeitabhängig.

Ubuntu 26.04 verwendet bei Neuinstallationen standardmäßig Chrony anstelle von systemd-timesyncd; Canonical nennt außerdem NTS mit Ubuntu-Zeitservern: https://documentation.ubuntu.com/release-notes/26.04/summary-for-lts-users/.

Status:

systemctl status chrony.service
chronyc tracking
chronyc sources -v

Chrony unterstützt Network Time Security (NTS). Canonical beschreibt die Konfiguration unter https://documentation.ubuntu.com/server/how-to/networking/serve-ntp-with-chrony/.

Für einen expliziten NTS-Pool kann eine Zeile beispielsweise so aussehen:

pool 1.ntp.ubuntu.com iburst maxsources 1 nts prefer

Danach kann ich Authentisierungsdaten prüfen:

sudo chronyc -N authdata

19. Monitoring, Integrität und Vulnerability Management

Ein gehärteter Server kann morgen unsicher sein. Deshalb brauche ich einen Prozess, der Veränderungen erkennt.

Ich überwache mindestens:

  • Erreichbarkeit und Dienstfunktion,
  • CPU, RAM, Storage und Inodes,
  • ungewöhnliche Neustarts und Servicefehler,
  • ausstehende Security Updates,
  • Zertifikatsablauf,
  • SSH-/sudo-/Authentifizierungsereignisse,
  • Firewall- und Fail2ban-Ereignisse,
  • AppArmor-Denials,
  • Backup- und Restore-Fähigkeit,
  • Änderungen an sicherheitskritischen Dateien,
  • bekannte Schwachstellen der installierten Software.

Dateiintegritätsüberwachung kann beispielsweise mit AIDE oder über ein zentrales Security-System erfolgen. Wichtig ist weniger das Produkt als die Frage: Erkenne ich eine unerwartete Änderung – und kann ich sie einem legitimen Change zuordnen?

Vulnerability Scanner sind ebenfalls kein Ersatz für Patchmanagement. Sie helfen mir, bekannte Schwachstellen, exponierte Dienste und Fehlkonfigurationen sichtbar zu machen.

Canonical pflegt die Ubuntu-CVE-Datenbank unter https://ubuntu.com/security/cves. Bei Ubuntu bewerte ich einen Fund gegen den tatsächlichen Ubuntu-Paketstand und nicht nur gegen eine Upstream-Versionsnummer.

20. Backup, Recovery und Break-Glass-Zugang

Hardening kann einen Angriff nicht garantiert verhindern. Deshalb gehört Recovery zur Sicherheitsarchitektur.

Ich sichere nicht nur Nutzdaten, sondern auch die Informationen, die für einen Wiederaufbau benötigt werden: Konfiguration, Paket-/Rollenbeschreibung, Schlüsselmaterial soweit zulässig und sicher, Firewallregeln, Service-Definitionen, PKI-Abhängigkeiten und Dokumentation.

Backups sollten nicht mit denselben Credentials und denselben Schreibrechten erreichbar sein wie das produktive System. Sonst kann ein kompromittierter Server möglicherweise gleich seine Backups mit zerstören.

Entscheidend ist der Restore-Test.

Ich möchte beantworten können:

  • Welche Daten darf ich maximal verlieren?
  • Wie lange darf die Wiederherstellung dauern?
  • Wo liegen vertrauenswürdige Installations- und Konfigurationsquellen?
  • Wie stelle ich fest, dass ein Restore nicht bereits kompromittiert ist?
  • Wie erreiche ich den Server, wenn VPN, SSH oder Firewallkonfiguration defekt sind?

Ein Break-Glass-Zugang ist kein dauerhaft offen gelassener Hintereingang. Er ist ein kontrollierter, dokumentierter und getesteter Notfallweg.

21. Secure Boot und Verschlüsselung

UEFI Secure Boot verhindert, dass nicht vertrauenswürdiger Code einfach in der Bootkette ausgeführt wird. Ubuntu validiert bei aktiviertem Secure Boot unter anderem Bootloader, Kernel und Kernelmodule. Canonical beschreibt die Architektur ausführlich unter https://documentation.ubuntu.com/security/security-features/platform-protections/secure-boot/.

Status:

mokutil --sb-state

Secure Boot ist besonders relevant, wenn physischer Zugriff oder die Integrität der Bootkette Teil des Threat Models sind.

Für Daten „at rest“ ist Full Disk Encryption ein weiterer Baustein. Canonical führt für Ubuntu 26.04 LUKS-basierte Full-Disk-Encryption als Sicherheitsfunktion auf: https://documentation.ubuntu.com/security/security-features/security-features-tables/.

Bei Remote-Servern ist Verschlüsselung allerdings auch eine Betriebsfrage: Wie wird nach einem ungeplanten Reboot entsperrt? Gibt es TPM-basierte Mechanismen, Remote-Unlock oder eine Konsole? Wer besitzt Recovery Keys? Verschlüsselung ohne Recovery-Konzept kann Verfügbarkeit zerstören.

22. Hardening gegen typische Angriffstechniken

Ich finde Hardening verständlicher, wenn ich Maßnahmen nicht nur als Checkliste, sondern gegen reale Angriffsideen betrachte.

Angriff / MITRE-Technik Was der Angreifer versucht Hardening, das Risiko reduziert
Network Service Discovery – T1046 erreichbare Hosts, Ports und Dienste finden unnötige Dienste entfernen, Default-Deny-Firewall, Managementdienste nicht öffentlich exponieren
Exploit Public-Facing Application – T1190 Schwachstelle oder Fehlkonfiguration eines erreichbaren Dienstes ausnutzen Patchmanagement, minimale Exposition, AppArmor/systemd-Sandboxing, Segmentierung, Vulnerability Scanning
Valid Accounts – T1078 gestohlene oder legitime Credentials missbrauchen individuelle Konten, Least Privilege, Schlüssel/MFA wo möglich, Account-Audits, VPN-/Quellnetzbeschränkung
Remote Services: SSH – T1021.004 SSH für Zugriff oder laterale Bewegung nutzen SSH nur aus Managementnetz, Keys, Root-Login aus, AllowGroups, Logging
External Remote Services – T1133 VPN oder andere Remote-Zugänge für Initial Access/Persistenz missbrauchen Schlüssel schützen, Zugänge begrenzen, Telemetrie, MFA wo verfügbar, Break-Glass getrennt halten
System Information Discovery – T1082 OS, Versionen und Patchstand ermitteln unnötige Banner/Debugdaten reduzieren; wichtiger: patchen und privilegierte Discovery erkennen
Defense Impairment / Log-Manipulation Security-Telemetrie schwächen oder entfernen zentrale Logs, Audit, externe Alarmierung, restriktive Rechte
Destructive Impact / Ransomware Daten und Systeme unbrauchbar machen getrennte Backups, immutable/offline Kopien je nach Bedarf, Restore-Tests, Least Privilege

MITRE beschreibt öffentlich erreichbare Anwendungen ausdrücklich als Ziel von Exploits und empfiehlt unter anderem, nicht benötigte öffentliche Dienste zu beschränken, Software zu aktualisieren, zu segmentieren und regelmäßig zu scannen: https://attack.mitre.org/techniques/T1190/.

Wichtig ist die Formulierung „Risiko reduzieren“. Eine Firewall „verhindert T1190“ nicht. Ein VPN „verhindert gestohlene Accounts“ nicht. Security entsteht aus mehreren unabhängigen Kontrollen.

23. CIS, Ubuntu Security Guide und automatisierte Audits

Für eine systematische Baseline ist der CIS Benchmark wertvoll. Seit August 2026 existiert der CIS Ubuntu Linux 26.04 LTS Benchmark v1.0.0. CIS dokumentiert die Veröffentlichung unter https://www.cisecurity.org/insights/blog/cis-benchmarks-september-2026-update und die Unterstützung in CIS-CAT unter https://www.cisecurity.org/cybersecurity-tools/cis-cat-pro/cis-benchmarks-supported-by-cis-cat-pro.

Ich verwende CIS nicht als magischen „Secure“-Schalter. Level-1- und Level-2-Empfehlungen können Funktionalität beeinflussen. Ich ordne jede Abweichung dem Serverzweck zu und dokumentiere bewusst akzeptierte Ausnahmen.

Canonical bietet mit dem Ubuntu Security Guide (USG) Werkzeuge für Compliance-/Hardening-Automatisierung im Rahmen von Ubuntu Pro: https://documentation.ubuntu.com/security/compliance/.

Hier ist 2026 eine wichtige Versionsnuance: Canonicals öffentlich dokumentierte USG-CIS-Automatisierungsseite listet derzeit Profile bis Ubuntu 24.04 LTS auf: https://ubuntu.com/security/certifications/docs/usg/cis. Obwohl der CIS-26.04-Benchmark bereits veröffentlicht ist, behaupte ich deshalb nicht, dass Canonicals automatisiertes 26.04-USG-Profil bereits allgemein verfügbar ist, solange Canonical das nicht entsprechend dokumentiert.

Das ist ein gutes Beispiel dafür, warum eine Hardening-Referenz versioniert sein muss.

24. Regelmäßig prüfen statt einmal härten

Nach dem Hardening führe ich eine technische Bestandsaufnahme durch:

cat /etc/os-release
uname -a

ss -lntup

sudo nft list ruleset
sudo ufw status verbose

sudo sshd -t
sudo sshd -T | less

sudo aa-status

systemd-analyze security

apt list --upgradable
systemctl status apt-daily-upgrade.timer

sudo fail2ban-client status

sudo auditctl -s
sudo auditctl -l

chronyc tracking
chronyc sources -v

systemctl --failed

Zusätzlich prüfe ich den Host von außen. Ein lokaler ss-Output zeigt mir, dass ein Prozess lauscht; erst ein externer Scan zeigt, was über die relevante Netzstrecke tatsächlich erreichbar ist.

Ich dokumentiere die Sollwerte. Sonst weiß ich in drei Monaten nicht mehr, ob ein neuer Port beabsichtigt war.

Hardening ist damit ein Kreislauf aus Baseline, Änderung, Verifikation und erneuter Bewertung.

25. Hardening endet nicht beim Betriebssystem

Ein gehärtetes Ubuntu ist nur das Fundament.

Danach härte ich jede darauf betriebene Komponente entsprechend ihrer eigenen aktuellen Security-Dokumentation. Dazu gehören beispielsweise:

  • Webserver und Reverse Proxies wie Nginx oder Apache,
  • Datenbanken wie PostgreSQL, MariaDB/MySQL oder Redis,
  • Container-Runtimes und Orchestrierung,
  • Mailserver,
  • DNS-Server,
  • Datei- und Transferdienste,
  • Monitoring-, Backup- und Managementoberflächen,
  • APIs,
  • CMS und Webanwendungen,
  • Runtime-Stacks wie PHP, Python, Java oder Node.js.

Das Grundprinzip bleibt gleich: so wenig wie möglich veröffentlichen und so wenig wie möglich verraten.

Eine Datenbank gehört normalerweise nicht direkt ins Internet, nur weil sie technisch auf TCP lauschen kann. Eine Administrationsoberfläche muss nicht öffentlich sein, nur weil sie HTTPS verwendet. Ein Webserver braucht nicht jedes Modul. Ein Container braucht nicht automatisch Host-Netzwerk, privilegierten Modus oder den Docker Socket.

Auch Informationspreisgabe reduziere ich: unnötige Server-Banner, exakte Versionsangaben, Patchlevel, Debugseiten, Stacktraces, Default-Seiten, Framework-Header oder offen zugängliche API-Dokumentation.

MITRE beschreibt System Information Discovery (T1082) als Sammlung von Betriebssystem-, Versions-, Patch- und Architekturinformationen, die Folgeaktivitäten beeinflussen können: https://attack.mitre.org/techniques/T1082/.

Aber ich halte die Priorität klar:

Eine Versionsnummer zu verstecken ist keine Alternative zum Patchen.

Security by obscurity allein schützt nicht. Informationsminimierung ist eine zusätzliche Schicht auf einem tatsächlich gepflegten System.

26. Meine kompakte Abschluss-Checkliste

Bevor ich einen neuen Ubuntu-Server als gehärtete Basis betrachte, möchte ich mindestens diese Fragen mit Ja beantworten können:

  • Ist die Serverrolle klar definiert und ist nur notwendige Software installiert?
  • Ist das System vollständig aktualisiert und ist der Updateprozess dauerhaft geregelt?
  • Sind unnötige Dienste deaktiviert und offene Ports inventarisiert?
  • Gilt eingehend ein Default-Deny-Prinzip?
  • Werden IPv4 und IPv6 gleichermaßen berücksichtigt?
  • Ist SSH auf notwendige Administratoren beschränkt?
  • Ist direkter Root-Login deaktiviert?
  • Sind SSH-Passwörter abgeschaltet, wenn die Umgebung vollständig mit Schlüsseln betrieben werden kann?
  • Sind private Schlüssel geschützt und gibt es einen Widerrufsprozess?
  • Kann SSH auf ein Managementnetz oder WireGuard beschränkt werden?
  • Existiert ein getesteter Break-Glass-/Konsolenzugang?
  • Sind lokale Accounts, sudo-Rechte und Service Accounts minimal?
  • Läuft AppArmor und werden Denials ausgewertet?
  • Sind lang laufende eigene Dienste mit systemd-Sandboxing geprüft?
  • Sind Kernel-/sysctl-Abweichungen dokumentiert und auf die Serverrolle abgestimmt?
  • Sind sensible Dateien, SUID/SGID-Binaries und Mount-Optionen geprüft?
  • Werden Authentifizierung, sudo, Security- und Serviceereignisse protokolliert?
  • Werden wichtige Logs zentral und möglichst manipulationsärmer gesammelt?
  • Ist Audit-Telemetrie dort aktiviert, wo sie einen konkreten Zweck erfüllt?
  • Ist die Systemzeit zuverlässig synchronisiert?
  • Gibt es Monitoring für Verfügbarkeit, Ressourcen, Updates, Zertifikate und Security-Signale?
  • Werden bekannte Schwachstellen regelmäßig gegen den tatsächlichen Ubuntu-Paketstand bewertet?
  • Existieren getrennte Backups und wurde ein Restore wirklich getestet?
  • Sind Secure Boot und Verschlüsselung entsprechend dem Threat Model bewertet?
  • Gibt es eine CIS-/Benchmark-Prüfung oder eine vergleichbare dokumentierte Baseline?
  • Werden Abweichungen und Ausnahmen begründet dokumentiert?
  • Werden Webserver, Datenbanken, Container und Anwendungen anschließend separat gehärtet?
  • Wird die externe Angriffsfläche nach Änderungen erneut geprüft?

Wenn eine dieser Fragen unbeantwortet bleibt, ist das für mich kein Grund, den Server nicht zu betreiben. Es ist aber ein sichtbarer offener Punkt, der bewusst bewertet werden muss.

Quellen und weiterführende Referenzen

Für diesen Beitrag habe ich bewusst Primärquellen und etablierte Security-Referenzen verwendet. Da Hardening versionsabhängig ist, prüfe ich diese Quellen bei späteren Ubuntu-/OpenSSH-/systemd-Versionen erneut.

Hardening bleibt für mich eine Abwägung zwischen Angriffsfläche, Funktion, Wartbarkeit und Wiederherstellbarkeit. Der beste Zustand ist nicht der Server mit den meisten gesetzten Security-Optionen, sondern der Server, dessen notwendige Funktion klar definiert, dessen Exposition minimal, dessen Rechte begrenzt, dessen Zustand beobachtbar und dessen Wiederherstellung beherrscht ist.

Tags