Lizenzserver — Administrationshandbuch

Erstellt: 2026-06-16 · Aktualisiert: 2026-06-16

Dieses Dokument beschreibt serverseitige Administrations­aufgaben für den PPPTools-Lizenzserver. Es richtet sich ausschliesslich an den Server-Administrator.


Architektur: Offline-Lizenzprüfung

PPPTools verwendet signierte Lizenz-Tokens (RSA-SHA256). Das bedeutet:

  • Der Server stellt bei jeder Aktivierung und Validierung einen signierten Token aus
  • Das AddIn prüft die Signatur lokal — ohne Netzwerkverbindung
  • Die Lizenz bleibt für bis zu 30 Tage offline gültig (Grace Period)
  • Alle 7 Tage holt das AddIn im Hintergrund automatisch einen neuen Token

Der Token enthält: kid, license_key, tier, machine_id, user_name, user_email, user_company, user_country, registered_at, valid_until, issued_at.


RSA-Schlüsselverwaltung

Schlüsselpaar erstellen (Ersteinrichtung)

cd /pfad/zu/PPPTools_License
python generate_keys.py

Erzeugt app_public/keys/k1.pem (Private Key) und gibt das XML für den Public Key aus.

Das ausgegebene XML wird in SSM_LicenseManager.cs im PublicKeys-Dictionary eingetragen:

private static readonly Dictionary<string, string> PublicKeys =
    new Dictionary<string, string>
{
    { "k1", "<RSAKeyValue><Modulus>...</Modulus><Exponent>AQAB</Exponent></RSAKeyValue>" },
};

Private Key niemals committen

app_public/keys/*.pem ist in .gitignore eingetragen. Der Private Key darf den Server nie verlassen. Bei einem Deployment (git pull) muss die Datei manuell auf dem Server verbleiben.

Welcher Key ist aktiv?

Der aktive Signing-Key wird über die Umgebungsvariable ACTIVE_KEY_ID gesteuert (Standard: k1).

# In der .env-Datei oder systemd-Unit:
ACTIVE_KEY_ID=k1

Key-Rotation

Eine Rotation ist nötig wenn:

  • Der Private Key kompromittiert wurde oder verloren gegangen ist
  • Der Key als Sicherheitsmassnahme regelmässig gewechselt werden soll

Voraussetzung: Warum eine Übergangszeit nötig ist

Das AddIn hat den Public Key hardcoded. Clients, die noch keinen AddIn-Update erhalten haben, kennen den neuen Key noch nicht. Gleichzeitig sind bestehende Tokens noch bis zu 30 Tage offline gültig — das AddIn muss also den alten Key noch verifizieren können.

Der Ablauf ist deshalb in vier Schritte aufgeteilt:


Schritt 1 — Neues Schlüsselpaar generieren

python generate_keys.py k2

Erzeugt app_public/keys/k2.pem und gibt das XML aus. Den XML-String notieren.


Schritt 2 — AddIn-Update: neuen Public Key eintragen

Im AddIn SSM_LicenseManager.cs den neuen Key zusätzlich eintragen (alter Key bleibt!):

private static readonly Dictionary<string, string> PublicKeys =
    new Dictionary<string, string>
{
    { "k1", "..." },   // alter Key — bleibt noch 30 Tage drin
    { "k2", "..." },   // neuer Key — ab jetzt bekannt
};

AddIn-Release deployen. Ab diesem Moment kennen alle Clients beide Keys.


Schritt 3 — Server auf neuen Key umschalten (nach AddIn-Rollout)

Sobald die neue AddIn-Version verbreitet ist (erfahrungsgemäss 1–2 Tage nach Release):

# In .env anpassen:
ACTIVE_KEY_ID=k2

Server neu starten. Ab jetzt werden alle neuen Tokens mit k2 signiert. Bestehende k1-Tokens (aus dem Cache) sind noch bis zu 30 Tage gültig.


Schritt 4 — Alten Key entfernen (nach 30 Tagen)

Nach mindestens 30 Tagen haben alle Clients einen neuen k2-Token erhalten. Jetzt den alten Key aus dem AddIn entfernen:

private static readonly Dictionary<string, string> PublicKeys =
    new Dictionary<string, string>
{
    // "k1" entfernt
    { "k2", "..." },
};

Erneutes AddIn-Release. Den k1.pem vom Server löschen.


Zeitplan Übersicht

Tag Aktion
0 k2 generieren, in AddIn eintragen, AddIn-Release
1–2 Warten bis neues AddIn verbreitet ist
2 ACTIVE_KEY_ID=k2 auf Server setzen, Server neu starten
32+ k1 aus AddIn entfernen, k1.pem vom Server löschen

Serverstruktur (Referenz)

PPPTools_License/
  app_public/
    keys/
      k1.pem          ← Private Key (nie in Git!)
      k2.pem          ← bei Rotation
    crypto_token.py   ← Token-Erstellung
    routers/api.py    ← activate / validate Endpunkte
  generate_keys.py    ← Key-Generator (einmalig ausführen)
  .gitignore          ← app_public/keys/*.pem ausgeschlossen

Umgebungsvariablen

Variable Standard Beschreibung
ACTIVE_KEY_ID k1 Welcher Private Key neue Tokens signiert
DATABASE_URL SQLAlchemy-Verbindungsstring zur Lizenz-DB
UMAMI_URL https://umami.happy-pc.ch Analytics-Endpoint
UMAMI_WEBSITE_ID Website-ID für Umami-Tracking

Notfall: Key kompromittiert

Wenn der Private Key in falsche Hände geraten ist:

  1. k1.pem sofort vom Server löschen — Server neu starten (neue Tokens mit kompromittiertem Key werden jetzt nicht mehr ausgestellt)
  2. Neues Schlüsselpaar k2 generieren (Schritt 1–3 oben, ohne Wartezeit)
  3. AddIn-Update mit k2 sofort releasen
  4. Bestehende Clients haben noch bis zu 30 Tage einen gültigen (alten) Token — das ist akzeptabel, da nur Tokens ausgestellt werden, nicht reaktiviert

Revocation

Einzelne Lizenzen können über das Admin-Panel deaktiviert werden (Status revoked). Beim nächsten Online-Sync (spätestens nach 7 Tagen) schlägt die Validierung fehl und der Token wird verworfen.