Zum Hauptinhalt springen
S-EDV news
← Alle Anleitungen
📘 Anleitung Sicherheit & Datenschutz 05.11.2026 · 8 min Lesezeit

Täglicher Sicherheitsbericht: Lynis-Härtung und Meldung per ntfy

Teil 18 der Reihe Server im Netz: Lynis prüft den VPS, die sinnvollen Vorschläge heben den Härtungsindex von 60 auf 74, zwei gefährliche für Docker-Hosts bleiben außen vor. Ein systemd-Timer schickt jeden Morgen Index, Updates und Zertifikate per ntfy.

Geprüft am 05.11.2026 · für Lynis 3.1.7, ntfy 2.37.2, Ubuntu 24.04

Mit KI erstellt – redaktionelle Prüfung ausstehend

WerbelinksMit * markierte Links sind Werbelinks: Bei einem Kauf erhalten wir eine Provision, der Preis bleibt gleich. Als Amazon-Partner verdiene ich an qualifizierten Verkäufen. Mehr dazu

Symbolbild: Server mit leuchtendem Kabel zur Weltkarte, Titel Täglicher Sicherheitsbericht

Ein Server wird nicht einmal abgesichert und ist dann fertig. Updates kommen, Zertifikate laufen ab, neue Dienste ändern die Lage. Lynis prüft ein Linux-System in wenigen Minuten auf hunderte bekannte Schwachstellen und Einstellungen und fasst das Ergebnis in einem Härtungsindex zusammen. Diese Anleitung lässt Lynis auf dem Server der Reihe laufen, setzt die sinnvollen Vorschläge um, zeigt zwei Vorschläge, die einen Docker-Host kaputtmachen würden, und schickt jeden Morgen einen kurzen Bericht mit Index, Updates und Zertifikaten aufs Telefon.

Dies ist Teil 18 der Reihe „Server im Netz“. Als Beispiel dient ein netcup-VPS mit Ubuntu und Docker, auf dem mehrere Dienste hinter Caddy laufen und ntfy aus Teil 10 Nachrichten zustellt.

Voraussetzungen

  • Ein Linux-Server mit root-Zugang, im Beispiel Ubuntu mit Docker
  • Git zum Holen von Lynis
  • Für den Bericht ntfy wie in Teil 10, mit einem Token, das ins Thema schreiben darf

Schritt 1: Lynis holen und erste Prüfung

Das Ubuntu-Paket liegt auf dem Testserver in Version 3.0.9 vor. Aktueller ist die Version aus dem Repository des Herstellers, sie läuft ohne Installation:

cd /opt
git clone --depth 1 --branch 3.1.7 https://github.com/CISOfy/lynis.git
cd lynis
./lynis show version
./lynis audit system --quick

--quick lässt die Pausen zwischen den Abschnitten weg. Die Prüfung dauerte auf dem Testserver gut eine Minute und lief 282 Tests. Das Ergebnis steht in /var/log/lynis-report.dat, das ausführliche Protokoll in /var/log/lynis.log.

grep -E "^hardening_index|^warning\[\]" /var/log/lynis-report.dat
grep "^suggestion\[\]" /var/log/lynis-report.dat | cut -d'|' -f1,2 | sort | uniq -c | sort -rn

Die erste Prüfung ergab den Index 60 mit drei Warnungen: veraltete Pakete mit bekannten Lücken, eine Netzwerkkarte im Promiscuous-Modus und ein Mailserver, der im Begrüßungstext seine Software verrät. Die Netzwerkkarte war kein Angriff, sondern unser Mitschnitt aus Teil 1: tcpdump schaltet die Karte standardmäßig in diesen Modus, mit -p unterbleibt das. Genau so etwas soll Lynis finden: Was man nicht selbst eingeschaltet hat, wäre ein Alarmzeichen.

Verifizieren: grep ^hardening_index /var/log/lynis-report.dat zeigt eine Zahl zwischen 0 und 100.

Schritt 2: Updates und Prüfwerkzeuge

Die Warnung zu verwundbaren Paketen nannte unter anderem apt und python3-twisted. Ein Update behebt das. Zusätzlich installieren wir zwei Werkzeuge, die Lynis vorschlägt:

apt-get update && apt-get upgrade -y
apt-get install -y apt-show-versions debsums
apt list --upgradable

Das Update dauerte 33 Sekunden und brachte auch eine neue Docker-Version, dabei starteten die Container kurz neu. Ein Paket blieb danach als aktualisierbar stehen. apt-cache policy zeigte dazu „gestaffelt 40%“: Ubuntu verteilt manche Updates in Stufen, nicht jeder Server bekommt sie am selben Tag. unattended-upgrades war auf dem Server schon aktiv, es spielt Sicherheitsupdates automatisch ein.

Verifizieren: ls /var/run/reboot-required zeigt die Datei nur, wenn ein Neustart nötig ist. Auf dem Testserver fehlte sie.

Schritt 3: Kernel-Einstellungen mit Bedacht

Lynis vergleicht viele sysctl-Werte mit einem Profil. Die Liste der Abweichungen steht im Protokoll:

grep "sysctl key .* different value" /var/log/lynis.log

Auf einem Docker-Host dürfen Sie hier nicht alles übernehmen. Zwei Vorschläge vertragen sich nicht mit Docker: net.ipv4.conf.all.forwarding=0 schaltet die Weiterleitung ab, über die Container ins Netz gehen. kernel.modules_disabled=1 verhindert bis zum nächsten Neustart jedes Nachladen von Kernelmodulen, die Docker etwa für neue Netze oder Firewallregeln braucht. rp_filter steht auf dem Testserver auf 2, also locker. Den strengen Wert 1 haben wir nicht gesetzt, weil er auf Hosts mit mehreren Netzen und Docker-Bridges Antworten verwerfen kann. Der Rest kommt in eine eigene Datei:

# /etc/sysctl.d/90-sedv-haertung.conf
dev.tty.ldisc_autoload = 0
fs.protected_fifos = 2
fs.suid_dumpable = 0
kernel.core_uses_pid = 1
kernel.kptr_restrict = 2
kernel.sysrq = 0
net.core.bpf_jit_harden = 2
net.ipv4.conf.all.log_martians = 1
net.ipv4.conf.default.log_martians = 1
net.ipv4.conf.all.send_redirects = 0
net.ipv4.conf.default.accept_redirects = 0
net.ipv4.conf.default.accept_source_route = 0
net.ipv6.conf.all.accept_redirects = 0
net.ipv6.conf.default.accept_redirects = 0
sysctl --system

Dazu kommen vier Netzwerkprotokolle, die ein Webserver nicht braucht und die Lynis als unnötig meldet:

# /etc/modprobe.d/sedv-protokolle.conf
install dccp /bin/false
install sctp /bin/false
install rds /bin/false
install tipc /bin/false

Verifizieren: sysctl kernel.kptr_restrict zeigt 2, und nach den Änderungen liefen alle Container und Websites weiter.

Schritt 4: SSH nachschärfen

Teil 2 hat SSH schon auf Schlüssel und einen eigenen Port umgestellt. Lynis schlug noch weitere Werte vor. Umgesetzt haben wir diese, in der Datei aus Teil 2:

# /etc/ssh/sshd_config.d/10-sedv.conf (Ergänzung)
LogLevel VERBOSE
ClientAliveInterval 300
ClientAliveCountMax 2
MaxSessions 4

Den Vorschlag AllowTcpForwarding no haben wir nicht übernommen. Über SSH-Tunnel erreichen wir in dieser Reihe die Oberflächen, die nur auf 127.0.0.1 lauschen, etwa das Dashboard von frps in Teil 8 oder AdGuard Home in Teil 9. Für Ihren Server entscheiden Sie das genauso: Wer keine Tunnel braucht, schaltet sie ab.

sshd -t && systemctl reload ssh

Verifizieren: sshd -T | grep -E "loglevel|maxsessions" zeigt loglevel VERBOSE und maxsessions 4.

Schritt 5: Was der Index danach sagt

Grafik: Lynis-Härtungsindex vor und nach den Maßnahmen
Eigene Messung: Härtungsindex von Lynis auf dem Testserver vor und nach den Maßnahmen aus Teil 2 und dieser Anleitung.

Der Index stieg von 60 auf 74, die Zahl der Vorschläge sank von 44 auf 33. Die meisten übrigen Vorschläge sind auf einem VPS nicht sinnvoll oder nicht möglich: eigene Partitionen für /var und /tmp, ein Passwort für GRUB, das Abschalten von USB-Speicher. Andere sind echte Arbeit für später, etwa auditd oder eine Prüfung der Dateiintegrität. Der Index ist eine Orientierung, kein Ziel: 100 erreicht kein Server, der noch etwas tun soll.

Verifizieren: Ein erneuter Lauf mit ./lynis audit system --quick zeigt den neuen Index am Ende der Ausgabe.

Schritt 6: Der tägliche Bericht

Ein kleines Skript führt Lynis aus, liest Index und Warnungen, zählt offene Updates, prüft die Restlaufzeit der Zertifikate und schickt das Ergebnis an ntfy. Die Zugangsdaten liegen in /etc/sicherheitsbericht.env mit chmod 600:

NTFY_URL=https://ntfy.sedv-lab.de/homelab
NTFY_TOKEN=tk_…
DOMAINS="sedv-lab.de git.sedv-lab.de status.sedv-lab.de"
#!/bin/sh
set -u
. /etc/sicherheitsbericht.env
cd /opt/lynis && ./lynis audit system --quick --cronjob >/dev/null 2>&1
R=/var/log/lynis-report.dat
IDX=$(grep -m1 '^hardening_index=' $R | cut -d= -f2)
WARN=$(grep -c '^warning\[\]' $R)
WTXT=$(grep '^warning\[\]' $R | cut -d'|' -f1,2 | sed 's/warning\[\]=//' | head -3)
UPD=$(apt list --upgradable 2>/dev/null | tail -n +2 | wc -l)
NEU=""; [ -f /var/run/reboot-required ] && NEU="Neustart nötig"
ZERT=""; MIN=999; FEHLER=0
for d in $DOMAINS; do
  END=$(echo | timeout 10 openssl s_client -connect "$d:443" -servername "$d" 2>/dev/null | openssl x509 -noout -enddate 2>/dev/null | cut -d= -f2)
  [ -n "$END" ] || { ZERT="$ZERT $d:FEHLER"; FEHLER=1; continue; }
  T=$(( ( $(date -d "$END" +%s) - $(date +%s) ) / 86400 )); [ $T -lt $MIN ] && MIN=$T
  [ $T -lt 21 ] && ZERT="$ZERT $d:${T}d"
done
PRIO=3; [ "$WARN" -gt 1 ] || [ "$UPD" -gt 10 ] || [ $MIN -lt 14 ] || [ $FEHLER -eq 1 ] && PRIO=4
MSG="Lynis-Index $IDX, Warnungen $WARN
$WTXT
Offene Updates: $UPD $NEU
Kürzeste Zertifikatslaufzeit: $MIN Tage${ZERT:+, knapp:$ZERT}"
curl -sf -H "Authorization: Bearer $NTFY_TOKEN" -H "Title: Sicherheitsbericht $(hostname -s)" \
  -H "Priority: $PRIO" -H "Tags: shield" -d "$MSG" "$NTFY_URL"

Gespeichert als /usr/local/bin/sicherheitsbericht mit chmod 755. Statt Cron nehmen wir einen systemd-Timer, weil Persistent=true einen verpassten Lauf nach einem Neustart nachholt:

# /etc/systemd/system/sicherheitsbericht.service
[Unit]
Description=Täglicher Sicherheitsbericht per ntfy
After=network-online.target
Wants=network-online.target
[Service]
Type=oneshot
ExecStart=/usr/local/bin/sicherheitsbericht

# /etc/systemd/system/sicherheitsbericht.timer
[Unit]
Description=Sicherheitsbericht jeden Morgen
[Timer]
OnCalendar=*-*-* 06:30:00
RandomizedDelaySec=10m
Persistent=true
[Install]
WantedBy=timers.target
systemctl daemon-reload
systemctl enable --now sicherheitsbericht.timer
systemctl start sicherheitsbericht.service

Der Testlauf dauerte 66 Sekunden, fast die ganze Zeit brauchte Lynis. Die Nachricht kam beim Abo an:

Darstellung der Nachricht des Sicherheitsberichts beim ntfy-Abo
Nachricht des Sicherheitsberichts beim Abo von ntfy, nachgesetzt aus dem Test. Servername ersetzt.

Die Priorität steigt auf 4, wenn mehr als eine Warnung, mehr als zehn offene Updates, ein Zertifikat mit weniger als 14 Tagen Laufzeit oder ein nicht erreichbarer Name dabei sind. Die App vibriert dann länger und zeigt die Nachricht als Pop-up.

Verifizieren: systemctl list-timers sicherheitsbericht.timer zeigt den nächsten Lauf am folgenden Morgen.

Typische Fehler

BeobachtungUrsache und Lösung
Container haben nach sysctl-Änderungen kein Netz mehrnet.ipv4.conf.all.forwarding=0 übernommen. Wieder auf 1 setzen, Docker braucht die Weiterleitung.
Warnung „promiscuous interface“Ein Mitschnitt oder ein anderes Werkzeug lauscht auf allen Paketen. Prüfen, ob das gewollt ist.
SSH-Tunnel gehen nicht mehrAllowTcpForwarding no gesetzt. Nur abschalten, wenn niemand Tunnel braucht.
Bericht kommt nicht anToken ohne Schreibrecht auf das Thema oder Server nicht erreichbar. Mit curl -sf endet das Skript dann mit Fehler, und systemctl status sicherheitsbericht.service zeigt ihn.

Häufige Fragen

Wie hoch sollte der Index sein?

Es gibt keinen Sollwert. Wichtiger als die Zahl ist, dass sie nicht sinkt und dass neue Warnungen auffallen. Dafür ist der tägliche Bericht da.

Ist das Paket aus Ubuntu nicht einfacher?

Es ist bequemer, aber älter. Neue Prüfungen und Korrekturen kommen nur mit neuen Versionen. Holen Sie Lynis gelegentlich mit einem neuen git clone des aktuellen Tags auf den aktuellen Stand. Ein git pull funktioniert nach dem Klonen eines Tags nicht.

Reicht Lynis als Schutz?

Lynis prüft Einstellungen, es schützt nicht. Firewall, Updates, Anmeldung mit Schlüssel und eine Überwachung wie in den anderen Teilen der Reihe machen die eigentliche Arbeit. Lynis zeigt, wo noch Lücken sind.

Fazit

Mit Lynis bekommt ein Server in wenigen Minuten eine ehrliche Bestandsaufnahme. Auf dem Testserver stieg der Index von 60 auf 74, ohne dass ein Dienst dauerhaft ausfiel. Lesen Sie die Vorschläge aber kritisch: Auf einem Docker-Host würden zwei davon alles lahmlegen. Der tägliche Bericht sorgt dafür, dass der Stand nicht unbemerkt schlechter wird.

Weiterführende Anleitungen und Quellen

Server im NetzLynisHärtungSicherheitntfysystemdLinux