- security-updates/auto-update: Das Ubuntu-Image bringt 20auto-upgrades und 10periodic selbst mit. Abwaehlen loeschte sie und schaltete damit die automatischen Sicherheitsupdates der Distro ab. Jetzt wird dort der Auslieferungszustand wiederhergestellt; auf Mint/Debian wie bisher entfernt. - zeitserver: Abwaehlen trug auf jedem Geraet pool.ntp.org ein, jetzt zurueck auf den auskommentierten Standard. - guest-session: Konto gast nur entfernen, wenn es von der Rolle stammt. - scripts/pruefe_absent.py: prueft die Abwaehl-Zweige gegen die Paketlisten der Golden Images (nach jedem neuen Image laufen lassen). Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
62 lines
2.3 KiB
Python
Executable File
62 lines
2.3 KiB
Python
Executable File
#!/usr/bin/env python3
|
|
"""
|
|
Prüft die Abwähl-Zweige aller Rollen gegen die Paketlisten der Golden Images
|
|
(roles/grundsystem/files/*.txt): Ein Paket, das ein Image selbst mitbringt,
|
|
darf beim Abwählen nur über den Grundsystem-Schutz
|
|
(| difference(tuxflotte_grundsystem_pakete …)) entfernt werden.
|
|
|
|
Aufruf im Repo-Wurzelverzeichnis: python3 scripts/pruefe_absent.py
|
|
Nach jedem neuen Golden Image (neue Paketliste) laufen lassen. Rückgabewert 1
|
|
bei Fund. Hintergrund: Firmware-Vorfall 09.10.2026, Audit 13.10.2026.
|
|
"""
|
|
import glob
|
|
import re
|
|
import sys
|
|
|
|
import yaml
|
|
|
|
IMAGES = {
|
|
pfad.split("/")[-1][:-4]: set(open(pfad, encoding="utf-8").read().split())
|
|
for pfad in glob.glob("roles/grundsystem/files/*.txt")
|
|
}
|
|
# Entfernt im Zustand "present" absichtlich Pakete (Sperre), kein Abwähl-Zweig.
|
|
AUSNAHMEN = {"netzwerkscanner-sperre"}
|
|
|
|
|
|
def aufgaben(liste):
|
|
for aufgabe in liste or []:
|
|
if not isinstance(aufgabe, dict):
|
|
continue
|
|
yield aufgabe
|
|
for block in ("block", "rescue", "always"):
|
|
yield from aufgaben(aufgabe.get(block))
|
|
|
|
|
|
funde = []
|
|
geprueft = 0
|
|
for datei in sorted(glob.glob("roles/*/tasks/*.yml")):
|
|
rolle = datei.split("/")[1]
|
|
if rolle in AUSNAHMEN:
|
|
continue
|
|
for aufgabe in aufgaben(yaml.safe_load(open(datei, encoding="utf-8"))):
|
|
for modul, argumente in aufgabe.items():
|
|
if not modul.endswith("apt") or not isinstance(argumente, dict) or argumente.get("state") != "absent":
|
|
continue
|
|
name = argumente.get("name")
|
|
text = str(name)
|
|
if "difference(tuxflotte_grundsystem_pakete" in text:
|
|
continue
|
|
pakete = name if isinstance(name, list) else (
|
|
re.findall(r"'([a-z0-9][a-z0-9.+-]+)'", text) if "{{" in text else [text]
|
|
)
|
|
for paket in pakete:
|
|
geprueft += 1
|
|
images = sorted(image for image, inhalt in IMAGES.items() if paket in inhalt)
|
|
if images:
|
|
funde.append(f"{rolle}: entfernt '{paket}' ungeschützt, enthalten in {', '.join(images)}")
|
|
|
|
for fund in funde:
|
|
print("FUND:", fund)
|
|
print(f"{geprueft} ungeschützt entfernte Pakete gegen {len(IMAGES)} Image-Listen geprüft, {len(funde)} Funde.")
|
|
sys.exit(1 if funde else 0)
|