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>
98 lines
3.1 KiB
YAML
98 lines
3.1 KiB
YAML
# Nur fuer Tests und Entwicklung (#011): zwei SSH-Testziele und ein Mock-OIDC-Anbieter.
|
||
# Diese Datei niemals im Betrieb verwenden – die Ziele erlauben root-Login per Passwort.
|
||
#
|
||
# pnpm test:ziele:up # bauen, starten, auf healthy warten
|
||
# pnpm test:integration
|
||
# pnpm test:ziele:down
|
||
#
|
||
# Alle Ports nur auf 127.0.0.1. Die Adressen kommen aus denselben Variablen, die auch
|
||
# die Testhilfen lesen (tests/integration/hilfen/ziele.ts), damit beide nie auseinanderlaufen.
|
||
|
||
name: sshkv-test
|
||
|
||
x-ssh-ziel: &ssh-ziel
|
||
# Kein gemeinsames `image:` – sonst bauen beide Dienste parallel unter demselben Tag
|
||
# und BuildKit bricht mit "already exists" ab. Der Build-Cache wird trotzdem geteilt.
|
||
build:
|
||
context: tests/ssh-ziel
|
||
restart: unless-stopped
|
||
networks: [ziel-netz]
|
||
environment:
|
||
SSHKV_ROOT_PASSWORT: ${SSHKV_TEST_ROOT_PASSWORT:-sshkv-test}
|
||
SSHKV_TEST_PASSWORT: ${SSHKV_TEST_TEST_PASSWORT:-sshkv-test}
|
||
|
||
services:
|
||
ziel-a:
|
||
<<: *ssh-ziel
|
||
hostname: ziel-a
|
||
ports:
|
||
- "${SSHKV_TEST_ZIEL_A:-127.0.0.1:2221}:22"
|
||
|
||
ziel-b:
|
||
<<: *ssh-ziel
|
||
hostname: ziel-b
|
||
ports:
|
||
- "${SSHKV_TEST_ZIEL_B:-127.0.0.1:2222}:22"
|
||
|
||
# Ersatz fuer authentik in der Entwicklung (PLAN.md, Entscheidung 7).
|
||
# Issuer: http://127.0.0.1:8090/sshkv – der Mock leitet den Issuer aus dem Host-Header
|
||
# ab, "localhost:8090" ergaebe also einen anderen Issuer. Client-ID und -Secret prueft
|
||
# er nicht; jeder Wert wird angenommen.
|
||
mock-oidc:
|
||
image: ghcr.io/navikt/mock-oauth2-server:6.0.5
|
||
restart: unless-stopped
|
||
ports:
|
||
- "${SSHKV_TEST_OIDC:-127.0.0.1:8090}:8080"
|
||
volumes:
|
||
- ./tests/mock-oidc/login.html:/mock/login.html:ro
|
||
environment:
|
||
SERVER_PORT: "8080"
|
||
# Bei interactiveLogin uebernimmt der Mock nur die Claims aus dem Login-Formular.
|
||
# Die eigene Login-Seite belegt sie deshalb vor (email, name, groups …) und
|
||
# erlaubt freie Gruppenwahl. tokenCallbacks gelten fuer nicht-interaktive Grants
|
||
# (z. B. client_credentials in Tests).
|
||
JSON_CONFIG: >-
|
||
{
|
||
"interactiveLogin": true,
|
||
"httpServer": "NettyWrapper",
|
||
"loginPagePath": "/mock/login.html",
|
||
"tokenCallbacks": [
|
||
{
|
||
"issuerId": "sshkv",
|
||
"tokenExpiry": 3600,
|
||
"requestMappings": [
|
||
{
|
||
"requestParam": "scope",
|
||
"match": "*",
|
||
"claims": {
|
||
"sub": "admin",
|
||
"email": "admin@sshkv.test",
|
||
"email_verified": true,
|
||
"name": "Admin (Mock)",
|
||
"preferred_username": "admin",
|
||
"groups": ["sshkv-admins"]
|
||
}
|
||
}
|
||
]
|
||
}
|
||
]
|
||
}
|
||
healthcheck:
|
||
test:
|
||
[
|
||
"CMD",
|
||
"wget",
|
||
"-q",
|
||
"-O",
|
||
"/dev/null",
|
||
"http://127.0.0.1:8080/sshkv/.well-known/openid-configuration",
|
||
]
|
||
interval: 3s
|
||
timeout: 3s
|
||
start_period: 10s
|
||
retries: 20
|
||
|
||
networks:
|
||
# Gemeinsames Netz: ziel-a erreicht ziel-b per Dienstname (Host-zu-Host-Tests).
|
||
ziel-netz:
|