Files
sshkeyvault/docs/issues/011-test-ssh-container.md
T
florian.wildeandClaude Opus 5.5 e89112a761 test: SSH-Testziele und Mock-OIDC fuer Integrationstests (#011)
Bootstrap, Host-Key-Pruefung und spaeteres Ausrollen brauchen echte
sshd-Gegenstellen. Zwei Debian-13-Container (ziel-a, ziel-b) in einem
gemeinsamen Netz bilden frische Hosts vor dem Bootstrap nach: root- und
Passwort-Login sind absichtlich offen, Host-Keys entstehen erst beim
Start, und `hostkeys-tauschen` erlaubt den Test "geaenderter Host-Key
wird abgelehnt" ohne Neuerstellen des Containers.

Die Testhilfen lesen dieselben Adress-Variablen wie die Compose-Datei
und lassen Tests mit Hinweis auf den Startbefehl fehlschlagen, statt
sie still zu ueberspringen - ein uebersprungener Integrationstest sieht
sonst wie ein bestandener aus.

Der Mock-OIDC-Anbieter ersetzt authentik in der Entwicklung (PLAN.md,
Entscheidung 7). Bei interaktivem Login uebernimmt er nur Claims aus dem
Formular, daher belegt eine eigene Login-Seite email, name und groups
vor und laesst die Gruppen frei waehlen.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-12 09:13:56 +02:00

50 lines
2.9 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# #011 Test-SSH-Container und Integrationstests
**Status:** erledigt
**Meilenstein:** v0.1.0
**Labels:** test
**Geschätzt:** 2 h **Tatsächlich:** 0,25 h
## Ziel
Debian-Container mit sshd für Integrationstests (Bootstrap, Host-Key, später Ausrollen).
## Aufgaben
- [x] Dockerfile `tests/ssh-ziel/` (Debian 13, sshd, sudo, Passwort für root/test)
- [x] Compose-Datei für Tests, zwei Ziele (für Host-zu-Host)
- [x] Vitest-Projekt `integration`
- [x] Mock-OIDC-Anbieter für die Entwicklung (`mock-oidc` in `docker-compose.test.yml`)
- [x] Hilfen `tests/integration/hilfen/ziele.ts` und Rauchtest `tests/integration/ziele.test.ts`
## Akzeptanzkriterien
- [x] `pnpm test:integration` läuft lokal
## Abhängigkeiten
#001
## Notizen / Entscheidungen
- **Start:** `pnpm test:ziele:up` (= `docker compose -f docker-compose.test.yml up -d --build --wait`),
Stopp: `pnpm test:ziele:down`. Projektname `sshkv-test`.
- **Ports** nur auf 127.0.0.1: `ziel-a` 2221, `ziel-b` 2222, `mock-oidc` 8090. Überschreibbar über
`SSHKV_TEST_ZIEL_A`/`SSHKV_TEST_ZIEL_B`/`SSHKV_TEST_OIDC` (Format `host:port`) – dieselben
Variablen lesen Compose (Port-Bindung) und die Testhilfen, damit beide nie auseinanderlaufen.
- **Testziel** (`debian:trixie-slim`): root und `test` (Gruppe `sudo`) mit Passwort
`sshkv-test` (ENV `SSHKV_TEST_ROOT_PASSWORT`/`SSHKV_TEST_TEST_PASSWORT`, wird beim Start per
`chpasswd` gesetzt). `PermitRootLogin yes` und `PasswordAuthentication yes` absichtlich –
das Ziel bildet einen Host vor dem Bootstrap nach.
- **Host-Keys** werden nicht ins Image gebacken, sondern beim Start mit `ssh-keygen -A` erzeugt:
jeder neu erstellte Container hat eigene Keys. `hostkeys-tauschen` im Container erzeugt neue
Keys, schickt sshd (PID 1) ein SIGHUP und wartet, bis `ssh-keyscan` den neuen Key sieht.
- **Fingerprint-Vergleich** handelt nur `ssh-ed25519` aus, sonst könnte der gezeigte Key-Typ
wechseln und der Vergleich flattern.
- **Nicht laufende Ziele** lassen die Tests mit Hinweis auf den Startbefehl fehlschlagen
(`zielBereit` wartet bis 15 s auf das SSH-Banner) – kein stilles Überspringen.
- Beide Ziele bauen ohne gemeinsames `image:`-Tag: Mit gemeinsamem Tag bricht der parallele
Build mit „already exists“ ab.
- **Mock-OIDC:** `ghcr.io/navikt/mock-oauth2-server:6.0.5` (exakt gepinnt).
Issuer `http://127.0.0.1:8090/sshkv` – der Mock leitet ihn aus dem Host-Header ab, mit
`localhost` entstünde ein anderer Issuer. Client-ID und -Secret werden nicht geprüft.
Bei `interactiveLogin` übernimmt der Mock **nur** die Claims aus dem Login-Formular
(`tokenCallbacks` greifen dann nicht). Deshalb liefert `tests/mock-oidc/login.html` eine
eigene Login-Seite (`loginPagePath`), die `email`, `email_verified`, `name`,
`preferred_username` und `groups: ["sshkv-admins"]` vorbelegt; Knöpfe für Admin/Operator/
Reader/ohne Gruppe, das JSON bleibt frei änderbar.