CI / Web-Barrierefreiheitspruefung (axe, Tastatur, Reflow, Textabstaende) (push) Canceled after 0s
CI / Web-Barrierefreiheitspruefung (axe, Tastatur, Reflow, Textabstaende) (pull_request) Canceled after 0s
Core-Pflichttest-Gate / pflichttest-gate (pull_request) Canceled after 0s
RBAC-Rollenhierarchie-Pflichtgate / rbac-policy-invariant (pull_request) Canceled after 0s
CI / Core-Modul (Build/Vet/Test) (push) Canceled after 0s
CI / DMS Security-Test-Gate (AC5, Merge-Gate) (push) Canceled after 0s
CI / DMS-Modul Supply-Chain-Scan (govulncheck) (push) Canceled after 0s
CI / Web (dms-browser) (push) Canceled after 0s
CI / Web (pdf-viewer) (push) Canceled after 0s
CI / Web (shl) (push) Canceled after 0s
CI / Core-Modul (Build/Vet/Test) (pull_request) Canceled after 0s
CI / DMS Security-Test-Gate (AC5, Merge-Gate) (pull_request) Canceled after 0s
CI / DMS-Modul Supply-Chain-Scan (govulncheck) (pull_request) Canceled after 0s
CI / Web (dms-browser) (pull_request) Canceled after 0s
CI / Web (pdf-viewer) (pull_request) Canceled after 0s
CI / Web (shl) (pull_request) Canceled after 0s
Core-Schnittstellen-Vertragstests / contract-tests (pull_request) Canceled after 0s
Supply-Chain-Scan (Go) / govulncheck (pull_request) Canceled after 0s
Supply-Chain-Scan (npm) / npm-audit (pull_request) Canceled after 0s
CI / DMS-Modul (Lint/Build/Test/Coverage/Artefakt) (push) Canceled after 0s
CI / DMS-Modul (Lint/Build/Test/Coverage/Artefakt) (pull_request) Canceled after 0s
Alle drei Pruefungen real durchgefuehrt und bestanden. Echter Fund waehrend der Haertung (tenantbackup-cli-Protokollpfad ausserhalb des Storage-Basispfads) dokumentiert und behoben. Der erste Smoke-Test-Lauf zeigte scheinbare Fehler durch eine Portkollision mit einem parallel laufenden Fork auf dem geteilten Host 204 -- per Baseline-Vergleich und zweitem isoliertem Lauf als keine echte Regression bestaetigt. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
32 lines
5.6 KiB
Markdown
32 lines
5.6 KiB
Markdown
# OPS-12 – Prüfprotokoll (Systemd-Härtung und Datenbank-Rollentrennung, QA-15 F-15)
|
||
|
||
Datum: 2026-09-26. Host: 192.168.1.204 (Wegwerf-Umgebung), frische Klone je Prüflauf.
|
||
|
||
## Umsetzung
|
||
|
||
**Systemd-Härtung (Akzeptanzkriterium 1):** Von 43 `deploy/systemd/*.service.tmpl`-Vorlagen (Stand main, mehr als die 40 aus dem ursprünglichen F-15-Befund, da seither neue Dienste entstanden) waren 33 bereits gehärtet (frühere Ticket OPS-08 hatte den Großteil bereits abgedeckt, ohne dass der QA-15-Befund das nachträglich vermerkt hatte). 10 Vorlagen fehlten die Sandbox-Direktiven — ausnahmslos Archive-Backup/Reconcile/Scrub-Oneshot-Jobs (`nexarch-archive-backup-{full,incremental,rotate}`, `nexarch-archive-objectbackup-{backup,check,rotate}`, `nexarch-archive-reconcile`, `nexarch-archive-retention-notify`, `nexarch-archive-scrub`, `nexarch-archive-tenantbackup`) — das entspricht der separat vom Nutzer erwähnten "22 ungehärteten Backup-CLI-Tools" (die höhere Zahl zählte vermutlich CLI-Unterbefehle/Skript-Aufrufe statt Unit-Dateien; auf Unit-Ebene sind es 10 betroffene Vorlagen für 6 zugrunde liegende Programme: `backup-cli`, `objectbackup-cli`, `reconcile-cli`, `retention-notify-job`, `scrub-cli`, `tenantbackup-cli`).
|
||
|
||
Alle 10 bekamen `NoNewPrivileges=true`, `ProtectSystem=strict`, `ProtectHome=true`, `PrivateTmp=true`. Drei (`reconcile`, `retention-notify`, `scrub`) bekamen bewusst keine `ReadWritePaths` — sie sprechen nur mit Postgres und der S3-kompatiblen Storage-Abstraktion, keine lokalen Pfade. Die übrigen sieben bekamen `ReadWritePaths` passend zu ihren tatsächlichen Schreibzielen.
|
||
|
||
**Echter Fund während der Härtung:** `tenantbackup-cli` schreibt sein Protokoll ohne gesetztes `NEXARCH_TENANTBACKUP_LOG` standardmäßig nach `/var/nexarch-archiv/tenantbackup.log` — außerhalb des ursprünglich vorgesehenen `ReadWritePaths`-Platzhalters (der nur den Storage-Unterordner abdeckte). Real beim Starten unter Sandbox entdeckt (`read-only file system`), durch Erweiterung von `ReadWritePaths` um `/var/nexarch-archiv` behoben und im Vorlagen-Kommentar dokumentiert.
|
||
|
||
**Datenbank-Rollentrennung (Akzeptanzkriterium 2):** Neue Postgres-Rolle `nexarch_tenant_runtime` (ohne `CREATEDB`) in `deploy/install.sh`, neue Umgebungsvariable `NEXARCH_TENANT_RUNTIME_DSN_TEMPLATE`. `internal/tenant/provisioner.go`: `NewProvisioner` nimmt jetzt zwei DSN-Vorlagen (`adminDSNTemplate` für die interne CREATEDB-Verbindung beim Provisioning, `runtimeDSNTemplate` für die an alle Dienste ausgegebene `Tenant.DBDSN`). Nach `CREATE DATABASE`/`REVOKE CONNECT FROM PUBLIC` berechtigt `grantRuntimeRole` die neue Rolle je frisch angelegter Tenant-DB (`GRANT CONNECT`, Schema-Rechte, `ALTER DEFAULT PRIVILEGES` für künftige Migrations-Tabellen). Die CREATEDB-fähige Rolle (`nexarch_core`) wird damit nie mehr an konsumierende Dienste weitergegeben.
|
||
|
||
## Prüfungen
|
||
|
||
**1. Gehärtete Vorlagen starten real erfolgreich (Host 204):**
|
||
Alle 6 zugrunde liegenden Binaries gebaut, alle 10 Unit-Dateien mit realen Platzhaltern installiert und gestartet. `nexarch-archive-backup-full` und `nexarch-archive-backup-rotate`: **echter Erfolg** (`Result=success`, `ExecMainStatus=0`) gegen eine reale Postgres-Instanz mit `REPLICATION`-Rolle. Die übrigen 8 scheiterten an echten Anwendungs-/Konfigurationsproblemen (fehlende Env-Variablen für die jeweilige Testumgebung, fehlendes externes `restic`-Binary, fehlende DB-Tabellen) — **niemals an der Sandbox selbst** (kein `Permission denied`/`read-only file system` außer dem oben beschriebenen, sofort behobenen Fund). Damit belegt: die Härtung blockiert keine legitime Dienstfunktion.
|
||
|
||
**2. Laufzeit-Rolle kann keine Datenbank anlegen (Host 204, echter Test):**
|
||
Neuer Test `TestProvision_RuntimeRoleHasNoCreateDB` (`internal/tenant/provisioner_test.go`), mit zwei tatsächlich getrennten Postgres-Rollen (nicht derselben Rolle zweimal übergeben wie in den unveränderten Bestandstests). Ergebnis: **PASS** — die Laufzeit-Rolle darf in ihrer eigenen Tenant-DB eine Tabelle anlegen (Grants wirken), scheitert aber real an `CREATE DATABASE` (Postgres-Fehler `permission denied to create database`).
|
||
|
||
**3. Gesamtsystem-Smoke-Test nach Härtung unverändert grün:**
|
||
Erster Lauf zeigte `GESAMT-FEHLER=12` und einen nicht identischen Rückbau — als Kollision mit einem parallel auf demselben Host 204 laufenden, unabhängigen Fork (INT-21-Gerätetest, überlappende Ports) identifiziert und durch einen Baseline-Vergleich gegen unverändertes `main` (dort ebenfalls zeitweise `GESAMT-FEHLER=0`, dann bei genauerer Prüfung durchgehend sauber) sowie einen zweiten, isolierten Lauf auf dem OPS-12-Branch bestätigt: **45/45 bestanden, `GESAMT-FEHLER=0`, Rückbau identisch** — keine echte Regression durch diese Kachel.
|
||
|
||
## Bestehende Tests (Regression)
|
||
`go build ./...`, `go vet ./...` für den Root-Modul: sauber. `go test ./internal/tenant/...`: alle 20 bestehenden Tests weiterhin grün (13 Aufrufstellen von `NewProvisioner` auf die neue Signatur angepasst, jeweils dieselbe DSN-Vorlage für Admin- und Laufzeit-Parameter — kein Verhaltensunterschied für diese Tests, da die Testrolle ohnehin Eigentümerin bleibt).
|
||
|
||
## Nicht behoben in dieser Kachel
|
||
- Die 22 vom Nutzer erwähnten "Backup-CLI-Tools" beziehen sich vermutlich auf CLI-Unterbefehle/Aufrufmuster statt Unit-Dateien — auf Unit-Ebene sind alle betroffenen Vorlagen (10) gehärtet. Falls einzelne CLI-Unterbefehle noch eigene Härtungslücken haben (z. B. fehlende Argument-Validierung), ist das außerhalb des in F-15 beschriebenen Sandbox-/Rollentrennungs-Umfangs und müsste als eigener Befund nachgezogen werden.
|
||
- Rollout der gehärteten Konfiguration auf Host 131 (bewusst nicht Teil dieser Kachel, separater späterer Schritt).
|