Merge branch 'phase/034-abnahme-checkliste'
This commit is contained in:
@@ -27,6 +27,7 @@ Notfallplan) und [`docs/betrieb/sicherung.md`](docs/betrieb/sicherung.md).
|
||||
- [Installation und Betrieb](docs/betrieb/installation.md) – Docker Compose, authentik, Reverse Proxy
|
||||
- [Sicherung und Wiederherstellung](docs/betrieb/sicherung.md) – `deploy/sichern.sh`, `deploy/wiederherstellen.sh`
|
||||
- [Sicherheit](docs/betrieb/sicherheit.md) – Aufbau, Bedrohungsanalyse, Notfallplan
|
||||
- [Abnahme vor 1.0.0](docs/betrieb/abnahme.md) – Prüfliste für authentik, echte Hosts und Betrieb
|
||||
|
||||
## Installation (Docker Compose)
|
||||
|
||||
|
||||
@@ -0,0 +1,130 @@
|
||||
# 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://<sshkv>/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://<sshkv>/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 <alias> 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
|
||||
@@ -0,0 +1,23 @@
|
||||
# #034 Abnahme-Checkliste für 1.0.0
|
||||
**Status:** erledigt
|
||||
**Meilenstein:** v1.0.0
|
||||
**Labels:** docs
|
||||
**Geschätzt:** 0,5 h **Tatsächlich:** 0,25 h
|
||||
|
||||
## Ziel
|
||||
Was die automatischen Tests nicht abdecken – echter authentik, echte Hosts, Betrieb auf dem Zielserver – als abhakbare Liste mit erwartetem Ergebnis je Punkt, damit die Abnahme von 1.0.0 vollständig und nachvollziehbar ist.
|
||||
|
||||
## Aufgaben
|
||||
- [x] `docs/betrieb/abnahme.md`: Installation, authentik, Notfall-Admin, Hosts, Ausrollen, Drift/Rotation/Widerruf, Audit-Log/Benachrichtigungen, Sicherung, Oberfläche
|
||||
- [x] Aussagen gegen den Code geprüft (Knopfnamen, Healthcheck, Ratenbegrenzung, Header)
|
||||
- [x] Verlinkt im README
|
||||
|
||||
## Akzeptanzkriterien
|
||||
- [x] Jeder Punkt nennt ein prüfbares Ergebnis
|
||||
- [x] Die kritischen offenen Punkte (authentik-Neuanmeldung mit `auth_time`, Byte-Gleichheit außerhalb des Blocks auf echten Hosts) sind ausdrücklich enthalten
|
||||
|
||||
## Abhängigkeiten
|
||||
#029
|
||||
|
||||
## Notizen / Entscheidungen
|
||||
- Die Abnahme selbst macht der Betreiber; 1.0.0 wird erst danach getaggt.
|
||||
Reference in New Issue
Block a user