feat(releases): Zugangsschutz ueber Lizenzschluessel
/releases/ wurde bisher offen ausgeliefert, damit ausgelieferte Anwendungen ohne Zugangsdaten nach Updates suchen koennen. Das bedeutete aber auch, dass jeder im Internet die vollstaendigen Pakete herunterladen konnte - mitsamt allem, was versehentlich darin liegt. Genau so lag ein echter API-Schluessel in einer mitgelieferten appsettings.json oeffentlich abrufbar. Zugang haengt jetzt am Lizenzschluessel: Wer eine gueltige Lizenz fuer ein Produkt hat, kommt an dessen Updates. Die Anwendung kennt ihren Schluessel ohnehin und versorgt sich damit selbst - es muss nichts verteilt werden. Server - ReleaseGuard erzeugt je Produktverzeichnis .htaccess und .htpasswd. Bewusst getrennt: eine gemeinsame Datei wuerde bedeuten, dass eine Lizenz fuer Produkt A auch Produkt B oeffnet. license_licenses.product_id bindet jeden Schluessel ohnehin an genau ein Projekt. - Eingetragen werden aktive, nicht abgelaufene Lizenzen (Benutzername = Passwort = Schluessel; Basic Auth braucht zwei Felder, es gibt aber nur ein Geheimnis) sowie alle Installationskonten - bei einer Erstinstallation gibt es noch keinen Schluessel, mit dem sich das Paket holen liesse. - Deren Hash wird unveraendert aus dc_users uebernommen: password_hash() erzeugt bcrypt im Format $2y$, genau das versteht Apache. Ein Klartextpasswort wird nirgends gebraucht. Argon2-Hashes werden erkannt und uebersprungen statt eine unbrauchbare Datei zu erzeugen. - Lizenzschluessel werden mit Kosten 8 gehasht statt 12: 29 Zeichen maschineller Zufall sind kein Menschenpasswort, Apache prueft aber bei *jeder* Anfrage neu. - Geschrieben wird ueber eine temporaere Datei mit rename() - ein Abbruch wuerde sonst eine halbe Zugangsdatei hinterlassen und in dem Moment die halbe Kundschaft aussperren. - Neu erzeugt bei jeder Lizenz- und Kontoaenderung. Abgelaufene Lizenzen loesen anders als ein Widerruf nichts aus; dafuer gleicht cli/tick.php nach und erzeugt spaetestens alle sechs Stunden neu. - Statusanzeige und Schaltflaeche im WebUI unter UpdateService. Client - ReleaseCredentials: Lizenzschluessel oder Installationskonto als Basic Auth. - UpdateClient und Agent senden sie fuer latest.json und package.tar.gz. - UpdateCheckResult.Unauthorized trennt "Lizenz traegt nicht mehr" von einem Netzwerkfehler. Ohne diese Unterscheidung sucht man an der falschen Stelle. - LaunchUpdateAgent reicht licenseKey als --license-key durch. - Der Installer benutzt die beim Anmelden eingegebenen Zugangsdaten auch fuer den Paketabruf; das Setup-Token taugt dafuer nicht, weil Apache prueft und nicht die Anwendung. Sonstiges - deploy.py klammert artifacts/ aus. Ohne das landeten die gebauten Installer-Binaries zusaetzlich unter /artifacts/ im Webroot. ACHTUNG Reihenfolge: Der Schutz sperrt jede Anwendung aus, die noch mit dem alten SDK gebaut ist. Erst ausliefern, dann scharfschalten - siehe UPGRADE.md §16. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 5
parent
7f41372e5f
commit
ceb977187e
@@ -47,6 +47,16 @@ irm https://dc.mhdf.de/installer/install.ps1 | iex
|
||||
| `/installer/update-agent-linux-arm64` | Linux ARM64 |
|
||||
| `/installer/installer.json` | Version, Größen und Prüfsummen aller Binaries |
|
||||
|
||||
**Der Installer-Download selbst bleibt offen** — die Binaries enthalten keine
|
||||
Zugangsdaten, und eine Anmeldung an dieser Stelle würde nur den Bootstrap
|
||||
verkomplizieren (Zugangsdaten in `wget --user=…` landen in der Shell-History).
|
||||
|
||||
Beim Ausführen fragt der Installer als Erstes nach Benutzername und Passwort.
|
||||
**Dieselben Zugangsdaten öffnen auch die Release-Ablage**, die seit Version 2.4
|
||||
hinter HTTP-Basic-Auth liegt — bei einer Erstinstallation gibt es noch keinen
|
||||
Lizenzschlüssel, mit dem sich das Paket holen ließe. Siehe
|
||||
**[UPDATESERVICE_INTEGRATION_GUIDE §5A](./UPDATESERVICE_INTEGRATION_GUIDE.md#5a-zugangsschutz-der-release-verzeichnisse)**.
|
||||
|
||||
Zu jedem Binary liegt eine `.sha256` daneben. **Die Prüfsumme vergleichen** —
|
||||
„Programm herunterladen und Zugangsdaten eingeben" ist genau das Muster, das
|
||||
Phishing nachahmt; die Prüfsumme ist der Grund, warum man es hier trotzdem tun
|
||||
@@ -65,7 +75,7 @@ NativeAOT und ohne Trimming — Spectre.Console löst seine Eingabeaufforderunge
|
||||
### Neu bauen und hochladen
|
||||
|
||||
```bash
|
||||
pwsh scripts/build_installer.ps1
|
||||
powershell -File scripts/build_installer.ps1
|
||||
python scripts/upload_installer.py ./artifacts/installer
|
||||
```
|
||||
|
||||
|
||||
Reference in New Issue
Block a user