VibeCoding: Anmeldung für manche Services nötig

This commit is contained in:
chk
2026-03-21 13:12:16 +01:00
parent c2a2f7c37d
commit 5c6ea53bd4
5 changed files with 34 additions and 32 deletions

View File

@@ -24,7 +24,6 @@ if [ ! -f "$FWD_FILE" ]; then
fi fi
# 1) Globale HTTP-Kontext-Map + Resolver (idempotent) # 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)" RESOLVERS="$(awk '/^nameserver/{print $2}' /etc/resolv.conf | xargs || true)"
if [ -n "${RESOLVERS:-}" ]; then if [ -n "${RESOLVERS:-}" ]; then
RESOLVER_LINE="resolver $RESOLVERS ipv6=off valid=30s;" RESOLVER_LINE="resolver $RESOLVERS ipv6=off valid=30s;"
@@ -40,7 +39,6 @@ map \$http_upgrade \$connection_upgrade {
} }
$RESOLVER_LINE $RESOLVER_LINE
NGINX NGINX
# <<< END CHANGE
# 2) Alte generierte Confs entfernen # 2) Alte generierte Confs entfernen
rm -f "$CONF_DIR/"*"$HTTPS_SUFFIX" 2>/dev/null || true rm -f "$CONF_DIR/"*"$HTTPS_SUFFIX" 2>/dev/null || true
@@ -50,12 +48,10 @@ rm -f "$CONF_DIR/"*"$HTTP_REDIRECT_SUFFIX" 2>/dev/null || true
LINE_NO=0 LINE_NO=0
while IFS= read -r RAW || [ -n "$RAW" ]; do while IFS= read -r RAW || [ -n "$RAW" ]; do
LINE_NO=$((LINE_NO+1)) LINE_NO=$((LINE_NO+1))
# trim + CR entfernen
LINE="$(printf '%s' "$RAW" | tr -d '\r' | sed 's/^[[:space:]]*//; s/[[:space:]]*$//')" LINE="$(printf '%s' "$RAW" | tr -d '\r' | sed 's/^[[:space:]]*//; s/[[:space:]]*$//')"
[ -z "$LINE" ] && continue [ -z "$LINE" ] && continue
case "$LINE" in \#*) continue;; esac case "$LINE" in \#*) continue;; esac
# Spalten splitten (mindestens 2 erforderlich)
set -- $LINE set -- $LINE
SERVER_NAME="${1:-}" SERVER_NAME="${1:-}"
UPSTREAM_URL="${2:-}" UPSTREAM_URL="${2:-}"
@@ -64,6 +60,7 @@ while IFS= read -r RAW || [ -n "$RAW" ]; do
VERIFY_TLS="${5:-false}" VERIFY_TLS="${5:-false}"
CERT_DOMAIN="${6:-$SERVER_NAME}" CERT_DOMAIN="${6:-$SERVER_NAME}"
LISTEN_PORT="${7:-443}" LISTEN_PORT="${7:-443}"
AUTH_REQUIRED="${8:-false}"
if [ -z "$SERVER_NAME" ] || [ -z "$UPSTREAM_URL" ]; then if [ -z "$SERVER_NAME" ] || [ -z "$UPSTREAM_URL" ]; then
echo "[connect-proxies] WARN(Line $LINE_NO): unvollständig -> $LINE" echo "[connect-proxies] WARN(Line $LINE_NO): unvollständig -> $LINE"
@@ -76,23 +73,17 @@ while IFS= read -r RAW || [ -n "$RAW" ]; do
HTTPS_OUT="$CONF_DIR/${SERVER_NAME}-p${LISTEN_PORT}${HTTPS_SUFFIX}" HTTPS_OUT="$CONF_DIR/${SERVER_NAME}-p${LISTEN_PORT}${HTTPS_SUFFIX}"
HTTP_REDIRECT_OUT="$CONF_DIR/${SERVER_NAME}${HTTP_REDIRECT_SUFFIX}" HTTP_REDIRECT_OUT="$CONF_DIR/${SERVER_NAME}${HTTP_REDIRECT_SUFFIX}"
# >>> NEW: Upstream normalisieren (Trailing Slash entfernen) + DNS-Check vorbereiten
SANITIZED_UPSTREAM="${UPSTREAM_URL%/}" SANITIZED_UPSTREAM="${UPSTREAM_URL%/}"
DNS_OK="true" DNS_OK="true"
SCHEME=""; HOST=""; PORT="" SCHEME=""; HOST=""; PORT=""
if [ "$SANITIZED_UPSTREAM" != "local" ]; then if [ "$SANITIZED_UPSTREAM" != "local" ]; then
case "$SANITIZED_UPSTREAM" in case "$SANITIZED_UPSTREAM" in
http://*) http://*) URI="${SANITIZED_UPSTREAM#http://}"; SCHEME="http"; DEFAULT_PORT="80";;
URI="${SANITIZED_UPSTREAM#http://}"; SCHEME="http"; DEFAULT_PORT="80" https://*) URI="${SANITIZED_UPSTREAM#https://}"; SCHEME="https"; DEFAULT_PORT="443";;
;;
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." echo "[connect-proxies] WARN(Line $LINE_NO): $SERVER_NAME upstream_url ungültig: '$UPSTREAM_URL' überspringe."
continue continue;;
;;
esac esac
HOSTPORT="${URI%%/*}" HOSTPORT="${URI%%/*}"
HOST="${HOSTPORT%%:*}" HOST="${HOSTPORT%%:*}"
@@ -107,12 +98,26 @@ while IFS= read -r RAW || [ -n "$RAW" ]; do
DNS_OK="unknown" DNS_OK="unknown"
fi fi
fi fi
# <<< END NEW
if [ -f "$FULLCHAIN" ] && [ -f "$PRIVKEY" ]; then if [ -f "$FULLCHAIN" ] && [ -f "$PRIVKEY" ]; then
echo "[connect-proxies] [+] $SERVER_NAME: Zertifikat OK (cert_domain=$CERT_DOMAIN). Erzeuge 443 …" echo "[connect-proxies] [+] $SERVER_NAME: Zertifikat OK (cert_domain=$CERT_DOMAIN). Erzeuge 443 …"
# Fall A: local (statisch, kein proxy_pass) # Auth-Block vorbereiten
AUTH_BLOCK=""
if [ "$AUTH_REQUIRED" = "true" ]; then
AUTH_BLOCK="
auth_request /auth;
location = /auth {
proxy_pass http://appserverauth:3000/internal/auth;
proxy_pass_request_body off;
proxy_set_header Content-Length \"\";
proxy_set_header X-Original-URI \$request_uri;
proxy_set_header Host server.schooltech.ch;
proxy_set_header Cookie \$http_cookie;
}"
fi
# Fall A: local (statisch, kein Proxy)
if [ "$SANITIZED_UPSTREAM" = "local" ]; then if [ "$SANITIZED_UPSTREAM" = "local" ]; then
cat > "$HTTPS_OUT" <<NGINX cat > "$HTTPS_OUT" <<NGINX
# Auto-generated - 443 static site # Auto-generated - 443 static site
@@ -120,6 +125,7 @@ server {
listen ${LISTEN_PORT} ssl http2; listen ${LISTEN_PORT} ssl http2;
listen [::]:${LISTEN_PORT} ssl http2; listen [::]:${LISTEN_PORT} ssl http2;
server_name $SERVER_NAME; server_name $SERVER_NAME;
$AUTH_BLOCK
ssl_certificate $FULLCHAIN; ssl_certificate $FULLCHAIN;
ssl_certificate_key $PRIVKEY; ssl_certificate_key $PRIVKEY;
@@ -132,7 +138,6 @@ server {
location /api/ { location /api/ {
proxy_pass http://appserverauth:3000/api/; proxy_pass http://appserverauth:3000/api/;
proxy_set_header Host \$host; proxy_set_header Host \$host;
proxy_set_header X-Real-IP \$remote_addr; proxy_set_header X-Real-IP \$remote_addr;
proxy_set_header X-Forwarded-For \$proxy_add_x_forwarded_for; proxy_set_header X-Forwarded-For \$proxy_add_x_forwarded_for;
@@ -146,9 +151,8 @@ server {
NGINX NGINX
else else
# >>> NEW: Zwei Pfade DNS_OK=false => Placeholder; sonst Proxy mit Laufzeit-Resolver # Proxy-Fall: DNS OK?
if [ "$DNS_OK" = "false" ]; then if [ "$DNS_OK" = "false" ]; then
# 443 Placeholder keine Proxy-Verbindung, saubere 503
cat > "$HTTPS_OUT" <<NGINX cat > "$HTTPS_OUT" <<NGINX
# Auto-generated - 443 placeholder (DNS failed) # Auto-generated - 443 placeholder (DNS failed)
server { server {
@@ -169,13 +173,14 @@ server {
} }
NGINX NGINX
else else
# 443 Proxy DNS ok/unknown: Laufzeit-Auflösung + freundlicher 503 bei Downstreams # Proxy mit Laufzeit-Auflösung
cat > "$HTTPS_OUT" <<NGINX cat > "$HTTPS_OUT" <<NGINX
# Auto-generated - 443 reverse proxy # Auto-generated - 443 reverse proxy
server { server {
listen ${LISTEN_PORT} ssl http2; listen ${LISTEN_PORT} ssl http2;
listen [::]:${LISTEN_PORT} ssl http2; listen [::]:${LISTEN_PORT} ssl http2;
server_name $SERVER_NAME; server_name $SERVER_NAME;
$AUTH_BLOCK
ssl_certificate $FULLCHAIN; ssl_certificate $FULLCHAIN;
ssl_certificate_key $PRIVKEY; ssl_certificate_key $PRIVKEY;
@@ -183,12 +188,10 @@ server {
ssl_protocols TLSv1.2 TLSv1.3; ssl_protocols TLSv1.2 TLSv1.3;
ssl_ciphers HIGH:!aNULL:!MD5; ssl_ciphers HIGH:!aNULL:!MD5;
# Fehler sauber abfangen und 503 liefern (statt rohe 502/504)
proxy_intercept_errors on; proxy_intercept_errors on;
error_page 502 503 504 = @service_down; error_page 502 503 504 = @service_down;
location / { location / {
# >>> CHANGE: variable proxy_pass -> DNS zur Laufzeit (verhindert nginx -t Crash)
set \$target $SANITIZED_UPSTREAM; set \$target $SANITIZED_UPSTREAM;
proxy_pass \$target; proxy_pass \$target;
@@ -239,14 +242,12 @@ NGINX
default_type text/html; default_type text/html;
return 503 "<!doctype html><html><head><meta charset='utf-8'><title>Service temporarily unavailable</title></head><body style='font-family:sans-serif;margin:3rem'><h1>$server_name nicht erreichbar</h1><p>Der Dienst ist momentan nicht verfügbar. Bitte später erneut versuchen.</p></body></html>"; return 503 "<!doctype html><html><head><meta charset='utf-8'><title>Service temporarily unavailable</title></head><body style='font-family:sans-serif;margin:3rem'><h1>$server_name nicht erreichbar</h1><p>Der Dienst ist momentan nicht verfügbar. Bitte später erneut versuchen.</p></body></html>";
} }
} }
NGINX NGINX
fi fi
# <<< END NEW
fi fi
# 80->443 Redirect-Server nur, wenn gewünscht # 80->443 Redirect-Server
if [ "$HTTP_BEHAVIOR" = "redirect" ]; then if [ "$HTTP_BEHAVIOR" = "redirect" ]; then
cat > "$HTTP_REDIRECT_OUT" <<NGINX cat > "$HTTP_REDIRECT_OUT" <<NGINX
# Auto-generated 80->443 redirect for $SERVER_NAME # Auto-generated 80->443 redirect for $SERVER_NAME
@@ -255,7 +256,6 @@ server {
listen [::]:80; listen [::]:80;
server_name $SERVER_NAME; server_name $SERVER_NAME;
# ACME-Ausnahme
location ^~ /.well-known/acme-challenge/ { location ^~ /.well-known/acme-challenge/ {
root /var/www/certbot; root /var/www/certbot;
default_type "text/plain; charset=utf-8"; default_type "text/plain; charset=utf-8";
@@ -267,7 +267,6 @@ server {
} }
NGINX NGINX
else else
# Sicherstellen, dass kein alter Redirect liegen bleibt
rm -f "$HTTP_REDIRECT_OUT" 2>/dev/null || true rm -f "$HTTP_REDIRECT_OUT" 2>/dev/null || true
fi fi

View File

View File

@@ -29,8 +29,9 @@ tcGuac.server.schooltech.ch http://appServer_TunnelHead:9780 redirect
tcPortainer.server.schooltech.ch http://appServer_TunnelHead:9703 redirect false false tcPortainer.server.schooltech.ch http://appServer_TunnelHead:9703 redirect false false
tcSimulation.server.schooltech.ch https://appServer_TunnelHead:9712 redirect true false tcSimulation.server.schooltech.ch https://appServer_TunnelHead:9712 redirect true false
#tcVideocontroller.server.schooltech.ch https://tcvideo:9443 redirect true false #tcVideocontroller.server.schooltech.ch https://tcvideo:9443 redirect true false
robotHoming.server.schooltech.ch https://appServer_TunnelHead:9793 redirect false false robotHoming.server.schooltech.ch https://appServer_TunnelHead:9793 redirect true fals
tcControl.server.schooltech.ch https://appServer_TunnelHead:9710 redirect true false robotVideo.server.schooltech.ch https://appServer_TunnelHead:9743 redirect true false robotVideo.server.schooltech.ch 443 true
tcControl.server.schooltech.ch https://appServer_TunnelHead:9710 redirect true false tcControl.server.schooltech.ch 443 true
# Beispiel mit abweichendem Zertifikats-Ordner (Lineage-Suffix) # Beispiel mit abweichendem Zertifikats-Ordner (Lineage-Suffix)

View File

@@ -1,4 +1,5 @@
for d in server.schooltech.ch \ for d in server.schooltech.ch \
robotVideo.server.schooltech.ch \
tcControl.server.schooltech.ch \ tcControl.server.schooltech.ch \
tcGuac.server.schooltech.ch \ tcGuac.server.schooltech.ch \
tcPortainer.server.schooltech.ch \ tcPortainer.server.schooltech.ch \
@@ -25,8 +26,7 @@ for d in server.schooltech.ch \
scaraSimu.server.schooltech.ch \ scaraSimu.server.schooltech.ch \
fluidncRed.server.schooltech.ch \ fluidncRed.server.schooltech.ch \
robotHoming.server.schooltech.ch \ robotHoming.server.schooltech.ch \
robotControl.server.schooltech.ch \ robotControl.server.schooltech.ch
robotVideo.server.schooltech.ch
do do
docker exec -it appServer_LetsEncryptFetcher certbot certonly \ docker exec -it appServer_LetsEncryptFetcher certbot certonly \

View File

@@ -5,7 +5,8 @@ const services = [
{ id: "abc", name: "Control GamePad", url: "https://tccontrol.server.schooltech.ch/" }, { id: "abc", name: "Control GamePad", url: "https://tccontrol.server.schooltech.ch/" },
{ id: "xyz", name: "Guacamole", url: "https://rp5guac.server.schooltech.ch/" }, { id: "xyz", name: "Guacamole", url: "https://rp5guac.server.schooltech.ch/" },
{ id: "sim", name: "Simulation", url: "https://tcSimulation.server.schooltech.ch/" }, { id: "sim", name: "Simulation", url: "https://tcSimulation.server.schooltech.ch/" },
{ id: "portainer", name: "Portainer", url: "https://rp5portainer.server.schooltech.ch/" } { id: "video", name: "Video", url: "https://robotVideo.server.schooltech.ch/" },
{ id: "homing", name: "Homing", url:"https://robotHoming.server.schooltech.ch/"}
]; ];
// DOM-Elemente // DOM-Elemente
@@ -104,6 +105,7 @@ loginSubmit.onclick = doLogin;
function setupServiceButtons() { function setupServiceButtons() {
nav.innerHTML = ""; nav.innerHTML = "";
services.forEach(svc => { services.forEach(svc => {
console.log("Service " + svc.name + " wird als Button angefuegt");
const btn = document.createElement("button"); const btn = document.createElement("button");
btn.textContent = svc.name; btn.textContent = svc.name;
btn.onclick = async () => { btn.onclick = async () => {