# #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.