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>
This commit is contained in:
2026-10-12 09:13:56 +02:00
co-authored by Claude Opus 5.5
parent 224386106b
commit e89112a761
11 changed files with 614 additions and 6 deletions
+38
View File
@@ -0,0 +1,38 @@
# SSH-Testziel fuer Integrationstests (#011). NUR fuer Tests und Entwicklung!
#
# Absichtlich offen konfiguriert (root-Login und Passwort-Anmeldung erlaubt): Das Ziel
# bildet einen frisch installierten Host vor dem Bootstrap nach, auf dem sshkv sich
# einmalig per Passwort anmeldet und dann seinen Deployment-Key hinterlegt.
FROM debian:trixie-slim
# openssh-client: Host-zu-Host-Tests (Ziel A ruft ssh/ssh-keyscan nach Ziel B auf).
# procps: pgrep/ps fuer Healthcheck und Fehlersuche.
RUN apt-get update \
&& apt-get install -y --no-install-recommends \
openssh-server openssh-client sudo passwd procps \
&& rm -rf /var/lib/apt/lists/* \
# Host-Keys aus dem Paket-Postinst entfernen: Sie wuerden sonst im Image-Layer
# landen und jeder Container haette dieselben Keys. Erzeugt wird beim Start.
&& rm -f /etc/ssh/ssh_host_* \
&& mkdir -p /run/sshd \
&& useradd --create-home --shell /bin/bash --groups sudo test
# Passwoerter werden beim Start aus der Umgebung gesetzt, damit Compose sie ohne
# Neubau aendern kann; die Build-Args liefern nur die Standardwerte.
ARG ROOT_PASSWORT=sshkv-test
ARG TEST_PASSWORT=sshkv-test
ENV SSHKV_ROOT_PASSWORT=${ROOT_PASSWORT} \
SSHKV_TEST_PASSWORT=${TEST_PASSWORT}
COPY sshd-test.conf /etc/ssh/sshd_config.d/10-sshkv-test.conf
COPY --chmod=0755 einstieg.sh /usr/local/sbin/einstieg
COPY --chmod=0755 hostkeys-tauschen.sh /usr/local/bin/hostkeys-tauschen
EXPOSE 22
# Prueft, ob sshd wirklich einen Host-Key ausliefert – ein laufender Prozess allein
# heisst nach einem Neuladen noch nicht, dass er schon Verbindungen annimmt.
HEALTHCHECK --interval=2s --timeout=3s --start-period=5s --retries=15 \
CMD ssh-keyscan -T 2 -t ed25519 127.0.0.1 2>/dev/null | grep -q ssh-ed25519
ENTRYPOINT ["/usr/local/sbin/einstieg"]
+14
View File
@@ -0,0 +1,14 @@
#!/bin/sh
# Einstieg des SSH-Testziels (#011).
set -eu
echo "root:${SSHKV_ROOT_PASSWORT}" | chpasswd
echo "test:${SSHKV_TEST_PASSWORT}" | chpasswd
# Host-Keys erst hier erzeugen: Jeder neu erstellte Container bekommt eigene Keys,
# so wie ein frisch installierter Host. ssh-keygen -A legt nur fehlende Keys an,
# ein blosser Neustart desselben Containers behaelt sie also.
ssh-keygen -A
# Vordergrund (-D) als PID 1, Log nach stderr (-e) – landet in `docker compose logs`.
exec /usr/sbin/sshd -D -e
+30
View File
@@ -0,0 +1,30 @@
#!/bin/sh
# Tauscht die Host-Keys des laufenden Testziels (#011). Damit laesst sich pruefen, dass
# sshkv einen geaenderten Host-Key ablehnt, ohne den Container neu zu erstellen.
set -eu
alt="$(ssh-keygen -lf /etc/ssh/ssh_host_ed25519_key.pub | awk '{print $2}')"
rm -f /etc/ssh/ssh_host_*
ssh-keygen -A >/dev/null
neu="$(ssh-keygen -lf /etc/ssh/ssh_host_ed25519_key.pub | awk '{print $2}')"
# SIGHUP laesst sshd sich neu ausfuehren und dabei die Host-Keys neu lesen. sshd laeuft
# als PID 1 (siehe einstieg.sh); bestehende Sitzungen bleiben dabei erhalten.
kill -HUP 1
# Erst zurueckkehren, wenn sshd wirklich den neuen Key ausliefert – sonst sieht ein
# Test direkt danach je nach Timing noch den alten oder gar keinen Key.
i=0
while [ "$i" -lt 50 ]; do
aktuell="$(ssh-keyscan -T 1 -t ed25519 127.0.0.1 2>/dev/null | ssh-keygen -lf - 2>/dev/null | awk '{print $2}')"
if [ "$aktuell" = "$neu" ]; then
echo "Host-Keys getauscht: $alt -> $neu"
exit 0
fi
i=$((i + 1))
sleep 0.2
done
echo "sshd liefert nach dem Tausch nicht den neuen Host-Key aus (erwartet $neu)." >&2
exit 1
+7
View File
@@ -0,0 +1,7 @@
# Bootstrap-Testziel (#011): absichtlich offen, siehe Dockerfile. Nie auf echten Hosts!
PermitRootLogin yes
PasswordAuthentication yes
KbdInteractiveAuthentication no
UseDNS no
# Fehlermeldungen im Container-Log sollen auch abgelehnte Host-Key-/Auth-Versuche zeigen.
LogLevel VERBOSE