# Umstellung auf Version 2.0 — Ablaufplan Diese Fassung enthält Sicherheitskorrekturen, die das Verhalten der Schnittstellen ändern. Bitte in dieser Reihenfolge vorgehen. --- ## 1. Vor dem Deployment: Zugangsdaten wechseln `Serverdaten.txt`, `config/config.php`, `config/.htpasswd` und `scripts/deploy_config.json` lagen im Git-Repository. Sie sind jetzt per `.gitignore` ausgeschlossen und aus dem Index entfernt — **die Git-Historie enthält sie aber weiterhin**. Alle betroffenen Zugangsdaten sind daher als kompromittiert zu behandeln: - [ ] MySQL-Passwort ändern, danach in `config/config.php` eintragen - [ ] FTP-Passwort ändern, danach in `scripts/deploy_config.json` eintragen - [ ] `.htpasswd`-Passwort für `deploy` neu setzen - [ ] Git-Token `eb429575…` widerrufen und neu ausstellen - [ ] Admin-Passwort im WebUI ändern (die alte Fassung setzte es bei jedem Aufruf von `install_db.php` auf `Admin1337!` zurück — jeder im Internet konnte das auslösen) Wenn die Historie bereinigt werden soll, geht das mit [`git filter-repo`](https://github.com/newren/git-filter-repo). Das schreibt alle Commit-Hashes um; bei einem Repository mit mehreren Nutzern vorher abstimmen. --- ## 2. Konfiguration ergänzen `config/config.php` braucht drei neue Schlüssel unter `security`. Die mitgelieferte Datei enthält bereits erzeugte Werte; für eine neue Installation: ```bash cp config/config.example.php config/config.php openssl rand -hex 32 # je einmal für shared_key, webhook_key, license_key ``` | Schlüssel | Zweck | |---|---| | `security.shared_key` | Server-zu-Server-Aufrufe: Evaluator-Cron, Migration, Deaktivierung | | `security.webhook_key` | HMAC-Signatur ausgehender Webhooks | | `security.license_key` | Signatur der Offline-Lizenzdateien (`.lic`) | | `app.debug` | Auf Produktivsystemen `false` — steuert, ob Exception-Texte ausgeliefert werden | > Der bisherige `shared_key` (`DC_MASTER_SECURE_TOKEN_2026_x98f`) stand im > Repository und wurde ersetzt. Wer ihn irgendwo eingetragen hat — etwa für > `/api/license/v1/deactivate` — muss den neuen Wert nachziehen. --- ## 3. Deployment ```bash python scripts/deploy.py ``` Das Skript überträgt unter anderem die neuen Verzeichnisse `var/` (Logs) und die zusätzlichen `.htaccess`-Dateien in `config/`, `src/` und `sql/`. --- ## 4. Migration ausführen Im WebUI anmelden, dann **System → DB-Migration → Migration jetzt ausführen**. Alternativ über die Kommandozeile: ```bash php public/install_db.php ``` Oder mit dem Shared Key: ```bash curl -H "Authorization: Bearer " https://dc.mhdf.de/install_db.php ``` Die Migration ist additiv und legt an bzw. korrigiert: - `dc_migrations` — vermerkt angewendete Versionen, damit nichts doppelt läuft - `dc_login_attempts` — Drosselung fehlgeschlagener Anmeldungen - `dc_webhooks` — ausgehende Benachrichtigungen - Bugtracker: Claim/Lease, `client_ref`, `dedup_key`, Code-Kontextfelder, Indizes - Watchdog: `last_state_change_utc`, `down_since_utc`, Zustand `unknown` - **Reparatur von Migration 005** — deren Spalten (`push_id`, `target_agent`, `tags`) fehlten bisher auf Datenbanken, die aus Migration 004 stammen. Die alte Fassung nutzte dynamisches SQL, dessen Semikolons in String-Literalen vom damaligen Installer als Statement-Ende gelesen wurden; die Fehler wurden stillschweigend verschluckt. - **Reparatur der Token-Hashes** — die Validierung vergleicht jetzt nur noch den SHA-256-Hash. Die geseedeten Beispiel-Tokens trugen Hashes, die nicht zu ihrem Klartext passten; sie werden korrigiert, damit bestehende Tokens weiterhin funktionieren. --- ## 5. Cron für den Watchdog-Evaluator einrichten **Ohne diesen Schritt sind die Monitor-Zustände wertlos.** Der Evaluator fehlte bisher vollständig — der Zustand änderte sich nur beim Eintreffen eines Heartbeats, ein ausgefallener Server blieb dauerhaft grün. ```bash * * * * * curl -fsS -H "Authorization: Bearer " https://dc.mhdf.de/api/watchdog/v1/evaluate > /dev/null ``` Solange der Job fehlt, zeigt das WebUI oben einen Warnhinweis mit einer Schaltfläche für einen einmaligen Lauf. --- ## 6. Agenten-Tokens ausstellen Die Ingest-Endpunkte verlangen jetzt zwingend ein Token. 1. WebUI → **Token-Verwaltung → Master-Token erstellen** 2. Scopes wählen (für einen Coding-Agenten: `bugtracker:report`, `bugtracker:read`, `bugtracker:manage`) 3. Master-Token einmalig kopieren und auf dem Agenten-Rechner als `DC_TOKEN` hinterlegen — oder den Agenten per `/api/tokens/v1/provision` ein eigenes Sub-Token ziehen lassen --- ## 7. Bestehende Integrationen anpassen | Betroffen | Was zu tun ist | |---|---| | Aufrufe von `/api/bugtracker/v1/report` ohne Token | Token-Header ergänzen | | Aufrufe von `/api/bugtracker/v1/projects` ohne Token | Token-Header ergänzen | | Skripte, die Releases veröffentlichen | Token mit `updateservice:publish` ergänzen | | Auswertung der Antworten | Neues Format: `{"status":"success",…}` bzw. `{"status":"error","error":{"code":…}}` | | Watchdog-Agenten mit `wd_live_…`-Token | Laufen unverändert weiter | | Clients, die `/api/updateservice/v1/check` aufrufen | Unverändert, weiterhin ohne Token | | Clients, die `/api/license/v1/validate` aufrufen | Unverändert, weiterhin ohne Token | --- ## 8. Zeitzonen Datenbankzeitstempel liegen jetzt durchgängig in **UTC**; das WebUI rechnet für die Anzeige in `app.timezone` (Europe/Berlin) um. Vorhandene Datensätze wurden in Serverzeit geschrieben und erscheinen daher einmalig um den Zeitzonenversatz verschoben. Für Monitoring-Daten ist das ohne Bedeutung, für den Audit-Log gegebenenfalls beachten. --- ## 9. Prüfen, ob alles läuft ```bash curl https://dc.mhdf.de/api/health -H "Authorization: Bearer " ``` Erwartet wird `"healthy": true`, eine leere `schema.pending`-Liste und ein `checks.evaluator.ok` von `true`. Zusätzlich stichprobenartig im WebUI prüfen: - [ ] Anmeldung funktioniert - [ ] Projekt anlegen und wieder löschen - [ ] Monitor bearbeiten — das Feld **Betriebssystem** bleibt nach dem Speichern erhalten (wurde zuvor bei jedem Speichern geleert) - [ ] Bugtracker: „🔍 Details" öffnet den Dialog, „✔" öffnet den Lösen-Dialog (dessen HTML fehlte bisher komplett) - [ ] Token widerrufen und löschen (warf zuvor `HY093`) - [ ] Lizenz-Aktivierung freigeben (warf zuvor `Class "Audit" not found`) - [ ] Nach dem Speichern F5 drücken — es entsteht kein zweiter Eintrag mehr --- ## 10. Optional: Webhooks Ereignisgesteuerte Benachrichtigung statt Polling. Ziel direkt in der Datenbank eintragen: ```sql INSERT INTO dc_webhooks (name, url, project_slug, events, secret, enabled) VALUES ('Telegram Alarm', 'https://n8n.example.com/webhook/dc', NULL, 'bug.critical,monitor.down', 'geheimnis', 1); ``` Verfügbare Ereignisse: `bug.created`, `bug.critical`, `bug.resolved`, `feature.created`, `monitor.down`, `monitor.recovered`, `release.published`, oder `*` für alle. Jede Zustellung trägt eine Signatur: ``` X-DC-Timestamp: 1754563200 X-DC-Signature: sha256= ``` Nach 20 Fehlversuchen in Folge deaktiviert sich ein Webhook selbst.