From befc76819ef57ce495939d7587513e4bf5025b45 Mon Sep 17 00:00:00 2001 From: alientim Date: Sat, 22 Aug 2026 11:11:41 +0200 Subject: [PATCH] Logrotate: TESM_LOG_DIR world-writable verhinderte jede Rotation Root Cause (live auf POETEST reproduziert): /var/log/tesm war 0o777 (noch aus einer Zeit vor dem Umstieg auf root-laufende systemd-Units). logrotate verweigert seit den aktuellen Haertungen jede Rotation in einem group-/world-writable Verzeichnis ("insecure permissions") komplett -- live.log wuchs auf POETEST seit der letzten Neuinstallation (9 Tage) unbegrenzt, /var/lib/logrotate/status hatte fuer tesm ueberhaupt keinen Eintrag. Direkte Folge: die neue Verlauf-Seite blieb leer, weil nie live.log.1/.2/... entstanden. Fix: - os.chmod(TESM_LOG_DIR) und os.chmod(TESM_CLIENT_UPDATE_LOG_DIR) in app.py: 0o777 -> 0o755 (tesm.service/tesm-check.service laufen beide als root, kein anderer Dienstbenutzer schreibt hierher -- Keas eigenes Log liegt separat unter /var/log/kea/). Laeuft bei jedem App-Start, heilt bestehende Installationen also automatisch beim naechsten Neustart/Update. - install.sh: chmod 777 -> chmod 755 fuer /var/log/tesm bei einer Frischinstallation, veraltete/falsche Kommentar-Begruendung (angeblich auch fuer Kea noetig) korrigiert. - _write_logrotate_config(): zusaetzlich 'su root root' in der generierten Konfiguration als Absicherung, falls das Verzeichnis aus irgendeinem Grund wieder zu weit geoeffnet wird. - VERSION 1.0.5 -> 1.0.6. Live verifiziert auf Testsystem-Update-Restart: logrotate -d zeigt nach dem Fix keine 'insecure permissions'-Fehler mehr, ein erzwungener Lauf (logrotate -f) erzeugt sauber live.log.1/live.log.2. Co-Authored-By: Claude Sonnet 5 --- install.sh | 17 +++++++++++------ srv/tesm/VERSION | 2 +- srv/tesm/app.py | 18 +++++++++++++++--- 3 files changed, 27 insertions(+), 10 deletions(-) diff --git a/install.sh b/install.sh index 4b84eee..60261aa 100644 --- a/install.sh +++ b/install.sh @@ -102,13 +102,18 @@ sudo apt-get update >>/var/log/tesm-install.log 2>&1 && print_status "apt update sudo apt-get install -y python3 python3-venv python3-pip nginx sqlite3 expect openssh-client git rsync iputils-ping logrotate >>/var/log/tesm-install.log 2>&1 && print_status "Packages installed" # ---- Log-Verzeichnis ---- -# Weltweit beschreibbar, da sowohl root (tesm.service/poe.sh) als auch -# der i.d.R. unprivilegierte kea-dhcp4-server-Dienstbenutzer (_kea) hier -# ihre jeweils eigene Log-Datei anlegen/schreiben müssen. Die eigentliche -# logrotate-Konfiguration (/etc/logrotate.d/tesm) schreibt die App -# selbst beim Start bzw. beim Speichern unter Systemeinstellungen → Logs. +# NICHT weltweit beschreibbar (0755 reicht) -- sowohl tesm.service als +# auch tesm-check.service (poe.sh) laufen als root, kein anderer +# Dienstbenutzer schreibt hierher (Keas eigenes Log liegt separat unter +# TESM_KEA_LOG_PATH, i.d.R. /var/log/kea/). Ein group-/world-writable +# Verzeichnis lässt logrotate die Rotation aus Sicherheitsgründen +# komplett verweigern ("insecure permissions") -- live reproduziert: bei +# 0777 rotierte live.log über Wochen hinweg gar nicht mehr. Die +# eigentliche logrotate-Konfiguration (/etc/logrotate.d/tesm) schreibt +# die App selbst beim Start bzw. beim Speichern unter +# Systemeinstellungen → Logs. sudo mkdir -p /var/log/tesm -sudo chmod 777 /var/log/tesm +sudo chmod 755 /var/log/tesm # ---- App-Verzeichnis ---- step "Deploying application to /srv/tesm" diff --git a/srv/tesm/VERSION b/srv/tesm/VERSION index 90a27f9..af0b7dd 100644 --- a/srv/tesm/VERSION +++ b/srv/tesm/VERSION @@ -1 +1 @@ -1.0.5 +1.0.6 diff --git a/srv/tesm/app.py b/srv/tesm/app.py index af6a4a1..4b1b1d3 100644 --- a/srv/tesm/app.py +++ b/srv/tesm/app.py @@ -95,7 +95,13 @@ TESM_KEA_LOG_PATH = os.environ.get("TESM_KEA_LOG_PATH", "/var/log/kea/kea-dhcp4. LOGROTATE_CONFIG_PATH = os.environ.get("TESM_LOGROTATE_CONFIG", "/etc/logrotate.d/tesm") try: os.makedirs(TESM_LOG_DIR, exist_ok=True) - os.chmod(TESM_LOG_DIR, 0o777) + # War früher 0o777, als noch nicht jeder schreibende Prozess (tesm.service, + # tesm-check.service) als root lief. Ein world-writable Verzeichnis lässt + # logrotate die Rotation aber aus Sicherheitsgründen komplett verweigern + # ("insecure permissions") -- live reproduziert: ohne Rotation blieb + # live.log unbegrenzt wachsen, siehe auch "su root root" in + # _write_logrotate_config als zusätzliche Absicherung. + os.chmod(TESM_LOG_DIR, 0o755) except OSError: pass SWITCH_DEFAULT_SSH_PORT = 22 @@ -1183,7 +1189,12 @@ def _write_logrotate_config(): Log-Reopen-Signal (SIGHUP o.ä.) implementiert — copytruncate funktioniert ohne jede Kooperation des schreibenden Prozesses (Kea eingeschlossen: logrotate läuft als root, unterliegt also nicht Keas - eigenem AppArmor-Profil).""" + eigenem AppArmor-Profil). "su root root" ist eine explizite Absicherung + dagegen, dass logrotate die Rotation wegen "insecure permissions" + verweigert, sobald TESM_LOG_DIR aus irgendeinem Grund wieder + gruppen-/world-writable wird (live reproduziert: bei 0o777 rotierte + logrotate live.log gar nicht mehr, siehe auch os.chmod(TESM_LOG_DIR) + weiter oben, das den eigentlichen Regelfall -- 0o755 -- durchsetzt).""" interval = get_setting("log_rotation_interval", LOG_ROTATION_DEFAULT_INTERVAL) if interval not in LOG_ROTATION_INTERVALS: interval = LOG_ROTATION_DEFAULT_INTERVAL @@ -1201,6 +1212,7 @@ def _write_logrotate_config(): f" missingok\n" f" notifempty\n" f" copytruncate\n" + f" su root root\n" f"}}\n" ) try: @@ -5077,7 +5089,7 @@ def _write_client_update_error_log(name, exit_code, lines): auch ohne offenes Browser-Fenster im Nachhinein auffindbar bleibt.""" try: os.makedirs(TESM_CLIENT_UPDATE_LOG_DIR, exist_ok=True) - os.chmod(TESM_CLIENT_UPDATE_LOG_DIR, 0o777) + os.chmod(TESM_CLIENT_UPDATE_LOG_DIR, 0o755) safe_name = secure_filename(name) or "unbenannt" path = os.path.join(TESM_CLIENT_UPDATE_LOG_DIR, f"{safe_name}.error") with open(path, "w", encoding="utf-8") as f: