#!/usr/bin/env bash # Prüft im CI-Job die Grenzen des isolierten Runners (Label ci-isolated, # Runner-Doku im VyCept-Repo, docs/BETRIEB.md 11b; Kopie von dort). Läuft als erster Schritt jedes Prüf-Jobs, damit jeder # Runner bei jedem Lauf geprüft wird. Schlägt fehl, wenn der Job mehr darf als # vorgesehen – oder wenn die Prüfung selbst nichts aussagen würde. set -euo pipefail fail() { echo "Runner-Isolation verletzt: $*" >&2 exit 1 } reachable() { timeout 5 bash -c "exec 3<>/dev/tcp/$1/$2" 2>/dev/null } # Namen mit Wiederholung auflösen: Das DNS des Job-Netzes antwortet unter Last # gelegentlich erst beim zweiten Versuch. resolve() { local address="" for _ in 1 2 3 4 5; do address=$(getent hosts "$1" | awk '{ print $1; exit }' || true) if [ -n "$address" ]; then echo "$address"; return 0; fi sleep 2 done return 1 } # 1. Kein Zugang zum Docker-Daemon über den Socket. [ -z "${DOCKER_HOST:-}" ] || fail "DOCKER_HOST ist gesetzt ($DOCKER_HOST)" for socket in /var/run/docker.sock /run/docker.sock; do [ ! -e "$socket" ] || fail "Docker-Socket $socket ist sichtbar" done # 2. Kein Zugang zur Docker-API des Daemons im Runner-Pod (Gateway des Job-Netzes): # 2375 (ohne TLS) zu, 2376 nur mit Client-Zertifikat, das der Job nicht hat. gateway_hex=$(awk '$2 == "00000000" { print $3; exit }' /proc/net/route) [ -n "$gateway_hex" ] || fail "kein Standard-Gateway gefunden – Prüfung wäre wirkungslos" gateway=$(printf '%d.%d.%d.%d' "0x${gateway_hex:6:2}" "0x${gateway_hex:4:2}" "0x${gateway_hex:2:2}" "0x${gateway_hex:0:2}") if reachable "$gateway" 2375; then fail "Docker-API ohne TLS am Gateway $gateway:2375"; fi if curl -sk --max-time 5 "https://$gateway:2376/version" >/dev/null 2>&1; then fail "Docker-API am Gateway $gateway:2376 ohne Client-Zertifikat nutzbar" fi # 3. Kein Clusternetz: Kubernetes-API (Service und Knoten) und fremde Namespaces. for target in 10.43.0.1:443 10.50.1.51:6443 10.50.1.52:6443 10.50.1.53:6443; do if reachable "${target%:*}" "${target##*:}"; then fail "$target ist erreichbar"; fi done resolve kubernetes.default.svc.cluster.local >/dev/null || fail "Clusternamen nicht auflösbar – Prüfung wäre wirkungslos" # Fremder Namespace (VyCept-Datenbank) und eigener Namespace (Gitea-Datenbank). for target in vycept-postgres.vycept.svc.cluster.local:5432 gitea-postgres.gitea.svc.cluster.local:5432; do host=${target%:*} address=$(resolve "$host") || fail "$host nicht auflösbar – Prüfung wäre wirkungslos" if reachable "$address" "${target##*:}"; then fail "$host ($address) ist erreichbar"; fi done # 4. Internet bleibt erreichbar (npm, GitHub, Images). reachable registry.npmjs.org 443 || fail "Internet (registry.npmjs.org) nicht erreichbar" echo "Runner-Isolation in Ordnung (Gateway $gateway, kein Socket, kein Clusternetz)"