alientimandClaude Opus 5 51ae39dd53 Upgrade von 1.x, Leerlaufabmeldung, Mitschrift im Audit
upgrade.sh -- ein Weg vom Stand SONNET5 auf diese Fassung, mit Daten. Der
Ablauf braucht keine Schalter: alte Installation sichern, abschalten, neu
installieren, exportieren, uebersetzen, einspielen. Die Sicherung steht
bewusst vor dem Export -- ohne --instance installiert install.sh in dasselbe
Verzeichnis, und wer erst exportiert und dann sichert, sichert im
schlechtesten Fall nichts mehr. Gelesen wird nur aus der Kopie.

Dafuer zwei neue Befehle: "legacy-export" liest eine alte Installation
unmittelbar (der Vorgaenger kann nur ueber die Weboberflaeche exportieren --
fuer ein Upgrade der falsche Weg, und unmoeglich, wenn die alte Anwendung nicht
mehr startet) und schreibt eine Datei im alten Format, die deshalb auch als
Rueckweg taugt. "legacy-import" liest eine Datei im neuen Format ein, ueber
transfer.apply_import -- dieselbe Funktion wie die Seite "Sicherung", kein
zweiter Schreibpfad.

Am Lizenzserver hat der Lauf gegen echte Altdaten zwei Fehler gezeigt, die
jede Uebernahme unmoeglich machten:

* Der alte Signaturschluessel ist URL-sicher kodiert (- und _). Das neue
  Protokoll prueft Base64 streng -- richtig so, aber beim Lesen einer alten
  Datei brach die Uebernahme mit einem Traceback ueber "kein gueltiges Base64"
  ab. Umkodiert wird jetzt an der Grenze zum Altformat; der kanonische Decoder
  bleibt streng.
* Der Anbieterblock wurde aus den Einstellungen der *neuen* Installation
  gebaut, und ohne Endpunkt brach die Uebernahme ab. Bei einem Upgrade ist die
  neue Installation frisch -- dort steht nichts. Endpunkt und Anbieterdaten
  kommen jetzt aus der alten Installation, aber nur dort, wo neu nichts steht.
  Der alte Signaturschluessel wird uebernommen: sonst muesste jeder Kunde
  einen Ausstellerwechsel bestaetigen.

Leerlaufabmeldung: sie hat nie ausgeloest. Ein offener Tab fragt seine
Kacheln alle 15 Sekunden neu ab, und jede Abfrage verlaengerte das
Leerlauffenster -- nachweisbar an einer Sitzung, deren last_seen_at eine
Minute alt war, obwohl seit zehn Stunden niemand am Rechner sass. Der Client
kennzeichnet automatische Anfragen jetzt mit einem Kopf, der Server
verlaengert daraufhin nichts, und last_seen_at bleibt, was der Name sagt.
Faellt die Sitzung waehrend des Pollens, antwortet der Server mit 401 statt
mit einer Umleitung: der Tab laedt neu und zeigt die Anmeldemaske, statt
stumm mit alten Zahlen stehenzubleiben.

Im Audit ist der Name der Mitschrift jetzt ein Verweis auf die Datei -- es ist
derselbe Weg wie zuvor, nur einen Klick weit. Verlinkt wird nur, wenn die
Datei existiert und der Betrachter Protokolle lesen darf; der Rest des
Eintrags wird maskiert, denn ein Auditeintrag enthaelt Fremdeingaben.

Ausserdem: Version 2.0.3.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-09-03 11:43:02 +02:00
2026-09-02 18:00:06 +02:00

TESM

Verwaltung von PoE-Geräten und Aruba-Switchen: Inventar, Zustandsüberwachung, Portsteuerung, Neustart (PoE, SSH, RPC), DHCP über Kea, Dateifreigaben, Wartung über SSH, Protokolle, Papierkorb, verschlüsselte Ein- und Ausfuhr und ein SSH-Terminal im Browser.

Dieses Repository enthält genau das, was zum Installieren und Betreiben von TESM gebraucht wird -- nichts darüber hinaus:

apps/tesm                   die Anwendung
packages/tesm-core          gemeinsamer Kern (Anmeldung, Rechte, Sicherung, nginx, ...)
packages/tesm-licensing     Lizenzprotokoll, Clientseite
deploy/                     install.sh, update.sh, release.sh, systemd, privilegierter Helfer
docs/                       Betrieb und Sicherheit

Die Serverhälfte des Lizenzprotokolls (tesm-licensing-server: ausstellen, erneuern, Antworten signieren) liegt nicht hier. TESM verifiziert Lizenzen und stellt Anfragen; den Code zum Ausstellen soll ein Client nicht einmal mitbringen.

Wo sonst noch
alientim/tesm-license der Lizenzserver
alientim/TESM-DEV Entwicklung: beide Anwendungen, Tests, Architekturdoku

Zweige

Zweig Inhalt
main dieser Neubau (Version 2.0.0)
SONNET5 der Stand davor, unverändert aufbewahrt

Installation

sudo bash deploy/install.sh --app tesm --https
sudo -u tesm tesm-admin create-admin

Danach https://<host>/. Ohne --domain entsteht ein selbstsigniertes Zertifikat; der Browser warnt einmal, die Verbindung ist verschlüsselt.

Mit öffentlichem Namen und Let's Encrypt stattdessen:

sudo bash deploy/install.sh --app tesm --https --domain tesm.firma.de --acme-email it@firma.de

Zielzustand: Port 443 mit TLS, Port 80 leitet dorthin um -- ausser dem ACME-Pfad, der erreichbar bleiben muss, sonst kann Let's Encrypt nie erneuern.

Sitzt ein eigener Reverse Proxy davor, der TLS beendet, läuft TESM ohne --https schlicht auf Port 80.

Eine zweite Installation zum Testen stört die laufende nicht:

sudo bash deploy/install.sh --app tesm --instance test --port 5100 --http-port 8080

Jede Instanz bekommt eigene Datenbank, eigene Schlüssel, eigene nginx-Site und ein eigenes Sitzungscookie.

Aktualisieren

sudo bash deploy/update.sh --app tesm

Das lädt ein Release, entpackt es und ruft dessen install.sh auf. Vor jedem Update entsteht ein vollständiges Backup -- unabhängig davon, ob sich das Schema geändert hat -- und danach läuft ein Health-Check mit automatischem Rollback.


Betrieb von der Kommandozeile

sudo -u tesm tesm-admin status              # Zustand der Installation
sudo -u tesm tesm-admin create-admin        # Konto anlegen oder zurücksetzen
sudo -u tesm tesm-admin check-now           # Überwachungsdurchlauf sofort
sudo -u tesm tesm-admin housekeeping        # Sitzungen und Protokolle aufräumen
sudo -u tesm tesm-admin web-setup --https   # nginx und TLS einrichten

Umzug aus dem alten TESM

Ein Export des Vorgängers lässt sich übersetzen und dann über den normalen Import einlesen -- Clients, Switche, Zugangsdaten und die DHCP-Konfiguration:

sudo -u tesm tesm-admin convert-legacy tesm_export_20260813_195455.json --dry-run

--dry-run zeigt nur den Bericht. Ohne die Option entsteht eine Datei im neuen Format, die unter Verwaltung -> Sicherung eingelesen wird. Der Bericht nennt ausdrücklich, was nicht übersetzt werden kann (lokale Konten, Rechte, Verzeichnisdienst, Webserver) -- das ist von Hand nachzuziehen.

Die Passphrase gehört an die verdeckte Eingabeaufforderung. --passphrase existiert nur für Automatisierung: es schreibt sie in Shell-Historie und Prozessliste.


Release bauen

git tag -a v2.0.0 -m "TESM 2.0.0" && git push origin v2.0.0
bash deploy/release.sh v2.0.0

Heraus kommt tesm-v2.0.0.tar.gz samt SHA-256. Der Name kommt aus dem Repository, nicht aus einer festen Zeichenkette.


Dokumentation

docs/BETRIEB.md Installation, Update, HTTPS, Sicherung, Fehlersuche
docs/SICHERHEIT.md Anmeldung, Sitzungen, CSRF, Geheimnisse, Rechtetrennung

Aufbau und Entwurfsentscheidungen stehen in docs/ARCHITEKTUR.md im Entwicklungsrepository, ebenso die Tests.


Was diese Fassung anders macht

Ein Neubau. Die Fehler des Vorgängers sind bekannt; an den Stellen, an denen sie entstanden sind, steht jetzt ein Kommentar, der erklärt, warum es hier anders gelöst ist. Die wichtigsten:

  • Kein root für die Anwendung. Ein einziger allowlisted Helfer mit Argumentprüfung statt eines Webprozesses als root.
  • CSRF-Schutz überhaupt. Der Vorgänger hatte keinen.
  • Rechte werden serverseitig geprüft, nicht nur im Template ausgeblendet.
  • Die nginx-Site wird bei jedem Lauf inhaltlich verglichen und erneuert. Ein falscher alias-Pfad überlebte im Vorgänger jahrelang jedes Update.
  • Jede erzeugte Konfiguration wird vor dem Übernehmen geprüft -- nginx wie Kea. Eine fehlerhafte Datei fällt beim Schreiben auf, nicht erst beim nächsten Start des Dienstes.
  • Kein Hostname im Lizenz-Fingerabdruck. Umbenennen brach die Bindung.
  • Zwei Installationen stören sich nicht -- eigener SITE_KEY für nginx-Site, netplan, logrotate, Zertifikate und Sitzungscookie.
  • Verschachtelte Datenbankverbindungen sind ein Fehler, kein Deadlock.
S
Description
Modernes UI-Rebuild des Aruba-PoE Managers (Dashboard, Rechtesystem, Browser-SSH-Terminal)
Readme
3.1 MiB
TESM 2.0.9
Latest
2026-09-03 16:18:53 +02:00
Languages
Python 65.7%
HTML 20.6%
Shell 6.5%
CSS 4.6%
JavaScript 2.6%