v1.2.7
16
Commits
| Author | SHA1 | Message | Date | |
|---|---|---|---|---|
|
|
c7ad0d3d49 |
KRITISCH: install.sh loeschte license.json bei jedem Update (v1.2.3)
Live auf POETEST reproduziert: rsync --delete im App-Verzeichnis-Schritt schliesst venv/sqlite.db/fernet.key/secret.key/known_hosts explizit aus, vergisst dabei aber license.json (in Phase 1 neu hinzugekommen, als Ausschluss schlicht uebersehen). Da license.json nur auf dem Zielsystem existiert (nie im Release-Paket enthalten, korrekt .gitignored), loescht --delete sie bei JEDEM 'sudo ./update.sh' auf einer bereits aktivierten Instanz kommentarlos mit -- die Lizenz war danach weg, ohne dass update.sh oder install.sh irgendeinen Fehler gemeldet haetten. Der Master-seitige Installer (install.sh im tesm-license-Repo) hatte diesen Ausschluss von Anfang an korrekt gesetzt -- betraf ausschliesslich TESM-Kundeninstanzen. Fix: license.json zur rsync --exclude-Liste hinzugefuegt, analog zu den anderen laufzeit-generierten Secrets. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> |
||
|
|
1b7fe81507 |
Fileshare: Baum-Navigation, Datei-Vorschau, 15MB-Uploads (v1.1.1)
- Freigaben-Auswahl von einem Dropdown auf eine Baum-Navigation (links) umgestellt: alle gemounteten Freigaben als Wurzelknoten, Ordner beliebig aufklappbar. Der Pfad von der Wurzel bis zur aktuellen Position wird serverseitig schon aufgeklappt gerendert (_fileshare_tree_ancestors), alles andere laedt der Client per Klick lazy nach (neue Route /fileshare/subfolders) -- kein Durchlaufen der kompletten Freigabe auf einmal noetig. Dateien stehen bewusst nicht im Baum, nur in der bestehenden Tabelle rechts. - Inline-Vorschau fuer PDF (iframe), Bilder, TXT/CSV/LOG/MD/JSON (per Range- Request in Haeppchen bis 512KB, mit Hinweis bei Abschneiden -- Erkennung ueber den Content-Range-Header, nicht nur den 206-Status, der bei JEDEM Range-Request auftritt) sowie Word/Excel rein clientseitig per mammoth.js bzw. SheetJS (beide lokal vendored, kein Cloud-Viewer -- interne Dokumente verlassen das Netz nicht). Excel-Zellen werden bewusst per textContent statt ueber SheetJS' eigene HTML-Ausgabe gesetzt, um unabhaengig von deren Escaping-Verhalten sicher zu sein. Neue Route /fileshare/view mit fester Endungs-Positivliste, nosniff + restriktiver CSP. - Uploads bis 15MB erlaubt (MAX_CONTENT_LENGTH in app.py) -- dafuer musste auch nginx' client_max_body_size (Standard 1MB) auf 16MB angehoben werden, sowohl im Vorlagen-Code (_NGINX_PROXY_LOCATIONS/_render_nginx_config, fuer die naechste Anwendung ueber Einstellungen->NGINX) als auch in der Fresh-Install-Vorlage. Neuer 413-Errorhandler zeigt eine Flash-Meldung statt Werkzeugs nackter Fehlerseite. - install.sh: known_hosts (liegt unter /srv/tesm) von rsync --delete ausgenommen -- fehlte bisher in der Exclude-Liste (anders als sqlite.db/ fernet.key/secret.key) und waere bei jedem Update verlorengegangen. Live auf POETEST getestet: Baum-Vorbefuellung, Lazy-Load von Geschwisterordnern, alle 5 Vorschautypen (PDF-Route direkt verifiziert, Bild/Text/Word/Excel zusaetzlich visuell), Abschneide-Erkennung sowohl bei kleiner als auch bei >512KB-Datei. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> |
||
|
|
09b222615a |
Fileshare-Feature: LDAP-gruppengesteuerte Netzlaufwerke im Browser (v1.1.0)
- Neue ldap_fileshare_mappings-Tabelle (AD-Gruppe -> Freigabe-UNC+Label), verwaltet in Einstellungen -> LDAP wie die bestehende App-Gruppenzuordnung (inkl. AD-Gruppen-Dropdown per "Gruppen laden", UNC-Backslash/Slash- Normalisierung). - Login-Gate: optionale "Erforderliche AD-Gruppe fuer Login" (Dropdown, gleiches Lade-Muster) -- ohne Mitgliedschaft scheitert der Login wie bei falschen Zugangsdaten, ohne Hinweis auf den eigentlichen Grund. - Sessionabhaengiges Mounten: beim LDAP-Login werden alle per AD-Gruppe zugeordneten Freigaben mit den eigenen (nie gespeicherten) Zugangsdaten per mount.cifs unter /mnt/tesm-shares/<session-token>/ gemountet, beim Logout wieder ausgehaengt. Passwort läuft ausschliesslich ueber die PASSWD-Umgebungsvariable von mount.cifs. Aufraeum-Sweep (30 Min-Takt, 12h-Schwelle) und Cleanup-on-Startup als Sicherheitsnetz. - Zwei unabhaengige Gates: TESM-Rechtesystem (fileshare.view/.create/.edit, neue PERMISSIONS-Gruppe fileshare_group) UND AD-Gruppenmitgliedschaft muessen beide zutreffen, sonst wird nicht gemountet und der Menuepunkt "Dateifreigaben" bleibt verborgen. - Neuer Dateibrowser (/fileshare, .../download, .../upload, .../mkdir, .../delete, .../rename) mit Breadcrumbs, Upload/Download, Anlegen/ Umbenennen/Loeschen -- Pfadaufloesung ausschliesslich ueber os.path.realpath-Vergleich gegen die eigene Mount-Root (Path-Traversal- Schutz), zusaetzlich secure_filename() fuer Datei-/Ordnernamen. - KRITISCHER Bugfix waehrend Live-Test gefunden: generate_ips.py importiert app.py als Hilfsmodul (u.a. aus poe.sh/tesm-check.service heraus, alle paar Sekunden) -- das fuehrte Modul-Level-Code erneut aus und hat aktive Fileshare-Mounts anderer Sitzungen sofort wieder ausgehaengt. Neues TESM_WEB_PROCESS-Env-Flag (nur in tesm.service gesetzt) schuetzt Cleanup-on-Startup und den Sweep-Thread davor, bei einem reinen Modul-Import erneut zu laufen. - install.sh: cifs-utils ergaenzt (liefert mount.cifs). - SCHEMA_VERSION 1 -> 2, VERSION 1.0.10 -> 1.1.0. Live auf Testbox (192.168.82.51) und POETEST (192.168.80.202) getestet: Login-Gate (erlauben/verbieten/reset), Rechte-Gate (Mount+Menuepunkt nur mit fileshare.view), vollstaendiger Datei-Workflow (Upload/Download/ Umbenennen/Anlegen/Loeschen) gegen eine echte SMB-Freigabe, Path-Traversal gegen alle 5 Routen (serverseitig verifiziert, kein Escape), sauberes Unmount bei /logout. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> |
||
|
|
4de5828573 |
NGINX-Seite ausgebaut: Domain/Ports, RAW-Config, Let's Encrypt mit Auto-Verlaengerung; Flask nur noch lokal erreichbar
Umbenennung: Einstellungen -> SSL/TLS heisst jetzt Einstellungen -> NGINX (Route /settings/ssl -> /settings/nginx, Recht settings_ssl.* -> settings_nginx.*, Icon "server" statt "shield") -- die Seite verwaltet den kompletten Reverse-Proxy, nicht mehr nur SSL. Neu: - Domain (server_name) und HTTP-/HTTPS-Port sind jetzt einstellbar, nicht mehr hart "_" bzw. 80/443. Aendert man den HTTP-Port weg von 80, wird automatisch zusaetzlich ein minimaler Nur-ACME-Block auf Port 80 mitgeschrieben, da Let's Encrypt (HTTP-01) protokollbedingt immer Port 80 braucht, unabhaengig vom konfigurierten HTTP-Port. - "RAW-Konfiguration"-Button zeigt die komplette aktuelle nginx-Config im selben Popup-Stil wie das Live-Log (Wiederverwendung von window.openRawLogModal, kein neuer Code dafuer noetig). - Let's Encrypt: Zertifikat per certbot anfordern (certonly --webroot, bewusst NICHT das certbot-nginx-Plugin -- das wuerde die App-eigene, komplett selbstgeschriebene Config direkt editieren und bei der naechsten Aenderung ueber diese Seite wieder verlieren). Automatische Verlaengerung laeuft ueber certbots eigenen systemd-Timer/Cron (Standard-Paketverhalten), ein Deploy-Hook (/etc/letsencrypt/renewal-hooks/deploy/tesm-reload-nginx.sh, wird wie die logrotate-Config bei jedem App-Start neu geschrieben) laedt nginx nach jeder Verlaengerung neu. Fehlgeschlagene Anforderung (kein oeffentlicher DNS-Eintrag o.ae.) wird sauber abgefangen und als Fehlermeldung angezeigt, ohne etwas zu veraendern -- live mit einer ungueltigen Test-Domain verifiziert. - Zertifikatsquelle (Upload vs. Let's Encrypt) wird als eigenes Setting (ssl_source) verfolgt, das Anwenden/Anzeigen/Entfernen beruecksichtigt beide Quellen jeweils passend (Entfernen einer LE-verwalteten Installation laeuft ueber "certbot delete", nicht ueber rohes Datei-Loeschen, damit certbots eigene Renewal-Konfiguration nicht verwaist). - certbot zu install.sh's Paketliste hinzugefuegt. Flask/gunicorn bindet jetzt an 127.0.0.1 statt 0.0.0.0 (tesm.service) -- direkter Zugriff auf Port 5000 aus dem Netz ist damit nicht mehr moeglich, nur noch ueber den nginx-Reverse-Proxy (der ohnehin nur ueber 127.0.0.1 zugreift). Beantwortet die Nachfrage, ob Flask unerreichbar gemacht werden kann. Live auf Testsystem-Update-Restart verifiziert: Domain/Port-Aenderung (HTTP-Port 8080 inkl. automatischem Zusatz-Block auf Port 80), RAW-Config-Anzeige, Zertifikat-Upload, Let's-Encrypt-Fehlschlag sauber abgefangen, Rueckbau auf Standardwerte (_, 80, 443, kein SSL) ueber denselben Anwenden/Bestaetigen-Sicherheitsnetz-Pfad wie zuvor. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> |
||
|
|
f27dde466b |
SSL/TLS-Verwaltung (Upload+Aktivieren), install.sh-Idempotenz, poe_web/rpi-check-Cleanup entfernt
SSL/TLS (neue Seite Einstellungen -> SSL/TLS, eigenes Recht settings_ssl.view/.edit):
- Zertifikat+privater Schluessel per Upload hinterlegbar (PEM), Validierung
VOR dem Speichern: gueltiges Zertifikat, noch nicht abgelaufen, Schluessel
passt zum Zertifikat (Abgleich ueber die oeffentlichen Schluessel als
DER-Bytes -- funktioniert algorithmus-unabhaengig fuer RSA/EC/...).
Speicherort /etc/tesm/ssl (bewusst ausserhalb von /srv/tesm, damit
rsync --delete beim Update das Zertifikat nicht mitloescht), Key mit
chmod 600.
- HTTPS aktivieren schreibt/validiert (nginx -t) eine neue nginx-Konfiguration
und laedt erst danach neu; Port 80 leitet dann automatisch auf https weiter.
HSTS optional zuschaltbar, setzt aktives SSL voraus.
- Gleiches Sicherheitsnetz wie bei den Netzwerkeinstellungen: nach dem
Anwenden 45s Zeitfenster zum Bestaetigen, sonst automatischer Rueckroll
der nginx-Konfiguration UND der ssl_enabled/hsts_enabled-Einstellungen.
Beide Pfade (Timeout-Rollback und Bestaetigen-verhindert-Rollback) live
auf Testsystem-Update-Restart verifiziert, inklusive eines ECHTEN,
ungeplant ausgeloesten Rollbacks waehrend des Testens.
- Noch KEINE Let's-Encrypt-Automatisierung (siehe Kommentar im Code) --
alle bekannten Instanzen laufen intern ohne oeffentliche Domain, HTTP-01
wuerde dort nicht funktionieren; kann bei Bedarf separat ergaenzt werden.
install.sh: Update-Idempotenz ("nur anfassen, was sich geaendert hat"):
- install_if_changed()-Helfer: Custom-Skript/systemd-Units/MOTD-Banner
werden nur noch bei tatsaechlich geaendertem Inhalt neu geschrieben,
daemon-reload nur wenn sich mindestens eine Unit geaendert hat.
- nginx-Konfiguration wird nur noch bei einer Frischinstallation aus dem
Repo-Template geschrieben -- eine bereits vorhandene (egal ob unveraendert
oder von der App selbst um SSL erweitert) wird nie wieder ueberschrieben.
Voraussetzung dafuer, dass die neue SSL-Funktion ein Update ueberlebt.
update.sh: komplette Sonderbehandlung fuer die zwei TESM vorausgehenden
Generationen (rpi-check.service, poe_web.service/poe_manager) entfernt --
auf allen aktuellen Installationen laengst migriert. Deaktivierte
Unit-Dateien dieser Generationen wurden auf Testsystem-Update-Restart
zusaetzlich manuell endgueltig geloescht (waren dort seit einer Migration
im September 2025 nur deaktiviert, nicht entfernt).
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
|
||
|
|
befc76819e |
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 <noreply@anthropic.com>
|
||
|
|
c30ad41101 |
install.sh: Sicherheitsnetz gilt jetzt fuer JEDES Update, nicht nur Schema-Aenderungen
Live gefunden: der 'Schema unveraendert -> kein Backup'-Kurzschluss aus v1.0.3 liess einen rein CODE-seitigen Fehler im neuen Paket (z.B. ein kaputtes app.py -- mit dem DB-Schema hat das nichts zu tun) komplett ungeschuetzt durch. Backup + Health-Check + ggf. Rollback laufen jetzt bei JEDEM Update einer bestehenden Installation, unabhaengig von SCHEMA_VERSION -- die bleibt nur noch fuer den Wortlaut der Log-Meldung relevant (In-Place-Update vs. Migration). Zusaetzlich beim Rollback selbst: 'mv' durch 'cp -a' beim Zurueckspielen ersetzt, plus die fehlgeschlagene Installation vorher separat beiseite gelegt (/srv/tesm-failed-update-<timestamp>) statt geloescht -- vorher wurde das Backup beim Zurueckspielen selbst zum neuen /srv/tesm und verschwand dadurch als eigenstaendige Sicherung (widersprach der eigenen Zusage 'Backup bleibt erhalten'). Live auf der Testbox in allen drei Pfaden verifiziert: - Erfolgreiches Update: Backup erstellt, Health-Check bestanden, Backup geloescht, Daten erhalten. - Migration (kuenstlich abweichende SCHEMA_VERSION, echte Struktur unveraendert): Backup erstellt, Health-Check bestanden, Backup geloescht. - Fehlgeschlagenes Update (absichtlich kaputte app.py): Backup erstellt, Health-Check schlaegt korrekt fehl, automatischer Rollback stellt den letzten funktionierenden Zustand wieder her (Dienst aktiv, Health-Check 200, Datenbank-Canary erhalten), Backup UND fehlgeschlagene Installation bleiben als zwei getrennte Verzeichnisse zur Fehlersuche erhalten. VERSION: 1.0.4 (v1.0.3 hatte die oben beschriebene Luecke und wurde bereits ausgerollt, daher hier ein neues Release statt eines erneuten Tags auf v1.0.3). |
||
|
|
e17d91743a |
install.sh wird update-faehig, update.sh auf Bootstrapper reduziert
install.sh erkennt jetzt selbststaendig eine bestehende Installation (an sqlite.db) und verhaelt sich entsprechend: - Keine vorhandene Installation -> normale Frischinstallation (wie bisher). - Vorhanden, SCHEMA_VERSION unveraendert -> einfaches In-Place-Update, kein Backup noetig (rsync schliesst sqlite.db ohnehin aus). - Vorhanden, SCHEMA_VERSION unbekannt/abweichend -> Update MIT Sicherheitsnetz: die KOMPLETTE bisherige Installation (Code, venv, Datenbank, Schluessel) wird vorher 1:1 nach /srv/tesm-backup-pre-migration-<timestamp> kopiert (bewusst nicht nur die Datenbank -- ein reines DB-Rollback wuerde beim naechsten Start mit dem NEUEN Code sofort denselben Migrationsfehler wiederholen). Die eigentliche Schema-Migration uebernimmt danach die App selbst beim Start (_ensure_schema() in app.py). Kommt der Dienst anschliessend per HTTP-Check auf /login nachweislich NICHT gesund hoch, wird automatisch die komplette Sicherung zurueckgespielt und bleibt zur manuellen Pruefung erhalten. Kommt er gesund hoch, gilt die Migration als erfolgreich und das Backup wird geloescht. update.sh delegiert diese gesamte /srv/tesm-spezifische Logik jetzt an install.sh und ist selbst nur noch fuer das Ablösen AELTERER, TESM vorausgehender Installationsstufen zustaendig (PoE Manager unter /srv/poe_manager, das urspruengliche reine Bash-Setup) -- bleibt aber als bequemer Ein-Skript-Bootstrapper (Download + Entpacken + Aufruf von install.sh) bestehen, wie gewuenscht. install.sh selbst ist dadurch jetzt auch OHNE update.sh direkt aus einem entpackten Release-Paket lauffaehig und erkennt ein Update trotzdem korrekt. VERSION: 1.0.3 (SCHEMA_VERSION unveraendert, 1 -- keine echte Schema- Aenderung in diesem Release, In-Place-Update-Pfad bleibt der Normalfall). |
||
|
|
bc360a0b7f |
Produktiver WSGI-Server (Gunicorn) statt Flasks Entwicklungsserver
tesm.service startete die App bisher direkt per 'python3 app.py', was Flasks eingebauten Werkzeug-Entwicklungsserver nutzt -- der meldet bei jedem Start 'WARNING: This is a development server. Do not use it in a production deployment.' und ist bewusst nicht für Dauerbetrieb gebaut. Umgestellt auf Gunicorn, mit zwei bewusst gesetzten Einschraenkungen: - '--workers 1': die App haelt laufende Wartungs-Jobs/Import-Vorschauen nur im Arbeitsspeicher DES EINEN Prozesses (_maintenance_jobs, _pending_imports, ...) -- mehrere Worker-Prozesse wuerden diesen Zustand auf mehrere, sich nicht kennende Prozesse verteilen. - '--worker-class gthread --threads 16' statt eines async-Workers: das Browser-SSH-Terminal (flask-sock) belegt pro offener WebSocket- Verbindung einen blockierenden Thread. - '--timeout 0': deaktiviert Gunicorns eigenen 30s-Worker-Timeout, der sonst auch eine offene, aber gerade inaktive SSH-Terminal-Verbindung killen wuerde. Live auf POETEST verifiziert: keine WARNING-Zeile mehr, genau 1 Master- + 1 Worker-Prozess, alle Kernseiten weiterhin 200, und als kritischer Regressionstest das WebSocket-SSH-Terminal Ende-zu-Ende gegen einen echten Host erfolgreich getestet (Host-Key/Passwort-Prompt/Login/Shell). Dabei einen unabhaengigen Altlast-Fehler in POETESTs venv gefunden und allgemein in install.sh gefixt: './venv/bin/pip' hat eine zur Venv-Erstellung fest einprogrammierte Shebang-Zeile -- nach der historischen Umbenennung 'poe_manager' -> 'tesm' zeigte sie auf einen nicht mehr existierenden Pfad und schlug mit 'cannot execute: required file not found' fehl. 'python3 -m pip' umgeht das, da nur der (korrekt referenzierte) venv-Python-Interpreter selbst gebraucht wird -- betrifft sonst auch jedes kuenftige In-Place-Update auf einem aehnlich gewachsenen Host. |
||
|
|
e6f9a7aee0 |
KRITISCH: install.sh brach ohne TTY sofort und lautlos ab (clear + set -e)
"clear" schlägt ohne TERM/Pseudo-Terminal mit Exit-Code 1 fehl ("TERM
environment variable not set") -- z.B. genau dann, wenn install.sh (wie von
update.sh vorgesehen) per SSH exec_command ohne pty aufgerufen wird. Mit
"set -e" hat das die GESAMTE Installation sofort an Zeile 2 abgebrochen,
noch bevor auch nur ein apt-Paket installiert oder eine einzige Zeile ins
Install-Log geschrieben wurde -- kein Fehlertext, kein Hinweis, einfach
Stille. Live reproduziert: update.sh lud das Release-Paket korrekt herunter
und entpackte es, install.sh selbst tat aber schlicht nichts.
Behoben: "clear" ist jetzt bewusst nie fatal (2>/dev/null || true) -- rein
kosmetisch, hat keinen Einfluss auf die eigentliche Installation.
|
||
|
|
3ab3407a18 |
Login-Seite überarbeitet, TESM-Logo als echter Hintergrund; SSH-MOTD-Banner mit Live-Daten
- Login-Seite: WiS-/TESM-Logo und "Melde dich an, um fortzufahren" aus der Box entfernt; die TESM-Wortmarke mit Funktionszeile ist jetzt der tatsächliche Seitenhintergrund (absolut positioniert, hinter allem), die Box liegt zentriert davor. Nebenbei zwei echte Bugs gefunden und behoben: fehlendes Cache-Busting auf login.html (asset_url() wie in base.html, sonst hält nginx' 7-Tage-Cache eine alte style.css/app.js fest) und ein durch den fehlenden align-items-Wert auf die volle Höhe gestrecktes Login-Formular. - Neuer SSH-Login-Banner (dynamisches MOTD) mit Live-Flottenstatus statt der Standard-Ubuntu-Willkommensmeldung: srv/tesm/motd_banner.py liest Online/Offline- und DHCP-Status aus denselben Quellen wie das Web-Dashboard (get_device_status()/_dhcp_read_leases()), eingebunden über etc/update-motd.d/50-tesm. install.sh deaktiviert dabei die Standard- Ubuntu-MOTD-Skripte (chmod -x, reversibel) und installiert den neuen Hook. |
||
|
|
d1b10bd970 |
Rebrand to TESM: infra rename, LDAP/AD login, selective import/export, Papierkorb
- Vollständiges Rebranding "PoE Manager" -> TESM (TimEShepManager): neue Logos/Favicon (theme-aware), Sidebar/Login-Branding, Copyright-Zeile. - Infrastruktur-Umbenennung: srv/poe_manager -> srv/tesm, alle POE_*-Env-Vars -> TESM_* (POE_SCRIPT bewusst unverändert, echtes PoE-Skript), systemd Units poe_web/rpi-check* -> tesm/tesm-check*, nginx-Site, netplan/logrotate Configs, Gitea-Repo alientim/Aruba-PoE-Modern -> alientim/tesm. - LDAP/Active-Directory Same-Sign-On: Search+Bind, AD-Gruppen->App-Gruppen- Zuordnung (additiv), Konto-Sperren, AD-Vorab-Suche/-Anlage, eigene Einstellungsseite. - Selektives Import/Export (8 Kategorien, Zwei-Schritt-Vorschau) mit eigenem R/E/X-Rechtemodell (X = Export, getrennt von E = Import). - Papierkorb: Soft-Delete statt Hard-Delete für Geräte/Switche/Zugangsdaten/ Benutzer/Gruppen (AD-Nutzer ausgenommen), eigene Seite unterhalb Wartung, konfigurierbare Aufbewahrungsfrist. - rpi_ip -> ip Spalten-/Code-Umbenennung (Geräte sind längst nicht mehr auf Raspberry Pis beschränkt). - README auf aktuellen Stand gebracht. |
||
|
|
7b30ebce7b |
Logging & Log-Rotation, Zeitzone, Dashboard-UX, Design-Politur
Logging-Infrastruktur (Logs können nach einem Import mit vielen Geräten schnell vollaufen): - Vier eigene, rotierte Log-Dateien statt allem in /var/log vermischt: Live (poe.sh, jetzt eine einzige durchgehend fortgeschriebene Datei statt vorher ein neues rpi-<timestamp>.log pro Dienst-Neustart), Änderungen (Spiegel der audit_log-Tabelle), App (Flask-Fehler/ Warnungen, vorher nur im journalctl-Output), Kea-DHCP (eigene Logging-Konfiguration in der generierten kea-dhcp4.conf) - Kea-DHCP-Log bewusst NICHT im gemeinsamen Verzeichnis: Keas AppArmor-Profil erlaubt Schreibzugriff exklusiv auf /var/log/kea/kea-dhcp4.log (kein Verzeichnis-Wildcard) -- live als "DENIED ... mknod ... .lock" reproduziert; die App nutzt Keas eigenen, bereits erlaubten Pfad statt das AppArmor-Profil eines Systemdienstes aufzuweichen. logrotate deckt trotzdem beide Verzeichnisse mit einer Regel ab - Neue Log-Seite "Kea-DHCP" (Logs-Bereich, eigenes Recht logs_kea.view) - Rotation (Intervall täglich/wöchentlich/monatlich, Aufbewahrung als Anzahl Rotationen) unter Systemeinstellungen → Logs einstellbar, generiert /etc/logrotate.d/poe-manager; copytruncate, da keiner der drei schreibenden Prozesse ein Reopen-Signal implementiert - Einmalige Migration räumt alte, verwaiste rpi-*.log-Dateien auf Zeitzone (Systemeinstellungen, mit Hostname in einer Kachel "Host"): setzt die System-Zeitzone per timedatectl, damit Logs/Änderungsverlauf die tatsächliche lokale Zeit statt UTC zeigen. time.tzset() direkt nach dem Setzen lässt die bereits laufende poe_web.service-Instanz die neue Zeitzone sofort übernehmen, ohne Neustart. Systemeinstellungen neu sortiert: Host + Netzwerkeinstellungen (beide Host-Konfiguration) nebeneinander, dann Logs, dann Prüfintervall. Netzwerkeinstellungen: DNS-Anzeige zeigte bisher den lokalen systemd-resolved-Stub (127.0.0.53) aus /etc/resolv.conf statt der echten Server -- jetzt über "resolvectl dns <interface>", inkl. Fix für eine falsch geparste IPv6-Fortsetzungszeile ohne Label, und gefiltert auf IPv4 (diese Seite verwaltet nur IPv4-Konfiguration, per IPv6-Router-Advertisement gelernte Server sind hier irreführend). Dashboard: die vier Stat-Kacheln (Online/Offline/Deaktiviert/Gesamt) sind jetzt klickbare Filter (blenden alle anderen Abschnitte aus, Klick auf die aktive Kachel oder "Gesamt" hebt den Filter auf); jeder Abschnitt lässt sich unabhängig davon per Klick auf seinen Titel ein-/ ausklappen. Beide Zustände bleiben über die automatischen Live-Updates hinweg erhalten. Design-Politur: - Hauptinhaltsbereich nutzt jetzt die volle verfügbare Breite (kein Bootstrap-typisches festes max-width mehr) -- Modals bleiben bewusst bei ihrer kompakten, festen Breite Akzentfarbe exakt auf das Orange aus dem WiS-Logo abgestimmt (#ff7100, per Pixel-Sampling ermittelt) statt einer nur ähnlichen, frei gewählten Nuance - Abmelden führt zurück auf das (auch ohne Login einsehbare) Dashboard statt auf die Login-Seite Live gegen die echte Test-VM verifiziert: alle vier Logs werden geschrieben, logrotate-Konfiguration korrekt generiert, ein Zeitzonenwechsel (UTC → Europe/Berlin) wirkte sofort, DNS-Anzeige zeigt jetzt die echten IPv4-Server (1.1.1.1, 8.8.8.8) statt Stub/IPv6, Dashboard-Filter/-Collapse und Logout-Redirect per Playwright bestätigt. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> |
||
|
|
357bb4caa5 |
Fix: iputils-ping fehlte in install.sh-Paketliste
Auf der Test-VM war 'ping' nicht vorhanden (Minimal-Ubuntu-Image liefert es nicht immer vor) -- fuer die Erreichbarkeitspruefung der Geraete (Pruefintervall / rpi-check-Dienst) zwingend noetig. Live auf dem Testsystem nachinstalliert und verifiziert. |
||
|
|
9e23243872 |
Fix: rsync fehlte in install.sh-Paketliste (Deploy-Schritt braucht es)
Live auf frischem Testsystem (Ubuntu 24.04, 192.168.80.114) verifiziert: Skript brach beim Kopieren nach /srv/poe_manager mit 'rsync: command not found' ab, weil rsync nirgends in der apt-get-install-Zeile stand. |
||
|
|
82bfeb17ed |
Initial commit: PoE Manager modern UI rebuild
- Neues, eigenständiges Frontend (Sidebar, zentriertes Logo in der Topbar, Dark/Light-Theme, Karten-Dashboard, Toasts/Modals statt Bootstrap) - Oeffentliches Kurz-Dashboard ohne Login (Status-Uebersicht) - Browser-SSH-Terminal (paramiko, plattformunabhaengig) zum Testen von Switch-Zugangsdaten inkl. interaktiver Host-Key-Bestaetigung - Granulares Rechtesystem mit Gruppen (Devices/Switches-Berechtigungen) - Aufgeraeumtes Backend mit konfigurierbaren Pfaden, auto-generierten Secrets statt hart codierter Werte im Original Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> |