# Abnahme vor Version 1.0.0 Was die automatischen Tests **nicht** abdecken können: der echte Anbieter (authentik), echte Hosts und der Betrieb auf dem Zielserver. Diese Liste geht genau das durch. Jeder Punkt nennt das erwartete Ergebnis; was abweicht, kommt als Issue in `docs/issues/` (oder direkt als Notiz hier darunter). Voraussetzung: Installation nach [installation.md](installation.md) ist durch, `docker compose ps` zeigt `db`, `web` und `worker` als *healthy*. **Abnahme durch:** ____________________ **Datum:** __________ **Version/Commit:** __________ --- ## A · Installation und Grundschutz - [ ] `https:///api/gesundheit` antwortet mit `{"status":"ok","version":…}`; über `http://` gibt es keine Anmeldung (Secure-Cookie). - [ ] Von außerhalb des internen Netzes ist die Oberfläche **nicht** erreichbar (Reverse Proxy / Firewall liefert 403 oder Timeout). - [ ] Der Web-Container sieht den Master-Key nicht: `docker compose exec web ls /run/secrets` → leer bzw. Fehler. - [ ] Worker-Log beim Start: Master-Key passt, Deployment-Key vorhanden (`docker compose logs worker | head`). - [ ] Antwort-Header prüfen (`curl -sI https:///anmelden`): `Content-Security-Policy`, `Strict-Transport-Security`, `X-Frame-Options`/`frame-ancestors`, `Referrer-Policy`. ## B · Anmeldung mit authentik - [ ] Anmelden mit einem Konto in `sshkv-admins` → Rolle **Admin** (unten links in der Navigation). - [ ] Konto in `sshkv-operators` → **Operator**; Konto in `sshkv-readers` → **Leser**. - [ ] Konto in **keiner** dieser Gruppen → kein Zugang, verständliche Meldung, Eintrag `anmeldung.verweigert` im Audit-Log. - [ ] Gruppe in authentik entziehen → bei der nächsten Anfrage gilt die neue Rolle bzw. kein Zugang (die Rolle kommt aus der Datenbank, nicht aus dem alten Token – spätestens nach erneuter Anmeldung). - [ ] **Erneute Bestätigung:** als Admin „Private Key anzeigen“ wählen → authentik fragt das Passwort (und ggf. MFA) **wirklich neu** ab; danach geht die Aktion fünf Minuten lang ohne erneute Frage. *Kritischer Punkt:* Kommt authentik ohne neue Eingabe zurück, meldet sshkv „auth_time fehlt oder ist zu alt“ – dann die Flow-Einstellung in authentik prüfen. - [ ] Abmelden beendet die Sitzung (Zurück-Knopf zeigt keine Daten mehr). ## C · Notfall-Admin - [ ] `/anmelden` → „Notfallzugang“: Benutzer `notfall` + Passwort aus `.env` → TOTP-Einrichtung erzwungen (QR-Code mit Authenticator-App scannen). - [ ] Erneute Anmeldung verlangt Passwort **und** TOTP-Code; falscher Code wird abgelehnt. - [ ] Nach fünf Fehlversuchen in 15 Minuten → „Zu viele Fehlversuche“, auch mit richtigem Passwort. - [ ] `SSHKV_BREAKGLASS_PASSWORD` danach aus der `.env` entfernen (der Hash steht in der Datenbank) und das Passwort im Passwortmanager ablegen. ## D · Echte Hosts aufnehmen Mindestens zwei Hosts, möglichst unterschiedlich (z. B. Debian 12 und Ubuntu 24.04), einer mit Anmeldeart *Dienstbenutzer*, einer mit *root*. - [ ] Host anlegen → „Host-Key abrufen“ → Fingerprint mit dem Host vergleichen (`ssh-keygen -lf /etc/ssh/ssh_host_ed25519_key.pub` **auf dem Host**) → vertrauen. - [ ] Bootstrap per Einmal-Passwort: danach existiert `sshkv` mit `/etc/sudoers.d/sshkv`, das Passwort steht **nirgends** (Audit-Log, `docker compose logs`, Datenbank: `grep -r` im Dump findet es nicht). - [ ] Bootstrap per Kopier-Befehl auf dem zweiten Host: Befehl in die Root-Shell einfügen, danach „Einrichtung erneut prüfen“ → eingerichtet. - [ ] „Verbindung prüfen“ → erreichbar; sshd-Befund wird angezeigt (z. B. PasswordAuthentication). - [ ] Host-Key auf einem Host absichtlich tauschen (`ssh-keygen -A` nach Löschen der Keys, sshd neu starten) → nächster Abgleich meldet **Host-Key geändert**, sshkv verbindet sich nicht mehr, bis ein Admin den neuen Key bestätigt. Danach zurückdrehen. ## E · Schlüssel ausrollen (Kern-Anwendungsfall) - [ ] Vorhandene `authorized_keys` eines Hosts mit eigenen Zeilen (Kommentare, Optionen, leere Zeilen) vorher sichern: `cp ~/.ssh/authorized_keys /tmp/vorher`. - [ ] Public Key eines Admins auf beide Hosts ausrollen → Dry-Run zeigt **nur** den verwalteten Block; nach „Anwenden“ ist alles außerhalb des Blocks **byte-gleich** (`diff` gegen `/tmp/vorher` zeigt nur den Block). - [ ] Backup-Datei `authorized_keys.sshkv.bak.*` liegt daneben; Rechte 0600, Verzeichnis 0700. - [ ] Host-zu-Host-Assistent: Vorlage „Deployment-Zugang“ von Host A nach Host B → Verbindungstest grün; auf A: `ssh id -un` funktioniert ohne Rückfrage (known_hosts gesetzt). - [ ] Datei `~/.ssh/config` auf A: eigener Inhalt außerhalb des sshkv-Blocks unverändert. - [ ] Zielkonto anlegen (z. B. `deploy` mit sudo) → Benutzer und sudoers-Datei entstehen, `visudo -c` auf dem Host ist sauber. ## F · Drift, Rotation, Widerruf - [ ] Im verwalteten Block auf einem Host von Hand eine Zeile ändern → Abgleich meldet Abweichung; Übersicht zeigt den Host; Dry-Run stellt den Soll-Stand wieder her. - [ ] Fremden Key außerhalb des Blocks eintragen → Abgleich meldet **unbekannten Schlüssel**; „übernehmen“ funktioniert. - [ ] Geführte Rotation des Assistenten-Schlüssels: Alias auf A funktioniert vorher, während und nachher; alte Datei ist weg. - [ ] Rotation einmal **abbrechen** und danach erneut rotieren (#032, #033). - [ ] Widerruf eines Schlüssels mit einem nicht erreichbaren Host (Host kurz stoppen) → „Widerruf unvollständig“; nach dem Wiederanlauf abschließbar. - [ ] **Deployment-Key rotieren** (Einstellungen → Instanz) über alle echten Hosts – danach klappen Abgleich und Ausrollen weiter; der alte Fingerprint steht auf keinem Host mehr. - [ ] Aussperrschutz: Den Deployment-Key auf einem Host per Hand aus dem Block löschen und ausrollen → sshkv schreibt ihn zurück bzw. verweigert eine Änderung, die ihn entfernen würde. ## G · Audit-Log und Benachrichtigungen - [ ] Audit-Log zeigt alle Aktionen aus D–F mit Akteur; „Kette prüfen“ → intakt. - [ ] CSV-Export öffnet sich sauber in LibreOffice/Excel (Umlaute, Trennzeichen). - [ ] Syslog-Kopie kommt beim Zielserver an (falls `SSHKV_SYSLOG_*` gesetzt). - [ ] Testversand E-Mail (Microsoft 365) und Webhook aus den Einstellungen kommt an. - [ ] Am nächsten Morgen: tägliche Zusammenfassung ist da und nennt die offenen Befunde. ## H · Sicherung und Wiederherstellung - [ ] `sudo bash deploy/sichern.sh` läuft durch; Sicherung landet am vorgesehenen Ort. - [ ] Master-Key **getrennt** gesichert (Passwortmanager/Tresor), Wiederauffinden geprobt. - [ ] Wiederherstellung auf einer **Wegwerf-Instanz** nach [sicherung.md](sicherung.md): danach Anmeldung, Private Key anzeigen und ein Abgleich funktionieren. - [ ] Mit falschem Master-Key verweigert der Worker den Start. ## I · Oberfläche - [ ] Smartphone (schmale Ansicht): Navigation, Übersicht, Hostliste und Dry-Run bedienbar. - [ ] Hell/dunkel: Die App ist bewusst dunkel (Tresor-Design); Kontrast in heller Umgebung ausreichend lesbar. - [ ] Handbuch (`docs/anleitung/README.md`) passt zu dem, was die Oberfläche zeigt. --- ## Ergebnis - [ ] Alle Punkte erledigt oder als Issue erfasst und als *nicht blockierend* eingestuft. - [ ] **Freigabe für 1.0.0** – danach: Version in `package.json`, CHANGELOG-Abschnitt `[1.0.0]`, Tag `v1.0.0`, Push. ### Notizen