# 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](https://gitea.int.eertmoed.net/alientim/tesm-license) | der Lizenzserver | | [alientim/TESM-DEV](https://gitea.int.eertmoed.net/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 ```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 verschlüsselt. Mit öffentlichem 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, läuft TESM ohne `--https` schlicht auf Port 80. Eine zweite Installation zum Testen stört die laufende nicht: ```bash 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 ```bash 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 ```bash 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: ```bash 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 ```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. --- ## Dokumentation | | | |---|---| | [docs/BETRIEB.md](docs/BETRIEB.md) | Installation, Update, HTTPS, Sicherung, Fehlersuche | | [docs/SICHERHEIT.md](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. --- ## Von einer Installation der Fassung 1.x Eine einzelne Datei genügt -- sie lädt das Release selbst: ```bash curl -fsSLO https://gitea.int.eertmoed.net/alientim/tesm/raw/branch/main/deploy/upgrade.sh sudo bash upgrade.sh --app tesm ``` Sichert die alte Installation, schaltet sie ab, installiert diese Fassung und übernimmt die Daten. Einzelheiten und was **nicht** mitkommt: [docs/BETRIEB.md](docs/BETRIEB.md).