Watchdog-Anleitung vollständig überarbeitet - Alle drei Codebeispiele trugen das geseedete Demo-Token fest im Quelltext. Es ist an die Source "srv-db-01" gebunden — wer es übernommen hätte, wäre für jeden anderen Dienst abgewiesen worden. Jetzt Umgebungsvariable und eine Anleitung, wie man ein eigenes Token erzeugt. - Der Ratschlag "sende beim Beenden einen Ping mit Status stopped" beschrieb etwas, das die API nicht konnte. Statt die Anleitung an die Lücke anzupassen, ist die Lücke geschlossen: status akzeptiert jetzt "stopped" und "maintenance". Der Evaluator lässt solche Monitore in Ruhe, statt wenige Minuten nach jedem sauberen Shutdown einen Fehlalarm zu erzeugen. - Neu dokumentiert: checks (Gesundheitszustand per Push, ohne offene Ports), metrics samt Verlauf und Abweichungsvergleich, Alarmunterdrückung über die Hierarchie, die Schwellen des Evaluators (2x warning, 4x down) und der erforderliche Cron-Job. Lizenz-Anleitung - Neuer Abschnitt zum Antwortformat. Die Lizenz-Endpunkte antworten bewusst ohne den status/error-Umschlag der übrigen API; das Feld status auf oberster Ebene trägt den Lizenzzustand. Genau diese Besonderheit hatte ich beim Umbau übersehen, weshalb sie jetzt ausdrücklich festgehalten ist — samt Tabelle aller Zustände. - Ergänzt: Deaktivierung braucht den shared_key, mit Beispiel für den .NET- Client und curl. Verhalten bei Ratenbegrenzung. UpdateService-Anleitung - Prüf-Endpunkte dokumentiert (check, latest, releases) samt Antwortformat. - Tabelle zum Versionsvergleich mit den Fällen, die vorher falsch liefen. - Auto-Resolve beim Veröffentlichen beschrieben. Agent-Prompt-Vorlage - Fehler-Schnittstelle ergänzt, inklusive Hinweis auf "ignored": true, damit ein Agent bekannte Fehler nicht untersucht. Alle in der Dokumentation genannten API-Pfade und Scopes wurden maschinell gegen Routing und TokenManager abgeglichen. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
282 lines
10 KiB
Markdown
282 lines
10 KiB
Markdown
# 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 <SHARED_KEY>" 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 <SHARED_KEY>" 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 <SHARED_KEY>"
|
|
```
|
|
|
|
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. Fehler-Stream (Migration 007)
|
|
|
|
Neu ist eine eigene Schnittstelle für Laufzeitfehler, gedacht für den globalen
|
|
Exception-Handler einer Anwendung:
|
|
|
|
```
|
|
POST /api/errors/v1/report
|
|
```
|
|
|
|
Gespeichert wird in derselben Tabelle wie der Bugtracker — ein zweiter Speicher
|
|
wäre nur ein zweiter Ort, an dem man suchen müsste. Die Trennung von Rauschen
|
|
und Signal leisten stattdessen **Ignore-Regeln**.
|
|
|
|
### Bekannte, harmlose Fehler stummschalten
|
|
|
|
Im WebUI unter **Bugtracker → 🔇 Ignore-Regeln**. Ein Treffer bedeutet nicht
|
|
„wegwerfen": Der Fehler wird weiterhin erfasst und hochgezählt, bleibt aber aus
|
|
der Übersicht heraus und löst keine Benachrichtigung aus.
|
|
|
|
Der Zähler ist dabei der eigentliche Zweck. Zu jeder Regel lässt sich eine
|
|
Alarmschwelle hinterlegen — dass ein bekannter Fehler auftritt, ist normal;
|
|
dass er plötzlich hundertmal so oft auftritt, bedeutet, dass sich etwas
|
|
geändert hat.
|
|
|
|
Eine deaktivierte Vorlage für den Duplicate-Entry-Fall liegt bereits vor; sie
|
|
lässt sich im WebUI anpassen und einschalten.
|
|
|
|
### Gruppierung
|
|
|
|
Veränderliche Anteile werden beim Zusammenfassen ausgeblendet: Werte in
|
|
Anführungszeichen, die Ziffern enthalten, Speicheradressen, GUIDs, Zeitstempel
|
|
und Zeilennummern. `Duplicate entry 'MKT-88213'` und `Duplicate entry 'AA-1'`
|
|
landen damit in einer Gruppe — ein anderer Unique-Key dagegen nicht.
|
|
|
|
> **Hinweis:** Migration 007 ändert die Berechnung des Gruppenschlüssels.
|
|
> Bereits erfasste Einträge behalten ihren alten Schlüssel; ein erneut
|
|
> auftretender Fehler legt daher einmalig eine neue Gruppe an. Danach ist der
|
|
> Zustand wieder konsistent.
|
|
|
|
## 11. Metrik-Verlauf und Health-Checks
|
|
|
|
Numerische Werte aus dem Heartbeat-Feld `metrics` werden jetzt mit Zeitstempel
|
|
abgelegt (Aufbewahrung 14 Tage) und lassen sich über
|
|
`GET /api/watchdog/v1/metrics` abfragen. Zuvor wurde `metrics_json` bei jedem
|
|
Heartbeat überschrieben — es gab immer nur den letzten Moment.
|
|
|
|
Zusätzlich kann eine Anwendung ihren Gesundheitszustand selbst mitschicken:
|
|
|
|
```json
|
|
{ "source": "polytrader-worker", "status": "ok", "interval": 60,
|
|
"checks": {
|
|
"db": { "ok": true },
|
|
"market_feed": { "ok": false, "message": "Letzter Tick vor 14 min" }
|
|
} }
|
|
```
|
|
|
|
Das Deploymentcenter interpretiert die Namen nicht — es liest nur `ok` und
|
|
`message`. Schlägt eine Prüfung fehl, wird ein als `ok` gemeldeter Heartbeat auf
|
|
`warning` herabgestuft. **Es müssen keine Ports geöffnet werden**, der Weg ist
|
|
ausgehend.
|
|
|
|
Neu sind außerdem die Statuswerte `stopped` und `maintenance`. Ohne sie erzeugte
|
|
jedes geplante Herunterfahren wenige Minuten später einen Fehlalarm — es gab
|
|
schlicht keinen Weg, ein beabsichtigtes Ende mitzuteilen:
|
|
|
|
```json
|
|
{ "source": "polytrader-worker", "status": "stopped",
|
|
"message": "Dienst planmäßig beendet" }
|
|
```
|
|
|
|
Der Evaluator lässt solche Monitore in Ruhe, bis wieder ein normaler Heartbeat
|
|
eintrifft.
|
|
|
|
## 12. Abhängigkeitsbewusste Alarmierung
|
|
|
|
Fällt ein Monitor aus, für den `parent_source` gesetzt ist, und ist der
|
|
übergeordnete Monitor selbst unten, wird der Alarm für das Kind unterdrückt.
|
|
Der Zustand bleibt im Dashboard sichtbar.
|
|
|
|
Vorher erzeugte ein ausgefallener Hypervisor mit zwölf VMs dreizehn Meldungen
|
|
für ein Problem.
|
|
|
|
Damit das greift, muss die Hierarchie gepflegt sein — im WebUI unter
|
|
**WatchDog → System-Hierarchie** über das Feld *Übergeordnete Entität*.
|
|
|
|
## 13. 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=<hex(hmac_sha256(secret, timestamp + "." + body))>
|
|
```
|
|
|
|
Nach 20 Fehlversuchen in Folge deaktiviert sich ein Webhook selbst.
|