Files
tesm-license/README.md
T
alientimandClaude Opus 5 6ac2ed0a62 Nur noch, was zum Installieren und Betreiben des Lizenzservers noetig ist
Entfernt: Tests, Architekturdokumentation und die Anwendung TESM. Beides liegt
im Entwicklungsrepository alientim/TESM-DEV.

Neu: packages/tesm-licensing-server -- die Serverhaelfte des Lizenzprotokolls
(issue_license, resign_license, build_master_response, verify_client_request,
Schluesselerzeugung). Sie war bisher Teil von tesm-licensing und lag damit auch
in jeder Client-Installation. Die gemeinsame Haelfte bleibt in tesm-licensing
und wird von beiden Seiten benutzt.

install.sh installiert diese Serverhaelfte ausschliesslich fuer
--app tesm-license und bricht ab, wenn sie fehlt.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-09-02 18:37:12 +02:00

138 lines
5.0 KiB
Markdown

# TESM-Lizenzserver
Ausgabe und Verwaltung der Lizenzen fuer TESM: Kunde -> Ticket -> Lizenz,
Aktivierung online und offline, Kundenportal, Selbstbedienung, Versand ueber
MS Graph und eine Hierarchie aus Unter-Lizenzservern.
**Dieses Repository enthaelt genau das, was zum Installieren und Betreiben des
Lizenzservers gebraucht wird** -- nichts darueber hinaus:
```
apps/tesm-license die Anwendung
packages/tesm-core gemeinsamer Kern (Anmeldung, Rechte, Sicherung, nginx, ...)
packages/tesm-licensing Lizenzprotokoll, gemeinsame Haelfte
packages/tesm-licensing-server Lizenzprotokoll, Serverhaelfte: ausstellen, erneuern, antworten
deploy/ install.sh, update.sh, release.sh, systemd, privilegierter Helfer
docs/ Betrieb und Sicherheit
```
Die verwaltete Anwendung liegt hier **nicht** mit drin.
| Wo sonst noch | |
|---|---|
| [alientim/tesm](https://gitea.int.eertmoed.net/alientim/tesm) | TESM selbst |
| [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, unveraendert aufbewahrt |
---
## Installation
```bash
sudo bash deploy/install.sh --app tesm-license --https --domain lizenz.firma.de
sudo -u tesm-license tesm-license-admin init-key
sudo -u tesm-license tesm-license-admin bootstrap
sudo -u tesm-license tesm-license-admin create-admin
```
**`init-key` erzeugt den Signaturschluessel dieses Servers. Sichern Sie ihn
sofort.** Ohne ihn laesst sich keine ausgestellte Lizenz mehr erneuern, und
Kunden muessten einen Ausstellerwechsel bestaetigen.
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 der Dienst ohne
`--https` schlicht auf Port 80.
Der Lizenzserver darf neben TESM auf demselben Host laufen; nginx unterscheidet
die beiden am Servernamen, und jede Installation hat ihren eigenen `SITE_KEY`
fuer nginx-Site, logrotate, Zertifikate und Sitzungscookie.
### Aktualisieren
```bash
sudo bash deploy/update.sh --app tesm-license
```
Vor jedem Update entsteht ein vollstaendiges Backup, danach laeuft ein
Health-Check mit automatischem Rollback.
---
## Betrieb von der Kommandozeile
```bash
sudo -u tesm-license tesm-license-admin status
sudo -u tesm-license tesm-license-admin init-key # Signaturschluessel
sudo -u tesm-license tesm-license-admin bootstrap # Grunddaten
sudo -u tesm-license tesm-license-admin create-admin
sudo -u tesm-license tesm-license-admin migrate-legacy # Altbestand uebernehmen
```
`migrate-legacy` liest die SQLite-Datei eines alten Lizenzservers **nur
lesend**, uebernimmt dessen Signaturschluessel und stellt die Lizenzen mit ihrer
restlichen Laufzeit neu aus. Wird der Schluessel nicht uebernommen, muessen
Kunden den Ausstellerwechsel einmal bestaetigen.
---
## Release bauen
```bash
git tag -a v2.0.0 -m "TESM-Lizenzserver 2.0.0" && git push origin v2.0.0
bash deploy/release.sh v2.0.0
```
Heraus kommt `tesm-license-v2.0.0.tar.gz` samt SHA-256. Der Name kommt aus dem
Repository -- ein Lizenzserver-Release, das `tesm-...` heisst, verwechselt man
genau einmal.
---
## Lizenzprotokoll in Kurzform
* Ed25519, getrennte Signaturkontexte je Nachrichtenart
(`tesm/license-file/v2\0`) -- eine Signatur aus einem Kontext ist in einem
anderen nicht verwendbar.
* Kanonisches JSON, damit dieselbe Aussage genau eine Signatur hat.
* Nonce gegen Wiedereinspielung, `seq` gegen das Zurueckrollen auf eine aeltere
Lizenz.
* Aussteller wird beim ersten Kontakt gemerkt (TOFU); ein Wechsel muss
ausdruecklich bestaetigt werden.
* Der Fingerabdruck der Maschine enthaelt **keinen** Hostnamen -- Umbenennen
brach im Vorgaenger die Bindung.
* Offline-Aktivierung ueber einen kurzen Code in beide Richtungen; die Lizenz
bleibt auf dem Server als "Aktivierung offen" markiert, bis sie zurueckkommt.
* Keine Lizenz ohne `master_endpoint`: eine Ausstellung ohne Endpunkt wird
abgelehnt statt eine Lizenz zu erzeugen, die sich nie aktivieren kann.
---
## 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
* **Keine doppelte `licensing.py`.** Ein Paket, das beide Anwendungen
installieren -- statt zweier Dateien, die byte-identisch bleiben sollen.
* **Kein root fuer die Anwendung.** Ein einziger allowlisted Helfer mit
Argumentpruefung.
* **CSRF-Schutz ueberhaupt.** Der Vorgaenger hatte keinen.
* **Rechte werden serverseitig geprueft**, nicht nur im Template ausgeblendet.
* **Verschachtelte Datenbankverbindungen sind ein Fehler**, kein Deadlock.