die Authentifizierung von server.schooltech.ch funktioniert. Ich komme wie gewünscht nur mit aktivem cookie rein. # /etc/nginx/conf.d/default.conf server { listen 80 default_server; listen [::]:80 default_server; # ACME HTTP-01 Challenge (Certbot) location ^~ /.well-known/acme-challenge/ { root /var/www/certbot; default_type "text/plain; charset=utf-8"; } # PortalUI root root /usr/share/nginx/html; index index.html; # === API forwarding for Auth-Service === location /api/ { proxy_pass http://appserverauth:3000/api/; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header X-Forwarded-Proto $scheme; } # === SPA routing (Portal UI) === location / { try_files $uri $uri/ /index.html; } } Die SubDomains werden in 50-subdomains-userA.conf verwaltet. Und bei diesen Subdomains sollen einige auch nur mit aktivem cookie erreichbar sein. Aber nicht alle. Deshalb: Eine weitere spalte in der forwarding.conf datei. #!/bin/sh # /docker-entrypoint.d/40-connect-proxies.sh # Generiert pro Zeile in /etc/nginx/forwarding.conf: # - HTTPS vHost (Proxy oder local static) NUR wenn Zertifikate existieren # - optional 80->443 Redirect-Server (mit ACME-Ausnahme) bei http_behavior=redirect # Läuft automatisch beim Containerstart (nginx:alpine EntryPoint). # # # Die Datei: connect-proxies.sh läuft, wenn nginx docker container startet set -eu CONF_DIR="/etc/nginx/conf.d" LIVE_DIR="/etc/letsencrypt/live" FWD_FILE="/etc/nginx/forwarding.conf" HTTPS_SUFFIX="-https.generated.conf" HTTP_REDIRECT_SUFFIX="-http-redirect.generated.conf" GLOBALS_FILE="$CONF_DIR/_globals.generated.conf" echo "[connect-proxies] start …" # 0) Forwarding-Datei vorhanden? if [ ! -f "$FWD_FILE" ]; then echo "[connect-proxies] WARN: $FWD_FILE fehlt – keine Proxies zu generieren." exit 0 fi # 1) Globale HTTP-Kontext-Map + Resolver (idempotent) # >>> CHANGE: Resolver NICHT hardcoden. Dynamisch aus /etc/resolv.conf ableiten, Fallback 127.0.0.11 RESOLVERS="$(awk '/^nameserver/{print $2}' /etc/resolv.conf | xargs || true)" if [ -n "${RESOLVERS:-}" ]; then RESOLVER_LINE="resolver $RESOLVERS ipv6=off valid=30s;" else RESOLVER_LINE="resolver 127.0.0.11 ipv6=off valid=30s;" fi cat > "$GLOBALS_FILE" </dev/null || true rm -f "$CONF_DIR/"*"$HTTP_REDIRECT_SUFFIX" 2>/dev/null || true # 3) Zeilen verarbeiten LINE_NO=0 while IFS= read -r RAW || [ -n "$RAW" ]; do LINE_NO=$((LINE_NO+1)) # trim + CR entfernen LINE="$(printf '%s' "$RAW" | tr -d '\r' | sed 's/^[[:space:]]*//; s/[[:space:]]*$//')" [ -z "$LINE" ] && continue case "$LINE" in \#*) continue;; esac # Spalten splitten (mindestens 2 erforderlich) set -- $LINE SERVER_NAME="${1:-}" UPSTREAM_URL="${2:-}" HTTP_BEHAVIOR="${3:-redirect}" WEBSOCKETS="${4:-false}" VERIFY_TLS="${5:-false}" CERT_DOMAIN="${6:-$SERVER_NAME}" LISTEN_PORT="${7:-443}" if [ -z "$SERVER_NAME" ] || [ -z "$UPSTREAM_URL" ]; then echo "[connect-proxies] WARN(Line $LINE_NO): unvollständig -> $LINE" continue fi FULLCHAIN="$LIVE_DIR/$CERT_DOMAIN/fullchain.pem" PRIVKEY="$LIVE_DIR/$CERT_DOMAIN/privkey.pem" HTTPS_OUT="$CONF_DIR/${SERVER_NAME}-p${LISTEN_PORT}${HTTPS_SUFFIX}" HTTP_REDIRECT_OUT="$CONF_DIR/${SERVER_NAME}${HTTP_REDIRECT_SUFFIX}" # >>> NEW: Upstream normalisieren (Trailing Slash entfernen) + DNS-Check vorbereiten SANITIZED_UPSTREAM="${UPSTREAM_URL%/}" DNS_OK="true" SCHEME=""; HOST=""; PORT="" if [ "$SANITIZED_UPSTREAM" != "local" ]; then case "$SANITIZED_UPSTREAM" in http://*) URI="${SANITIZED_UPSTREAM#http://}"; SCHEME="http"; DEFAULT_PORT="80" ;; https://*) URI="${SANITIZED_UPSTREAM#https://}"; SCHEME="https"; DEFAULT_PORT="443" ;; *) echo "[connect-proxies] WARN(Line $LINE_NO): $SERVER_NAME upstream_url ungültig: '$UPSTREAM_URL' – überspringe." continue ;; esac HOSTPORT="${URI%%/*}" HOST="${HOSTPORT%%:*}" PORT="${HOSTPORT#*:}"; [ "$PORT" = "$HOSTPORT" ] && PORT="$DEFAULT_PORT" if command -v getent >/dev/null 2>&1; then if ! getent hosts "$HOST" >/dev/null 2>&1; then DNS_OK="false" echo "[connect-proxies] [-] $SERVER_NAME: DNS nicht auflösbar ($HOST) – erzeuge 503-Placeholder statt Proxy." fi else DNS_OK="unknown" fi fi # <<< END NEW if [ -f "$FULLCHAIN" ] && [ -f "$PRIVKEY" ]; then echo "[connect-proxies] [+] $SERVER_NAME: Zertifikat OK (cert_domain=$CERT_DOMAIN). Erzeuge 443 …" # Fall A: local (statisch, kein proxy_pass) if [ "$SANITIZED_UPSTREAM" = "local" ]; then cat > "$HTTPS_OUT" <>> NEW: Zwei Pfade – DNS_OK=false => Placeholder; sonst Proxy mit Laufzeit-Resolver if [ "$DNS_OK" = "false" ]; then # 443 Placeholder – keine Proxy-Verbindung, saubere 503 cat > "$HTTPS_OUT" <Service temporarily unavailable

\$server_name nicht erreichbar

DNS-Auflösung fehlgeschlagen. Bitte später erneut versuchen.

"; } } NGINX else # 443 Proxy – DNS ok/unknown: Laufzeit-Auflösung + freundlicher 503 bei Downstreams cat > "$HTTPS_OUT" <>> CHANGE: variable proxy_pass -> DNS zur Laufzeit (verhindert nginx -t Crash) set \$target $SANITIZED_UPSTREAM; proxy_pass \$target; proxy_set_header Host \$host; proxy_set_header X-Real-IP \$remote_addr; proxy_set_header X-Forwarded-For \$proxy_add_x_forwarded_for; proxy_set_header X-Forwarded-Proto \$scheme; proxy_http_version 1.1; NGINX if [ "$WEBSOCKETS" = "true" ]; then cat >> "$HTTPS_OUT" <<'NGINX' proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection $connection_upgrade; NGINX else cat >> "$HTTPS_OUT" <<'NGINX' proxy_set_header Upgrade ""; proxy_set_header Connection close; NGINX fi case "$SANITIZED_UPSTREAM" in https://*) if [ "$VERIFY_TLS" = "true" ]; then cat >> "$HTTPS_OUT" <<'NGINX' proxy_ssl_verify on; proxy_ssl_server_name on; NGINX else cat >> "$HTTPS_OUT" <<'NGINX' proxy_ssl_verify off; proxy_ssl_server_name on; NGINX fi ;; esac cat >> "$HTTPS_OUT" <<'NGINX' client_max_body_size 50m; proxy_connect_timeout 60s; proxy_send_timeout 60s; proxy_read_timeout 60s; } location @service_down { default_type text/html; return 503 "Service temporarily unavailable

$server_name nicht erreichbar

Der Dienst ist momentan nicht verfügbar. Bitte später erneut versuchen.

"; } } NGINX fi # <<< END NEW fi # 80->443 Redirect-Server nur, wenn gewünscht if [ "$HTTP_BEHAVIOR" = "redirect" ]; then cat > "$HTTP_REDIRECT_OUT" <443 redirect for $SERVER_NAME server { listen 80; listen [::]:80; server_name $SERVER_NAME; # ACME-Ausnahme location ^~ /.well-known/acme-challenge/ { root /var/www/certbot; default_type "text/plain; charset=utf-8"; } location / { return 301 https://\$host\$request_uri; } } NGINX else # Sicherstellen, dass kein alter Redirect liegen bleibt rm -f "$HTTP_REDIRECT_OUT" 2>/dev/null || true fi else echo "[connect-proxies] [-] $SERVER_NAME: keine Zertifikate (cert_domain=$CERT_DOMAIN). Entferne evtl. alte Confs." rm -f "$HTTPS_OUT" "$HTTP_REDIRECT_OUT" 2>/dev/null || true fi done < "$FWD_FILE" echo "[connect-proxies] nginx -t …" nginx -t echo "[connect-proxies] done." # server_name upstream_url http_behavior websockets verify_upstream_tls [cert_domain] #fluidncRed.server.schooltech.ch http://appServer_TunnelHead:8120 redirect true false # 444 → 8121 (WS/WSS) # fluidncRedWs.server.schooltech.ch http://appServer_TunnelHead:8121 redirect true false fluidncRedWs.server.schooltech.ch 444 #server.schooltech.ch local static false false server.schooltech.ch local redirect false false server.schooltech.ch 443 tcPortainer.server.schooltech.ch http://thinkcentre.local:9000 redirect true false tcGuac.server.schooltech.ch http://thinkcentre.local:9000 redirect true false #inf InformatiWeb ist per Tunnel angeschlossen. Soll auf 97xx Ports gehen infPortainer.server.schooltech.ch http://appServer_TunnelHead:9903 redirect true false infGuac.server.schooltech.ch http://appServer_TunnelHead:9980 redirect true false #RP5 ist "Lokal" der Server rp5Guac.server.schooltech.ch http://appServer_guacamole:8080 redirect true false rp5Portainer.server.schooltech.ch http://portainer:9000 redirect true false #RP3 ist Raspi für die Scara-Robots, per Tunnel angeschlossen. Er hat 81xx Ports am TunnelHead rp3Portainer.server.schooltech.ch http://appServer_TunnelHead:8100 redirect true false rp3Guac.server.schooltech.ch http://appServer_TunnelHead:8180 redirect true false fluidncRed.server.schooltech.ch http://appServer_TunnelHead:8120 redirect true false fluidncWhite.server.schooltech.ch https://appServer_TunnelHead:8104 redirect true false ============ Fragen: 1) ist der aufbau einigermassen klar? 2) weisst du, wo die User-Authentifizierung eingebaut wereden könnte? 3) Ist es sinnvoll, das in der forwaring.conf abzuspeichern?