Wie sicher ist mein Server? Selbst-Audit mit Lynis
Lynis 3.1.7 auf Debian 13: Server auditieren, den Hardening-Index verstehen, Findings abarbeiten – und wissen, welche Vorschläge den Docker-Host zerlegen.
Inhaltsverzeichnis
Du hast SSH abgesichert, eine Firewall gesetzt, fail2ban laufen – und weißt trotzdem nicht, was du übersehen hast. Lynis beantwortet genau diese Frage: Es geht deinen Server von innen durch und sagt dir, was noch offen ist. Der schwierigere Teil kommt danach, nämlich zu entscheiden, welche der Vorschläge du wirklich umsetzt.
Was bauen wir?
Wir installieren Lynis 3.1.7 auf einem Debian 13 und lassen ein vollständiges Audit laufen. Aus dem Ergebnis – auf einem frischen netcup-Server mit Docker zunächst Hardening-Index 64, eine Warnung und 44 Vorschläge – arbeiten wir die Punkte ab, die tatsächlich etwas bringen, und lassen die anderen bewusst stehen. Am Ende steht ein reproduzierbarer Audit-Lauf per systemd-Timer, eine dokumentierte Ausnahmeliste und ein Index von 77.
Genauso wichtig ist, was wir nicht tun: Einer der Vorschläge nimmt jedem Container auf der Stelle das Netz, ein zweiter legt beim nächsten neuen Stack eine Zeitbombe, ein dritter beanstandet eine Einstellung, die bereits strenger ist als gefordert. Lynis kennt deinen Server nicht – du schon.
Voraussetzungen
- Ein abgesicherter Server mit Debian 13 und root- bzw. sudo-Zugang
- Grundverständnis für systemd-Units und Timer – für die Automatisierung am Ende
- Etwa eine Stunde Zeit; das erste Audit selbst dauert nur 1–2 Minuten
- Optional, aber praktisch: unattended-upgrades ist schon eingerichtet – dann fällt eines der Findings von selbst weg
VPS 1000 G12.5
4 vCore · 8 GB RAM · 128 GB SSD
ab 14,50 €/Monat
Lynis läuft auf jedem noch so kleinen Server – ein VPS 1000 reicht für Audit und Docker-Stack locker.
💶 1 Monat gratis:
Einmal einlösbar, gilt für VPS 1000 G12.5. Im Warenkorb einlösen →
💶 5,95 € Gutschein für netcup-Neukunden: immer gültig · nicht für Domains und VPS Lite
Schritt für Schritt
Schritt 1: Lynis aus dem CISOfy-Repository installieren
Debian bringt Lynis mit, aber in einer älteren Fassung:
apt-cache policy lynislynis:
Installed: (none)
Candidate: 3.1.4-1Das ist kein Schönheitsfehler. Lynis besteht fast vollständig aus Tests, und die veralten schneller als das Programm drumherum – neue Kernel-Parameter, neue Dienste, neue Standardwerte. Ein Audit mit einer alten Testsammlung übersieht genau die Dinge, die neu dazugekommen sind. Deshalb nehmen wir das Repository von CISOfy, den Lynis-Entwicklern.
Den Signaturschlüssel legen wir als ASCII-armored Datei (.asc) ab. Das ist der Trick, der dir
die Installation von gnupg erspart – apt kann Klartext-Schlüssel direkt lesen, wenn die Datei auf
.asc endet:
install -d -m 0755 /etc/apt/keyrings
curl -fsSL https://packages.cisofy.com/keys/cisofy-software-public.key \
-o /etc/apt/keyrings/cisofy.ascPrüfe kurz, dass wirklich ein Schlüssel angekommen ist und nicht eine Fehlerseite:
head -1 /etc/apt/keyrings/cisofy.asc-----BEGIN PGP PUBLIC KEY BLOCK-----Jetzt die Paketquelle eintragen. Das signed-by bindet die Quelle fest an genau diesen Schlüssel –
CISOfy darf damit nur Lynis-Pakete signieren, nicht dein halbes System ersetzen:
echo "deb [signed-by=/etc/apt/keyrings/cisofy.asc] https://packages.cisofy.com/community/lynis/deb/ stable main" \
> /etc/apt/sources.list.d/cisofy-lynis.list
apt-get update
apt-get install -y lynislynis --version3.1.7Hinweis
apt-cache policy lynis weiter nur 3.1.4 anbietet, hat apt-get update die neue Quelle nicht
eingelesen – meist wegen eines Tippfehlers im Dateinamen. Die Liste muss auf .list enden und in
/etc/apt/sources.list.d/ liegen.Schritt 2: Der erste Audit-Lauf
Lynis braucht keinen Dienst und keine Konfiguration. Einmal aufrufen genügt:
lynis audit system --quick --no-colors | tee /root/lynis-run1.txt--quick überspringt die Pausen, in denen Lynis sonst auf einen Tastendruck wartet – sonst
identisch zum normalen Lauf. --no-colors macht die Ausgabe kopierbar, tee hebt sie auf, damit du
später vergleichen kannst.
Nach ein bis zwei Minuten steht am Ende die Zusammenfassung:
Details:
Hardening index : 64 [############ ]
Tests performed : 251
Plugins enabled : 0Darüber stehen die eigentlichen Ergebnisse, getrennt in zwei Kategorien:
Warnings (1):
----------------------------
! Found one or more vulnerable packages. [PKGS-7392]
Suggestions (44):Der Unterschied ist wichtig. Eine Warning ist für Lynis ein Zustand, der jetzt falsch ist – ein ungepatchtes Paket, ein Dienst, der nicht tut, was er soll. Eine Suggestion ist eine Empfehlung, die je nach Einsatzzweck sinnvoll sein kann oder eben nicht. Warnungen schaust du dir immer an; Vorschläge sortierst du.
Der Hardening-Index ist dabei die am häufigsten missverstandene Zahl. Er ist kein Prozentwert für „Sicherheit", sondern ein simpler Punktequotient: Jeder Test vergibt erreichte und mögliche Punkte, am Ende wird geteilt. Ein Server ohne Webserver bekommt für nicht durchgeführte Webserver-Tests weder Punkte noch Maximum – ein Server mit Webserver kann also bei gleicher Sorgfalt schlechter dastehen. Vergleiche den Index nur mit dir selbst, nie mit anderen.
Schritt 3: Den Bericht lesen, nicht die Bildschirmausgabe
Die Konsolenausgabe ist die schlechteste der drei Informationsquellen. Zehn Zeilen „Consider hardening SSH configuration [SSH-7408]" untereinander sagen dir nicht, welche zehn Optionen gemeint sind. Die stehen im maschinenlesbaren Bericht:
grep "^suggestion\[\]=SSH-7408" /var/log/lynis-report.datsuggestion[]=SSH-7408|Consider hardening SSH configuration|AllowTcpForwarding (set YES to NO)|-|
suggestion[]=SSH-7408|Consider hardening SSH configuration|ClientAliveCountMax (set 3 to 2)|-|
suggestion[]=SSH-7408|Consider hardening SSH configuration|LogLevel (set INFO to VERBOSE)|-|
suggestion[]=SSH-7408|Consider hardening SSH configuration|MaxAuthTries (set 6 to 3)|-|
suggestion[]=SSH-7408|Consider hardening SSH configuration|MaxSessions (set 10 to 2)|-|
suggestion[]=SSH-7408|Consider hardening SSH configuration|PermitRootLogin (set YES to (FORCED-COMMANDS-ONLY|NO|PROHIBIT-PASSWORD|WITHOUT-PASSWORD))|-|
suggestion[]=SSH-7408|Consider hardening SSH configuration|Port (set 22 to )|-|
suggestion[]=SSH-7408|Consider hardening SSH configuration|TCPKeepAlive (set YES to NO)|-|
suggestion[]=SSH-7408|Consider hardening SSH configuration|X11Forwarding (set YES to NO)|-|
suggestion[]=SSH-7408|Consider hardening SSH configuration|AllowAgentForwarding (set YES to NO)|-|Das dritte Feld ist die konkrete Handlungsanweisung. Merke dir die drei Dateien:
/var/log/lynis-report.dat– Ergebnis als Schlüssel-Wert-Liste, ideal zum Greppen/var/log/lynis.log– das vollständige Protokoll inklusive der Begründung jedes Tests- die Bildschirmausgabe – nur zum Überfliegen
Was Lynis bei einem Test genau erwartet, steht im Log. Beispiel Kernel-Parameter:
grep "different value than expected" /var/log/lynis.log | sed "s/.*sysctl key //"dev.tty.ldisc_autoload has a different value than expected in scan profile. Expected=0, Real=1
fs.protected_fifos has a different value than expected in scan profile. Expected=2, Real=1
kernel.kptr_restrict has a different value than expected in scan profile. Expected=2, Real=0
kernel.modules_disabled has a different value than expected in scan profile. Expected=1, Real=0
kernel.sysrq has a different value than expected in scan profile. Expected=0, Real=438
kernel.unprivileged_bpf_disabled has a different value than expected in scan profile. Expected=1, Real=2
kernel.yama.ptrace_scope has a different value than expected in scan profile. Expected=1 2 3, Real=0
net.core.bpf_jit_harden has a different value than expected in scan profile. Expected=2, Real=0
net.ipv4.conf.all.forwarding has a different value than expected in scan profile. Expected=0, Real=1
net.ipv4.conf.all.log_martians has a different value than expected in scan profile. Expected=1, Real=0
net.ipv4.conf.all.rp_filter has a different value than expected in scan profile. Expected=1, Real=0
net.ipv4.conf.all.send_redirects has a different value than expected in scan profile. Expected=0, Real=1
net.ipv4.conf.default.accept_redirects has a different value than expected in scan profile. Expected=0, Real=1
net.ipv4.conf.default.log_martians has a different value than expected in scan profile. Expected=1, Real=0
net.ipv6.conf.all.accept_redirects has a different value than expected in scan profile. Expected=0, Real=1
net.ipv6.conf.default.accept_redirects has a different value than expected in scan profile. Expected=0, Real=1Sechzehn Abweichungen – und drei davon darfst du auf keinen Fall übernehmen. Dazu gleich mehr.
Schritt 4: Die Findings abarbeiten, die etwas bringen
Pakete aktualisieren (PKGS-7392)
Die erste Warnung ist die banalste und die wichtigste. Lynis vergleicht die installierten Pakete mit den verfügbaren Sicherheitsupdates:
apt list --upgradable
apt-get -y upgradeWenn das bei dir regelmäßig auftaucht, ist nicht Lynis das Problem, sondern der fehlende Automatismus – dafür gibt es unattended-upgrades.
SSH nachziehen (SSH-7408)
Statt /etc/ssh/sshd_config anzufassen, legen wir eine Drop-in-Datei an. Debian 13 lädt alles aus
/etc/ssh/sshd_config.d/, und bei einem Paketupdate bleibt deine Änderung so unangetastet:
cat > /etc/ssh/sshd_config.d/99-hardening.conf <<'EOF'
LogLevel VERBOSE
MaxAuthTries 3
MaxSessions 2
TCPKeepAlive no
X11Forwarding no
AllowAgentForwarding no
EOFLogLevel VERBOSE protokolliert zusätzlich den Fingerprint des verwendeten Schlüssels – genau die
Information, die du bei einem Vorfall brauchst. MaxAuthTries 3 begrenzt Fehlversuche pro
Verbindung, AllowAgentForwarding no verhindert, dass jemand mit Root auf dem Server deinen
lokalen SSH-Agent mitbenutzt.
Achtung
sshd -t prüft die Konfiguration, ohne den Dienst anzufassen. Ein
Tippfehler plus blindes restart sperrt dich aus – und ein zweites Terminal aufzumachen hilft nur,
solange es schon offen ist.sshd -t && systemctl reload ssh
sshd -T | grep -E "^(maxauthtries|maxsessions|x11forwarding|loglevel)"maxauthtries 3
maxsessions 2
x11forwarding no
loglevel VERBOSEDie beiden schärfsten Punkte aus der Liste – PermitRootLogin und PasswordAuthentication –
stehen hier bewusst nicht drin. Die setzt du erst, wenn ein funktionierender SSH-Schlüssel liegt,
und genau das macht das Tutorial SSH absichern Schritt für Schritt.
Wenn du es durchgearbeitet hast, ist SSH-7408 bei dir von vornherein kürzer.
Kernel-Parameter – hier lauert die Docker-Falle
Von den sechzehn abweichenden sysctl-Werten übernehmen wir dreizehn:
# /etc/sysctl.d/99-lynis.conf
dev.tty.ldisc_autoload = 0
fs.protected_fifos = 2
kernel.kptr_restrict = 2
kernel.sysrq = 0
kernel.yama.ptrace_scope = 1
net.core.bpf_jit_harden = 2
net.ipv4.conf.all.log_martians = 1
net.ipv4.conf.default.log_martians = 1
net.ipv4.conf.all.rp_filter = 1
net.ipv4.conf.all.send_redirects = 0
net.ipv4.conf.default.accept_redirects = 0
net.ipv6.conf.all.accept_redirects = 0
net.ipv6.conf.default.accept_redirects = 0Die letzten vier betreffen ICMP-Redirects – Hinweise eines Routers, ein Paket doch besser über einen anderen Weg zu schicken. Ein Server mit fester Standardroute braucht sie weder zu senden noch anzunehmen, und Docker-Container kommen ohne sie über IPv4 wie IPv6 ins Netz.
sysctl -p /etc/sysctl.d/99-lynis.confDrei Werte fehlen in der Datei, und das ist Absicht:
net.ipv4.conf.all.forwarding = 0– Lynis will IP-Forwarding abschalten. Docker braucht es, um Pakete zwischen Containernetz und Außenwelt zu routen. Setzt du das auf 0, hat kein einziger Container mehr Netz. Wenn du wissen willst, warum, hilft Docker-Netzwerke verstehen.kernel.modules_disabled = 1– verbietet dem Kernel, weitere Module zu laden. Docker lädt je nach Stackoverlay,br_netfilterodernf_tablesbei Bedarf nach. Auf einem Container-Host ist das eine Zeitbombe, die beim nächsten neuen Stack hochgeht.kernel.unprivileged_bpf_disabled = 1– hier ist Lynis schlicht zu eng. Debian 13 steht auf2, und das ist die strengere Einstellung: BPF für unprivilegierte Nutzer ist aus und lässt sich zur Laufzeit nicht wieder einschalten. Lynis prüft auf exakte Gleichheit und meckert deswegen über eine Verbesserung.
Prüfe nach dem Anwenden, dass die Container noch reden können – rp_filter ist der Wert, der am
ehesten Ärger macht:
docker run --rm alpine:3.22 sh -c "wget -qO- -T5 https://example.com >/dev/null && echo NET-OK"NET-OKPasswort-Richtlinien und umask (AUTH-9286, AUTH-9328)
sed -i 's/^PASS_MAX_DAYS.*/PASS_MAX_DAYS\t365/; s/^PASS_MIN_DAYS.*/PASS_MIN_DAYS\t1/' /etc/login.defs
grep -q "^UMASK" /etc/login.defs || printf 'UMASK\t\t027\n' >> /etc/login.defsUMASK 027 sorgt dafür, dass neu angelegte Dateien nicht mehr für alle lesbar sind. Das ist
sinnvoll – hat aber eine Nebenwirkung, die dich beim nächsten Konfigurationsschritt einholt, siehe
„Wenn es nicht funktioniert".
Nicht übernommen haben wir AUTH-9229 und AUTH-9230, die SHA_CRYPT_MIN_ROUNDS in
/etc/login.defs verlangen. Debian 13 hasht Passwörter mit yescrypt:
grep ^ENCRYPT_METHOD /etc/login.defsENCRYPT_METHOD YESCRYPTDie SHA_CRYPT_*-Werte gelten ausschließlich für SHA-512-Hashes. Sie hier einzutragen würde die
Lynis-Meldung zum Verschwinden bringen, ohne irgendetwas zu ändern – die klassische
Scheinverbesserung. Der Test schaut wirklich nur nach diesen beiden Zeilen und ignoriert
ENCRYPT_METHOD komplett.
Ungenutzte Kernel-Module sperren (USB-1000, STRG-1846, NETW-3200)
Ein VPS braucht weder USB-Speicher noch FireWire noch die Netzwerkprotokolle DCCP, SCTP, RDS oder TIPC. Jedes geladene Modul ist Angriffsfläche:
cat > /etc/modprobe.d/99-lynis-blacklist.conf <<'EOF'
install usb-storage /bin/true
install firewire-core /bin/true
install firewire_ohci /bin/true
install ohci1394 /bin/true
install dccp /bin/true
install sctp /bin/true
install rds /bin/true
install tipc /bin/true
EOFinstall <modul> /bin/true ist stärker als blacklist: blacklist verhindert nur das automatische
Laden, ein modprobe von Hand geht trotzdem. Prüfe das Ergebnis im Trockenlauf:
modprobe -n -v sctpinstall /bin/trueEin Banner, das Lynis zählen kann (BANN-7126, BANN-7130)
Lynis sucht in /etc/issue nach juristischen Reizwörtern und will mindestens fünf davon finden –
aus einer fest eingebauten englischen Liste (authori, monitor, log, legal, prohibited,
access, system …). Ein rein deutscher Text besteht den Test nicht, egal wie deutlich er ist.
Deshalb zweisprachig:
cat > /etc/issue <<'EOF'
Zugriff nur für autorisierte Nutzer. Alle Zugriffe werden protokolliert.
Authorized access only. All connections to this system are monitored and
logged. Unauthorized use is prohibited and may be prosecuted by law.
EOF
cp /etc/issue /etc/issue.net/etc/issue sieht man an der lokalen Konsole, /etc/issue.net zeigt SSH vor dem Login an. Letzteres
passiert allerdings nur, wenn du es sshd auch sagst – ab Werk steht das Banner auf none:
echo "Banner /etc/issue.net" >> /etc/ssh/sshd_config.d/99-hardening.conf
sshd -t && systemctl reload ssh
sshd -T | grep -i "^banner"banner /etc/issue.netPaketintegrität und Audit-Protokoll (PKGS-7370, ACCT-9622, ACCT-9628)
apt-get install -y debsums apt-show-versions acct auditddebsums vergleicht die Prüfsummen installierter Dateien mit denen aus dem Paket – damit fällt auf,
wenn jemand /usr/bin/ssh ausgetauscht hat. Lynis will zusätzlich, dass die Prüfung regelmäßig
läuft:
sed -i 's/^CRON_CHECK=.*/CRON_CHECK=weekly/' /etc/default/debsumsauditd protokolliert Kernel-Ereignisse. Frisch installiert hat es allerdings kein einziges
Regelwerk – und Lynis quittiert das prompt mit einem neuen Finding, das vorher nicht da war:
* Audit daemon is enabled with an empty ruleset. Disable the daemon or define rules [ACCT-9630]Das ist kein Fehler, sondern korrekt: ein Audit-Daemon ohne Regeln kostet Ressourcen und liefert nichts. Ein kleines, sinnvolles Regelwerk für einen Docker-Host:
cat > /etc/audit/rules.d/99-serverkueche.rules <<'EOF'
-w /etc/passwd -p wa -k identity
-w /etc/shadow -p wa -k identity
-w /etc/group -p wa -k identity
-w /etc/sudoers -p wa -k privileged
-w /etc/sudoers.d/ -p wa -k privileged
-w /etc/ssh/sshd_config -p wa -k sshd
-w /etc/ssh/sshd_config.d/ -p wa -k sshd
-w /var/log/lastlog -p wa -k logins
-w /usr/bin/docker -p x -k docker
EOF
augenrules --load
auditctl -l-p wa heißt „bei Schreib- und Attributänderung", -k setzt ein Stichwort, nach dem du später
suchst: ausearch -k sshd. Die letzte Regel protokolliert jeden docker-Aufruf – auf einem Server,
auf dem Docker-Zugriff faktisch Root-Zugriff bedeutet, ist das die interessanteste Zeile.
Die Zeit-Warnung, die früher oder später kommt (TIME-3185)
Eine zweite Warnung taucht auf fast jedem Server irgendwann auf und sieht nach einem echten Problem aus, ist aber keins:
timedatectl timesync-status | grep -E "Poll|Offset"Poll interval: 34min 8s (min: 32s; max 34min 8s)
Offset: +1.462msDie Uhr geht 1,5 Millisekunden falsch – sie ist perfekt synchron. Lynis misst aber das Alter der
Datei /run/systemd/timesync/synchronized und warnt ab 2048 Sekunden. Genau 2048 Sekunden ist
auch das Standard-Maximum, auf das systemd-timesyncd sein Abfrageintervall hochzieht, wenn die Uhr
stabil läuft. Der Test schlägt also auf jedem gut laufenden System zwangsläufig irgendwann an.
Statt die Warnung zu ignorieren, drücken wir das Intervall knapp darunter. Dann bedeutet ein Anschlagen dieses Tests wieder etwas:
# /etc/systemd/timesyncd.conf.d/99-lynis.conf
[Time]
PollIntervalMaxSec=1024chmod 0644 /etc/systemd/timesyncd.conf.d/99-lynis.conf
systemctl restart systemd-timesyncd
timedatectl timesync-status | grep PollPoll interval: 1min 4s (min: 32s; max 17min 4s)Das chmod ist kein Schreibfehler – warum es nötig ist, steht weiter unten.
Schritt 5: Nachmessen
lynis audit system --quick --no-colors | tee /root/lynis-run2.txt
grep -E "Hardening index|Tests performed" /root/lynis-run2.txt Hardening index : 77 [############### ]
Tests performed : 254Von 64 auf 77, und der Abschnitt Warnings fehlt jetzt komplett – bei null Warnungen lässt Lynis
ihn einfach weg. Die Vorschläge sind von 44 auf 22 geschrumpft.
Schritt 6: Bewusste Ausnahmen in custom.prf
Was übrig bleibt, sind Vorschläge, die du bei jedem Lauf wieder liest und jedes Mal wieder
verwirfst. Genau dafür gibt es /etc/lynis/custom.prf. Wichtig: jede Zeile bekommt eine
Begründung, sonst weißt du in einem halben Jahr nicht mehr, ob das eine Entscheidung war oder
Bequemlichkeit.
# /etc/lynis/custom.prf
# FILE-6310: eigene Partitionen für /home und /var. Ein VPS hat eine Disk;
# nachträglich partitionieren wäre hier mehr Risiko als Gewinn.
skip-test=FILE-6310
# AUTH-9229/9230: verlangen SHA_CRYPT_*_ROUNDS. Debian 13 nutzt yescrypt,
# die Werte hätten keinerlei Wirkung.
skip-test=AUTH-9229
skip-test=AUTH-9230
# BOOT-5122: GRUB-Passwort. Wer über die netcup-VNC-Konsole kommt, hat ohnehin
# Zugriff auf das Serverpanel und damit auf Snapshots und Rescue-System.
skip-test=BOOT-5122Der nächste Lauf ist danach deutlich ruhiger – aber der Index bewegt sich nicht:
Hardening index : 77 [############### ]
Tests performed : 250
Suggestions (17):Das ist kein Fehler, sondern der Beweis, dass die Zahl sich nicht schönrechnen lässt: Ein
übersprungener Test nimmt seine erreichten und seine möglichen Punkte aus der Rechnung. Von 22
auf 17 Vorschläge, vier Tests weniger – Index unverändert 77. custom.prf ist ein Werkzeug gegen
Rauschen, kein Werkzeug für den Punktestand.
Achtung
skip-test schaltet den Test dauerhaft ab – auch dann noch, wenn sich die Lage ändert. Nimm die
Liste bei jedem Quartals-Audit einmal durch und frag dich, ob die Begründung noch stimmt. Was du nur
diesmal nicht sehen willst, gehört nicht hier hinein.Zwei Vorschläge lassen wir bewusst sichtbar stehen, statt sie wegzuschalten: HRDN-7230
(Malware-Scanner) und LOGG-2154 (zentrales Logging). Beides ist auf einem einzelnen kleinen VPS
schwer zu rechtfertigen – ClamAV allein zieht sich rund ein Gigabyte RAM für die Signaturdatenbank –
aber sobald ein zweiter Server dazukommt, ändert sich die Rechnung. Ein Vorschlag, den du jedes Mal
wieder liest und wieder ablehnst, ist eine Erinnerung; ein weggeschalteter ist vergessen.
Schritt 7: Das Audit automatisieren
Ein einmaliges Audit ist eine Momentaufnahme. Interessant wird es, wenn du den Verlauf siehst – besonders nach jedem neuen Stack, den du deployst. Lynis bringt dafür einen eigenen Modus mit:
# /etc/systemd/system/lynis-audit.service
[Unit]
Description=Lynis Sicherheits-Audit
[Service]
Type=oneshot
ExecStart=/usr/sbin/lynis audit system --cronjob --quiet--cronjob schaltet Farben und Rückfragen ab, --quiet unterdrückt alles außer Warnungen. Der
Timer daneben:
# /etc/systemd/system/lynis-audit.timer
[Unit]
Description=Monatliches Lynis-Audit
[Timer]
OnCalendar=monthly
RandomizedDelaySec=1h
Persistent=true
[Install]
WantedBy=timers.targetPersistent=true holt einen verpassten Lauf nach, wenn der Server zum Termin aus war.
systemctl daemon-reload
systemctl enable --now lynis-audit.timer
systemctl list-timers lynis-audit.timerDen Index eines Laufs holst du dir danach mit einer Zeile aus dem Bericht – das ist die Zahl, die du über die Monate beobachtest:
grep ^hardening_index= /var/log/lynis-report.dathardening_index=77Wenn du dir das Ergebnis aufs Handy schicken lassen willst, hängst du eine
ExecStartPost-Zeile mit ntfy an den Service.
Wenn es nicht funktioniert
Nach dem Setzen von UMASK 027 startet ein Dienst nicht mehr und meldet „Permission denied" auf seine eigene Konfigurationsdatei. Die neue umask gilt ab der nächsten Anmeldung, und alles, was du danach mit > oder cat > anlegst, bekommt Modus 0640 statt 0644. Dienste, die unter einem eigenen Benutzer laufen – systemd-timesyncd etwa nutzt DynamicUser –, dürfen die Datei dann nicht mehr lesen. Im Journal steht Failed to open ...: Permission denied. Setz die Rechte für Konfigurationsdateien, die nicht root gehören, explizit: chmod 0644 /etc/systemd/timesyncd.conf.d/99-lynis.conf.
Nach dem Anwenden der sysctl-Werte haben alle Container kein Netz mehr. Dann ist net.ipv4.conf.all.forwarding auf 0 gelandet. Lynis schlägt das vor, Docker kann ohne IP-Forwarding aber keine Pakete zwischen Containernetz und Außenwelt weiterreichen. Nimm die Zeile aus /etc/sysctl.d/99-lynis.conf heraus und setz den Wert mit sysctl -w net.ipv4.conf.all.forwarding=1 sofort zurück – ein Neustart von Docker allein hilft nicht.
systemd-timesyncd did not synchronized the time recently bleibt stehen, obwohl timedatectl NTPSynchronized=yes meldet. Lynis prüft nicht die Uhr, sondern das Alter von /run/systemd/timesync/synchronized, und warnt ab 2048 Sekunden. Da systemd sein Abfrageintervall bei stabiler Uhr genau auf 2048 Sekunden hochzieht, läuft der Test zwangsläufig in die Warnung. Entweder du senkst PollIntervalMaxSec wie in Schritt 4 oder du nimmst den Test in custom.prf auf – ignorieren solltest du ihn nicht, denn dann übersiehst du den Tag, an dem die Zeitsynchronisation wirklich hängt.
Lynis meldet Consider hardening SSH configuration zehnmal und sagt nicht, was gemeint ist. Die Bildschirmausgabe kürzt die Details weg. Sie stehen im dritten Feld von grep "^suggestion\[\]=SSH-7408" /var/log/lynis-report.dat – dort findest du für jede Zeile den Parameter und den Zielwert.
Nach der Installation von auditd ist ein Finding dazugekommen statt weg. ACCT-9630 meldet einen laufenden Audit-Daemon mit leerem Regelwerk. Das ist beabsichtigt: auditd ohne Regeln verbraucht Ressourcen, ohne etwas zu protokollieren. Leg Regeln unter /etc/audit/rules.d/ ab und lade sie mit augenrules --load – oder deinstalliere auditd wieder, wenn du das Protokoll nicht auswertest.
Dein Problem ist nicht dabei? Alle Fehlermeldungen durchsuchen →
Wartung & Backups
Lynis selbst aktualisiert sich über apt mit; durch das CISOfy-Repository bekommst du neue Testsammlungen zeitnah. Prüfe nach einem Major-Update kurz, ob plötzlich neue Findings auftauchen – das sind meist neue Tests, keine neuen Probleme auf deinem Server.
Realistischer Aufwand: Das erste Audit samt Abarbeiten kostet dich einen Abend. Danach sind es
etwa 20 Minuten pro Quartal – Bericht überfliegen, neue Findings einsortieren, custom.prf
gegenlesen. Der monatliche Timer läuft ohne dich; du schaust nur hin, wenn sich der Index bewegt.
Sichere die Ergebnisse deiner Arbeit mit. Die eigentlichen Werte stecken nicht in Lynis, sondern in den Dateien, die du angelegt hast. Nimm sie in dein Restic-Backup auf:
/etc/lynis/custom.prf
/etc/sysctl.d/99-lynis.conf
/etc/modprobe.d/99-lynis-blacklist.conf
/etc/ssh/sshd_config.d/99-hardening.conf
/etc/audit/rules.d/
/etc/systemd/system/lynis-audit.{service,timer}Nach jedem größeren Umbau – neuer Reverse-Proxy, neue Datenbank, neuer offener Port – lohnt ein Lauf von Hand. Genau dann entstehen die Lücken, die ein Monatstimer erst Wochen später findet.
Was Lynis nicht ist
Feedback per E-Mail: feedback@serverkueche.de
Das könnte dir auch schmecken


