# TESM Verwaltung von PoE-Geraeten und Aruba-Switchen: Inventar, Zustandsueberwachung, Portsteuerung, Neustart (PoE, SSH, RPC), DHCP ueber Kea, Dateifreigaben, Wartung ueber SSH, Protokolle, Papierkorb, verschluesselte Ein- und Ausfuhr und ein SSH-Terminal im Browser. Der Lizenzserver liegt in einem eigenen Repository: [alientim/tesm-license](https://gitea.int.eertmoed.net/alientim/tesm-license). Beide teilen sich den Kern (`packages/tesm-core`) und das Lizenzprotokoll (`packages/tesm-licensing`); diese Pakete sind hier mit enthalten, damit sich das Repository allein installieren laesst. ## Zweige | Zweig | Inhalt | |---|---| | `main` | dieser Neubau (Version 2.0.0) | | `SONNET5` | der Stand davor, unveraendert aufbewahrt | --- ## Installation auf einem Server ```bash sudo bash deploy/install.sh --app tesm --https sudo -u tesm tesm-admin create-admin ``` Danach `https:///`. Ohne `--domain` entsteht ein selbstsigniertes Zertifikat; der Browser warnt einmal, die Verbindung ist verschluesselt. Mit oeffentlichem Namen und Let's Encrypt stattdessen: ```bash 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, laeuft TESM ohne `--https` schlicht auf Port 80. Eine zweite Installation zum Testen stoert die laufende nicht: ```bash sudo bash deploy/install.sh --app tesm --instance test --port 5100 --http-port 8080 ``` Jede Instanz bekommt eigene Datenbank, eigene Schluessel, eigene nginx-Site und ein eigenes Sitzungscookie. ### Aktualisieren ```bash sudo bash deploy/update.sh --app tesm ``` Das laedt ein Release, entpackt es und ruft dessen `install.sh` auf. Vor jedem Update entsteht ein vollstaendiges Backup -- unabhaengig davon, ob sich das Schema geaendert hat -- und danach laeuft ein Health-Check mit automatischem Rollback. --- ## Release bauen ```bash 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. --- ## Entwicklung ```bash python -m venv .venv && . .venv/bin/activate pip install -e packages/tesm-licensing -e packages/tesm-core -e apps/tesm pip install pytest pytest tests -q ``` Ohne gesetzte Umgebungsvariablen legt die Anwendung ihre Daten unter `instance/tesm/` im Arbeitsverzeichnis an -- kein Zugriff auf `/srv` oder `/var/log` noetig. ```bash TESM_DEBUG=1 flask --app tesm run ``` Im Debug-Modus wird `COOKIE_SECURE` abgeschaltet, sonst kaeme das Sitzungscookie ueber `http://127.0.0.1` nie an. --- ## Verwaltung von der Kommandozeile ```bash sudo -u tesm tesm-admin status # Zustand der Installation sudo -u tesm tesm-admin create-admin # Konto anlegen oder zuruecksetzen sudo -u tesm tesm-admin check-now # Ueberwachungsdurchlauf sofort sudo -u tesm tesm-admin housekeeping # Sitzungen und Protokolle aufraeumen sudo -u tesm tesm-admin web-setup --https # nginx und TLS einrichten ``` ### Umzug aus dem alten TESM Ein Export des Vorgaengers laesst sich uebersetzen und dann ueber den normalen Import einlesen -- Clients, Switche, Zugangsdaten und die DHCP-Konfiguration: ```bash 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 ausdruecklich, was **nicht** uebersetzt werden kann (lokale Konten, Rechte, Verzeichnisdienst, Webserver) -- das ist von Hand nachzuziehen. Die Passphrase gehoert an die verdeckte Eingabeaufforderung. `--passphrase` existiert nur fuer Automatisierung: es schreibt sie in Shell-Historie und Prozessliste. --- ## Dokumentation | | | |---|---| | [docs/ARCHITEKTUR.md](docs/ARCHITEKTUR.md) | Aufbau, Schnitte und die Gruende dafuer | | [docs/SICHERHEIT.md](docs/SICHERHEIT.md) | Anmeldung, Sitzungen, CSRF, Geheimnisse, Rechtetrennung | | [docs/BETRIEB.md](docs/BETRIEB.md) | Installation, Update, HTTPS, Sicherung, Fehlersuche | --- ## Tests ```bash pytest tests -q ``` Dazu ein Skript, das **auf dem Zielhost gegen die laufende Installation** spricht -- ueber nginx, gunicorn und echtes TLS. Es wird nicht mitinstalliert (`install.sh` laesst `tests/` aus); bei Bedarf dorthin kopieren. Jeder Lauf legt eigene Datensaetze an, ist also beliebig oft wiederholbar: ```bash python3 tests/e2e_smoke.py https://host admin 'Passwort' ``` --- ## Was diese Fassung anders macht Ein Neubau. Die Fehler des Vorgaengers sind bekannt; an den Stellen, an denen sie entstanden sind, steht jetzt ein Kommentar, der erklaert, warum es hier anders geloest ist. Die wichtigsten: * **Kein root fuer die Anwendung.** Ein einziger allowlisted Helfer mit Argumentpruefung statt eines Webprozesses als `root`. * **CSRF-Schutz ueberhaupt.** Der Vorgaenger hatte keinen. * **Rechte werden serverseitig geprueft**, nicht nur im Template ausgeblendet. * **Die nginx-Site wird bei jedem Lauf inhaltlich verglichen und erneuert.** Ein falscher `alias`-Pfad ueberlebte im Vorgaenger jahrelang jedes Update. * **Kein Hostname im Lizenz-Fingerabdruck.** Umbenennen brach die Bindung. * **Zwei Installationen stoeren sich nicht** -- eigener `SITE_KEY` fuer nginx-Site, netplan, logrotate, Zertifikate und Sitzungscookie. * **Verschachtelte Datenbankverbindungen sind ein Fehler**, kein Deadlock. * **Jede Konfiguration wird vor dem Uebernehmen geprueft** -- nginx wie Kea. Eine fehlerhafte Datei faellt beim Schreiben auf, nicht erst beim naechsten Start des Dienstes.