Login
This commit is contained in:
0
.forwarding.conf.swp
Normal file
0
.forwarding.conf.swp
Normal file
10
.gitignore
vendored
Executable file
10
.gitignore
vendored
Executable file
@@ -0,0 +1,10 @@
|
|||||||
|
|
||||||
|
# Let's Encrypt Konfigurationen und Zertifikate ignorieren
|
||||||
|
letsencrypt/
|
||||||
|
letsencrypt/conf/
|
||||||
|
letsencrypt/conf/**/*
|
||||||
|
|
||||||
|
# Falls du nur Zertifikate ignorieren willst:
|
||||||
|
*.pem
|
||||||
|
*.key
|
||||||
|
*.csr
|
||||||
@@ -1,375 +0,0 @@
|
|||||||
error_log /var/log/nginx/error.log info;
|
|
||||||
|
|
||||||
map $http_upgrade $connection_upgrade {
|
|
||||||
default upgrade;
|
|
||||||
'' close;
|
|
||||||
}
|
|
||||||
|
|
||||||
# ------------------------------------------------------------
|
|
||||||
# Default HTTP -> HTTPS redirect
|
|
||||||
# ------------------------------------------------------------
|
|
||||||
server {
|
|
||||||
listen 80 default_server;
|
|
||||||
server_name _;
|
|
||||||
|
|
||||||
location /.well-known/acme-challenge/ {
|
|
||||||
root /var/www/certbot;
|
|
||||||
}
|
|
||||||
|
|
||||||
location / {
|
|
||||||
return 301 https://$host$request_uri;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
# ------------------------------------------------------------
|
|
||||||
# #***# DEFAULT 443 SERVER (NEU)
|
|
||||||
# Verhindert, dass der erste 443-vHost andere Subdomains "abfängt"
|
|
||||||
# ------------------------------------------------------------
|
|
||||||
server {
|
|
||||||
listen 443 ssl http2 default_server;
|
|
||||||
server_name _;
|
|
||||||
|
|
||||||
ssl_certificate /etc/letsencrypt/live/server.schooltech.ch/fullchain.pem;
|
|
||||||
ssl_certificate_key /etc/letsencrypt/live/server.schooltech.ch/privkey.pem;
|
|
||||||
ssl_protocols TLSv1.2 TLSv1.3;
|
|
||||||
|
|
||||||
# Einfach Verbindung schließen für unbekannte Hosts
|
|
||||||
return 444;
|
|
||||||
}
|
|
||||||
|
|
||||||
# ------------------------------------------------------------
|
|
||||||
# UI (portal) - nur für server.schooltech.ch
|
|
||||||
# ------------------------------------------------------------
|
|
||||||
server {
|
|
||||||
listen 443 ssl http2;
|
|
||||||
server_name server.schooltech.ch;
|
|
||||||
|
|
||||||
ssl_certificate /etc/letsencrypt/live/server.schooltech.ch/fullchain.pem;
|
|
||||||
ssl_certificate_key /etc/letsencrypt/live/server.schooltech.ch/privkey.pem;
|
|
||||||
ssl_protocols TLSv1.2 TLSv1.3;
|
|
||||||
ssl_prefer_server_ciphers on;
|
|
||||||
|
|
||||||
root /usr/share/nginx/html;
|
|
||||||
index index.html;
|
|
||||||
|
|
||||||
location / {
|
|
||||||
try_files $uri $uri/ /index.html;
|
|
||||||
}
|
|
||||||
|
|
||||||
# API forwarding to auth (wie vorher) - nur für server.schooltech.ch
|
|
||||||
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;
|
|
||||||
}
|
|
||||||
|
|
||||||
# ------------------------------------------------------------
|
|
||||||
# Internal auth endpoint for auth_request (used by other server blocks)
|
|
||||||
# Einheitlicher nginxauth-Block: Host + URI an Auth-Service
|
|
||||||
# ------------------------------------------------------------
|
|
||||||
location = /nginxauth {
|
|
||||||
internal;
|
|
||||||
proxy_pass http://appserverauth:3000/internal/auth; #***# AUTH: proxy_pass (wichtig)
|
|
||||||
proxy_set_header Cookie $http_cookie; #***# AUTH: Cookie weitergeben
|
|
||||||
|
|
||||||
#***# AUTH HEADER ERWEITERUNG
|
|
||||||
proxy_set_header X-Original-URI $request_uri;
|
|
||||||
proxy_set_header X-Original-Host $host;
|
|
||||||
proxy_set_header X-Forwarded-Host $host;
|
|
||||||
}
|
|
||||||
|
|
||||||
# Security
|
|
||||||
add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" always;
|
|
||||||
}
|
|
||||||
|
|
||||||
# ------------------------------------------------------------
|
|
||||||
# abc.server.schooltech.ch - Controller on ThinkCentre
|
|
||||||
# ------------------------------------------------------------
|
|
||||||
server {
|
|
||||||
listen 443 ssl http2;
|
|
||||||
server_name abc.server.schooltech.ch;
|
|
||||||
|
|
||||||
ssl_certificate /etc/letsencrypt/live/server.schooltech.ch/fullchain.pem;
|
|
||||||
ssl_certificate_key /etc/letsencrypt/live/server.schooltech.ch/privkey.pem;
|
|
||||||
ssl_protocols TLSv1.2 TLSv1.3;
|
|
||||||
ssl_prefer_server_ciphers on;
|
|
||||||
|
|
||||||
# ---- Static assets: keine Auth, damit Browser die .js/.css korrekt erhält ----
|
|
||||||
location ~* \.(?:js|css|png|jpg|jpeg|gif|ico|svg|webp)$ {
|
|
||||||
proxy_pass https://thinkcentre.local:10010;
|
|
||||||
proxy_set_header Host thinkcentre.local;
|
|
||||||
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 https;
|
|
||||||
# kein proxy_set_header Connection / Upgrade hier
|
|
||||||
}
|
|
||||||
|
|
||||||
# ---- WebSocket-Endpoint (falls z.B. /echo) - auth prüfen ----
|
|
||||||
location /echo {
|
|
||||||
auth_request /nginxauth;
|
|
||||||
proxy_pass https://thinkcentre.local:10010/echo;
|
|
||||||
|
|
||||||
proxy_http_version 1.1;
|
|
||||||
proxy_set_header Upgrade $http_upgrade;
|
|
||||||
proxy_set_header Connection $connection_upgrade;
|
|
||||||
|
|
||||||
proxy_ssl_server_name on;
|
|
||||||
proxy_ssl_name thinkcentre.local;
|
|
||||||
proxy_ssl_verify off;
|
|
||||||
|
|
||||||
proxy_set_header Host thinkcentre.local;
|
|
||||||
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 https;
|
|
||||||
}
|
|
||||||
|
|
||||||
# ---- Hauptanwendung (HTML, API-Aufrufe) - auth prüfen ----
|
|
||||||
location / {
|
|
||||||
auth_request /nginxauth;
|
|
||||||
|
|
||||||
proxy_pass https://thinkcentre.local:10010/;
|
|
||||||
|
|
||||||
proxy_http_version 1.1;
|
|
||||||
proxy_set_header Upgrade $http_upgrade;
|
|
||||||
proxy_set_header Connection $connection_upgrade;
|
|
||||||
|
|
||||||
proxy_ssl_server_name on;
|
|
||||||
proxy_ssl_name thinkcentre.local;
|
|
||||||
proxy_ssl_verify off;
|
|
||||||
|
|
||||||
proxy_set_header Host thinkcentre.local;
|
|
||||||
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 https;
|
|
||||||
proxy_set_header Origin $http_origin;
|
|
||||||
|
|
||||||
proxy_hide_header X-Frame-Options;
|
|
||||||
add_header X-Frame-Options "ALLOWALL" always;
|
|
||||||
|
|
||||||
proxy_hide_header Content-Security-Policy;
|
|
||||||
add_header Content-Security-Policy "frame-ancestors https://server.schooltech.ch" always;
|
|
||||||
}
|
|
||||||
|
|
||||||
# /nginxauth (lokal für diesen vhost, aber internal request wird an auth-service weitergeleitet)
|
|
||||||
location = /nginxauth {
|
|
||||||
internal;
|
|
||||||
proxy_pass http://appserverauth:3000/internal/auth; #***# AUTH
|
|
||||||
proxy_set_header Cookie $http_cookie; #***# AUTH
|
|
||||||
|
|
||||||
#***# AUTH HEADER ERWEITERUNG
|
|
||||||
proxy_set_header X-Original-URI $request_uri;
|
|
||||||
proxy_set_header X-Original-Host $host;
|
|
||||||
proxy_set_header X-Forwarded-Host $host;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
# ------------------------------------------------------------
|
|
||||||
# simulation3a29.server.schooltech.ch
|
|
||||||
# ------------------------------------------------------------
|
|
||||||
server {
|
|
||||||
listen 443 ssl http2;
|
|
||||||
server_name simulation3a29.server.schooltech.ch;
|
|
||||||
|
|
||||||
ssl_certificate /etc/letsencrypt/live/server.schooltech.ch/fullchain.pem;
|
|
||||||
ssl_certificate_key /etc/letsencrypt/live/server.schooltech.ch/privkey.pem;
|
|
||||||
ssl_protocols TLSv1.2 TLSv1.3;
|
|
||||||
ssl_prefer_server_ciphers on;
|
|
||||||
|
|
||||||
# ---- Static assets: keine Auth ----
|
|
||||||
location ~* \.(?:js|css|png|jpg|jpeg|gif|ico|svg|webp)$ {
|
|
||||||
proxy_pass https://thinkcentre.local:1003;
|
|
||||||
proxy_set_header Host thinkcentre.local;
|
|
||||||
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 https;
|
|
||||||
# kein proxy_set_header Connection / Upgrade hier
|
|
||||||
}
|
|
||||||
|
|
||||||
# ---- WebSocket-Endpoint ----
|
|
||||||
location /echo {
|
|
||||||
auth_request /nginxauth;
|
|
||||||
proxy_pass https://thinkcentre.local:1003/echo;
|
|
||||||
|
|
||||||
proxy_http_version 1.1;
|
|
||||||
proxy_set_header Upgrade $http_upgrade;
|
|
||||||
proxy_set_header Connection $connection_upgrade;
|
|
||||||
|
|
||||||
proxy_ssl_server_name on;
|
|
||||||
proxy_ssl_name thinkcentre.local;
|
|
||||||
proxy_ssl_verify off;
|
|
||||||
|
|
||||||
proxy_set_header Host thinkcentre.local;
|
|
||||||
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 https;
|
|
||||||
}
|
|
||||||
|
|
||||||
# ---- Hauptanwendung ----
|
|
||||||
location / {
|
|
||||||
auth_request /nginxauth;
|
|
||||||
|
|
||||||
proxy_pass https://thinkcentre.local:1003/;
|
|
||||||
|
|
||||||
proxy_http_version 1.1;
|
|
||||||
proxy_set_header Upgrade $http_upgrade;
|
|
||||||
proxy_set_header Connection $connection_upgrade;
|
|
||||||
|
|
||||||
proxy_ssl_server_name on;
|
|
||||||
proxy_ssl_name thinkcentre.local;
|
|
||||||
proxy_ssl_verify off;
|
|
||||||
|
|
||||||
proxy_set_header Host thinkcentre.local;
|
|
||||||
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 https;
|
|
||||||
proxy_set_header Origin $http_origin;
|
|
||||||
|
|
||||||
proxy_hide_header X-Frame-Options;
|
|
||||||
add_header X-Frame-Options "ALLOWALL" always;
|
|
||||||
|
|
||||||
proxy_hide_header Content-Security-Policy;
|
|
||||||
add_header Content-Security-Policy "frame-ancestors https://server.schooltech.ch" always;
|
|
||||||
}
|
|
||||||
|
|
||||||
# ------------------------------------------------------------
|
|
||||||
# location = /nginxauth (SIMULATION FIX)
|
|
||||||
# ------------------------------------------------------------
|
|
||||||
location = /nginxauth {
|
|
||||||
internal;
|
|
||||||
proxy_pass http://appserverauth:3000/internal/auth; #***# SIMULATION: fehlende proxy_pass eingefügt
|
|
||||||
proxy_set_header Cookie $http_cookie; #***# SIMULATION: Cookie weitergeben
|
|
||||||
|
|
||||||
#***# AUTH HEADER ERWEITERUNG (nur einmal)
|
|
||||||
proxy_set_header X-Original-URI $request_uri;
|
|
||||||
proxy_set_header X-Original-Host $host;
|
|
||||||
proxy_set_header X-Forwarded-Host $host;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
# ------------------------------------------------------------
|
|
||||||
# xyz.server.schooltech.ch (Guacamole on ThinkCentre)
|
|
||||||
# ------------------------------------------------------------
|
|
||||||
server {
|
|
||||||
listen 443 ssl http2;
|
|
||||||
server_name xyz.server.schooltech.ch;
|
|
||||||
|
|
||||||
ssl_certificate /etc/letsencrypt/live/server.schooltech.ch/fullchain.pem;
|
|
||||||
ssl_certificate_key /etc/letsencrypt/live/server.schooltech.ch/privkey.pem;
|
|
||||||
ssl_protocols TLSv1.2 TLSv1.3;
|
|
||||||
ssl_prefer_server_ciphers on;
|
|
||||||
|
|
||||||
location / {
|
|
||||||
auth_request /nginxauth; # Auth prüfen
|
|
||||||
|
|
||||||
proxy_pass http://thinkcentre.local:8080/;
|
|
||||||
|
|
||||||
proxy_http_version 1.1;
|
|
||||||
proxy_set_header Upgrade $http_upgrade;
|
|
||||||
proxy_set_header Connection $connection_upgrade;
|
|
||||||
|
|
||||||
# Proxy Header (Upstream erwartet thinkcentre.local)
|
|
||||||
proxy_set_header Host thinkcentre.local; # bewusst: Upstream Host-Expectation
|
|
||||||
proxy_set_header Origin $http_origin;
|
|
||||||
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 https;
|
|
||||||
|
|
||||||
# iFrame erlauben
|
|
||||||
proxy_hide_header X-Frame-Options;
|
|
||||||
add_header X-Frame-Options "ALLOWALL" always;
|
|
||||||
|
|
||||||
proxy_hide_header Content-Security-Policy;
|
|
||||||
add_header Content-Security-Policy "frame-ancestors *" always;
|
|
||||||
}
|
|
||||||
|
|
||||||
location = /nginxauth {
|
|
||||||
internal;
|
|
||||||
proxy_pass http://appserverauth:3000/internal/auth; #***# XYZ: proxy_pass wie überall
|
|
||||||
proxy_set_header Cookie $http_cookie;
|
|
||||||
|
|
||||||
proxy_set_header X-Original-URI $request_uri;
|
|
||||||
|
|
||||||
#***# XYZ AUTH HOST: Original-Host weitergeben (wichtig für Redirects/Checks)
|
|
||||||
proxy_set_header X-Original-Host $host;
|
|
||||||
proxy_set_header X-Forwarded-Host $host;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
# ------------------------------------------------------------
|
|
||||||
# portainer.server.schooltech.ch
|
|
||||||
# ------------------------------------------------------------
|
|
||||||
server {
|
|
||||||
listen 443 ssl http2;
|
|
||||||
server_name portainer.server.schooltech.ch;
|
|
||||||
|
|
||||||
ssl_certificate /etc/letsencrypt/live/server.schooltech.ch/fullchain.pem;
|
|
||||||
ssl_certificate_key /etc/letsencrypt/live/server.schooltech.ch/privkey.pem;
|
|
||||||
ssl_protocols TLSv1.2 TLSv1.3;
|
|
||||||
ssl_prefer_server_ciphers on;
|
|
||||||
|
|
||||||
#***# PORTAINER: API direkt weiterleiten (kein auth_request)
|
|
||||||
location ^~ /api/ {
|
|
||||||
proxy_pass http://127.0.0.1:9000; #***# auf lokalen Portainer HTTP Backend zeigen
|
|
||||||
proxy_http_version 1.1;
|
|
||||||
proxy_set_header Host $host;
|
|
||||||
proxy_set_header X-Forwarded-Host $host;
|
|
||||||
proxy_set_header X-Forwarded-Proto https;
|
|
||||||
proxy_set_header X-Real-IP $remote_addr;
|
|
||||||
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
|
||||||
}
|
|
||||||
|
|
||||||
#***# PORTAINER: statische Assets / locales ebenfalls ohne auth (wichtig für i18n)
|
|
||||||
location ~* \.(?:js|css|json|png|jpg|jpeg|gif|ico|svg|woff2?)$ {
|
|
||||||
proxy_pass http://127.0.0.1:9000;
|
|
||||||
proxy_set_header Host $host;
|
|
||||||
proxy_set_header X-Forwarded-Proto https;
|
|
||||||
proxy_set_header X-Real-IP $remote_addr;
|
|
||||||
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
|
||||||
}
|
|
||||||
|
|
||||||
location ^~ /locales/ {
|
|
||||||
# explizit für i18n Pfade
|
|
||||||
proxy_pass http://127.0.0.1:9000;
|
|
||||||
proxy_set_header Host $host;
|
|
||||||
proxy_set_header X-Forwarded-Proto https;
|
|
||||||
}
|
|
||||||
|
|
||||||
# Haupt-UI: auth_request greift nur hier (UI), nicht für /api/ oder Assets
|
|
||||||
location / {
|
|
||||||
auth_request /nginxauth;
|
|
||||||
|
|
||||||
proxy_pass http://127.0.0.1:9000/; #***# auf lokales Portainer HTTP Backend zeigen
|
|
||||||
|
|
||||||
proxy_http_version 1.1;
|
|
||||||
proxy_set_header Upgrade $http_upgrade;
|
|
||||||
proxy_set_header Connection $connection_upgrade;
|
|
||||||
|
|
||||||
#***# PORTAINER HOST FIX:
|
|
||||||
proxy_set_header Host $host; #***# PORTAINER HOST
|
|
||||||
proxy_set_header X-Forwarded-Host $host; #***# PORTAINER HOST
|
|
||||||
proxy_set_header X-Forwarded-Proto https; #***# PORTAINER HOST
|
|
||||||
|
|
||||||
proxy_set_header Origin $http_origin;
|
|
||||||
proxy_set_header X-Real-IP $remote_addr;
|
|
||||||
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
|
||||||
|
|
||||||
proxy_hide_header X-Frame-Options;
|
|
||||||
add_header X-Frame-Options "ALLOWALL" always;
|
|
||||||
|
|
||||||
proxy_hide_header Content-Security-Policy;
|
|
||||||
add_header Content-Security-Policy "frame-ancestors *" always;
|
|
||||||
}
|
|
||||||
|
|
||||||
location = /nginxauth {
|
|
||||||
internal;
|
|
||||||
proxy_pass http://appserverauth:3000/internal/auth; #***# AUTH
|
|
||||||
proxy_set_header Cookie $http_cookie; #***# AUTH
|
|
||||||
|
|
||||||
#***# AUTH HEADER ERWEITERUNG
|
|
||||||
proxy_set_header X-Original-URI $request_uri;
|
|
||||||
proxy_set_header X-Original-Host $host;
|
|
||||||
proxy_set_header X-Forwarded-Host $host;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,31 +0,0 @@
|
|||||||
user www-data;
|
|
||||||
worker_processes auto;
|
|
||||||
pid /run/nginx.pid;
|
|
||||||
|
|
||||||
events {
|
|
||||||
worker_connections 1024;
|
|
||||||
}
|
|
||||||
|
|
||||||
http {
|
|
||||||
log_format main '$remote_addr - $remote_user [$time_local] "$request" '
|
|
||||||
'$status $body_bytes_sent "$http_referer" "$http_user_agent" "$http_x_forwarded_for"';
|
|
||||||
access_log /var/log/nginx/access.log main;
|
|
||||||
error_log /var/log/nginx/error.log info;
|
|
||||||
|
|
||||||
include /etc/nginx/mime.types;
|
|
||||||
default_type application/octet-stream;
|
|
||||||
|
|
||||||
# Upgrade map (WebSockets)
|
|
||||||
map $http_upgrade $connection_upgrade {
|
|
||||||
default upgrade;
|
|
||||||
'' close;
|
|
||||||
}
|
|
||||||
|
|
||||||
sendfile on;
|
|
||||||
keepalive_timeout 65;
|
|
||||||
gzip on;
|
|
||||||
|
|
||||||
# Include modulare Server-Configs
|
|
||||||
include /etc/nginx/conf.d/*.conf;
|
|
||||||
}
|
|
||||||
|
|
||||||
1
auth/node_modules/.bin/mime
generated
vendored
1
auth/node_modules/.bin/mime
generated
vendored
@@ -1 +0,0 @@
|
|||||||
../mime/cli.js
|
|
||||||
8
auth/node_modules/.bin/mime
generated
vendored
Executable file
8
auth/node_modules/.bin/mime
generated
vendored
Executable file
@@ -0,0 +1,8 @@
|
|||||||
|
#!/usr/bin/env node
|
||||||
|
|
||||||
|
var mime = require('./mime.js');
|
||||||
|
var file = process.argv[2];
|
||||||
|
var type = mime.lookup(file);
|
||||||
|
|
||||||
|
process.stdout.write(type + '\n');
|
||||||
|
|
||||||
1
auth/node_modules/.bin/node-gyp-build
generated
vendored
1
auth/node_modules/.bin/node-gyp-build
generated
vendored
@@ -1 +0,0 @@
|
|||||||
../node-gyp-build/bin.js
|
|
||||||
84
auth/node_modules/.bin/node-gyp-build
generated
vendored
Executable file
84
auth/node_modules/.bin/node-gyp-build
generated
vendored
Executable file
@@ -0,0 +1,84 @@
|
|||||||
|
#!/usr/bin/env node
|
||||||
|
|
||||||
|
var proc = require('child_process')
|
||||||
|
var os = require('os')
|
||||||
|
var path = require('path')
|
||||||
|
|
||||||
|
if (!buildFromSource()) {
|
||||||
|
proc.exec('node-gyp-build-test', function (err, stdout, stderr) {
|
||||||
|
if (err) {
|
||||||
|
if (verbose()) console.error(stderr)
|
||||||
|
preinstall()
|
||||||
|
}
|
||||||
|
})
|
||||||
|
} else {
|
||||||
|
preinstall()
|
||||||
|
}
|
||||||
|
|
||||||
|
function build () {
|
||||||
|
var win32 = os.platform() === 'win32'
|
||||||
|
var shell = win32
|
||||||
|
var args = [win32 ? 'node-gyp.cmd' : 'node-gyp', 'rebuild']
|
||||||
|
|
||||||
|
try {
|
||||||
|
var pkg = require('node-gyp/package.json')
|
||||||
|
args = [
|
||||||
|
process.execPath,
|
||||||
|
path.join(require.resolve('node-gyp/package.json'), '..', typeof pkg.bin === 'string' ? pkg.bin : pkg.bin['node-gyp']),
|
||||||
|
'rebuild'
|
||||||
|
]
|
||||||
|
shell = false
|
||||||
|
} catch (_) {}
|
||||||
|
|
||||||
|
proc.spawn(args[0], args.slice(1), { stdio: 'inherit', shell, windowsHide: true }).on('exit', function (code) {
|
||||||
|
if (code || !process.argv[3]) process.exit(code)
|
||||||
|
exec(process.argv[3]).on('exit', function (code) {
|
||||||
|
process.exit(code)
|
||||||
|
})
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
function preinstall () {
|
||||||
|
if (!process.argv[2]) return build()
|
||||||
|
exec(process.argv[2]).on('exit', function (code) {
|
||||||
|
if (code) process.exit(code)
|
||||||
|
build()
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
function exec (cmd) {
|
||||||
|
if (process.platform !== 'win32') {
|
||||||
|
var shell = os.platform() === 'android' ? 'sh' : true
|
||||||
|
return proc.spawn(cmd, [], {
|
||||||
|
shell,
|
||||||
|
stdio: 'inherit'
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
return proc.spawn(cmd, [], {
|
||||||
|
windowsVerbatimArguments: true,
|
||||||
|
stdio: 'inherit',
|
||||||
|
shell: true,
|
||||||
|
windowsHide: true
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
function buildFromSource () {
|
||||||
|
return hasFlag('--build-from-source') || process.env.npm_config_build_from_source === 'true'
|
||||||
|
}
|
||||||
|
|
||||||
|
function verbose () {
|
||||||
|
return hasFlag('--verbose') || process.env.npm_config_loglevel === 'verbose'
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO (next major): remove in favor of env.npm_config_* which works since npm
|
||||||
|
// 0.1.8 while npm_config_argv will stop working in npm 7. See npm/rfcs#90
|
||||||
|
function hasFlag (flag) {
|
||||||
|
if (!process.env.npm_config_argv) return false
|
||||||
|
|
||||||
|
try {
|
||||||
|
return JSON.parse(process.env.npm_config_argv).original.indexOf(flag) !== -1
|
||||||
|
} catch (_) {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
}
|
||||||
1
auth/node_modules/.bin/node-gyp-build-optional
generated
vendored
1
auth/node_modules/.bin/node-gyp-build-optional
generated
vendored
@@ -1 +0,0 @@
|
|||||||
../node-gyp-build/optional.js
|
|
||||||
7
auth/node_modules/.bin/node-gyp-build-optional
generated
vendored
Executable file
7
auth/node_modules/.bin/node-gyp-build-optional
generated
vendored
Executable file
@@ -0,0 +1,7 @@
|
|||||||
|
#!/usr/bin/env node
|
||||||
|
|
||||||
|
/*
|
||||||
|
I am only useful as an install script to make node-gyp not compile for purely optional native deps
|
||||||
|
*/
|
||||||
|
|
||||||
|
process.exit(0)
|
||||||
1
auth/node_modules/.bin/node-gyp-build-test
generated
vendored
1
auth/node_modules/.bin/node-gyp-build-test
generated
vendored
@@ -1 +0,0 @@
|
|||||||
../node-gyp-build/build-test.js
|
|
||||||
19
auth/node_modules/.bin/node-gyp-build-test
generated
vendored
Executable file
19
auth/node_modules/.bin/node-gyp-build-test
generated
vendored
Executable file
@@ -0,0 +1,19 @@
|
|||||||
|
#!/usr/bin/env node
|
||||||
|
|
||||||
|
process.env.NODE_ENV = 'test'
|
||||||
|
|
||||||
|
var path = require('path')
|
||||||
|
var test = null
|
||||||
|
|
||||||
|
try {
|
||||||
|
var pkg = require(path.join(process.cwd(), 'package.json'))
|
||||||
|
if (pkg.name && process.env[pkg.name.toUpperCase().replace(/-/g, '_')]) {
|
||||||
|
process.exit(0)
|
||||||
|
}
|
||||||
|
test = pkg.prebuild.test
|
||||||
|
} catch (err) {
|
||||||
|
// do nothing
|
||||||
|
}
|
||||||
|
|
||||||
|
if (test) require(path.join(process.cwd(), test))
|
||||||
|
else require('./')()
|
||||||
@@ -1,3 +1,4 @@
|
|||||||
{
|
{
|
||||||
"admin": "$2b$12$a6.TdWrJruzs1qfwfMBNsuJApkRwUiDG5IZfbtclNPhYEAsIJGMHC"
|
"admin": "$2b$12$a6.TdWrJruzs1qfwfMBNsuJApkRwUiDG5IZfbtclNPhYEAsIJGMHC",
|
||||||
|
"abc": "$2b$12$HurtBQkjJyXOV2qFpWkFv.wAIRs6B01sSSScaHMdUrbuBWE0aoyIa"
|
||||||
}
|
}
|
||||||
283
connect-proxies.sh
Executable file
283
connect-proxies.sh
Executable file
@@ -0,0 +1,283 @@
|
|||||||
|
#!/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).
|
||||||
|
|
||||||
|
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" <<NGINX
|
||||||
|
# Automatisch generiert – nicht editieren
|
||||||
|
map \$http_upgrade \$connection_upgrade {
|
||||||
|
default upgrade;
|
||||||
|
'' close;
|
||||||
|
}
|
||||||
|
$RESOLVER_LINE
|
||||||
|
NGINX
|
||||||
|
# <<< END CHANGE
|
||||||
|
|
||||||
|
# 2) Alte generierte Confs entfernen
|
||||||
|
rm -f "$CONF_DIR/"*"$HTTPS_SUFFIX" 2>/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" <<NGINX
|
||||||
|
# Auto-generated - 443 static site
|
||||||
|
server {
|
||||||
|
listen ${LISTEN_PORT} ssl http2;
|
||||||
|
listen [::]:${LISTEN_PORT} ssl http2;
|
||||||
|
server_name $SERVER_NAME;
|
||||||
|
|
||||||
|
ssl_certificate $FULLCHAIN;
|
||||||
|
ssl_certificate_key $PRIVKEY;
|
||||||
|
|
||||||
|
ssl_protocols TLSv1.2 TLSv1.3;
|
||||||
|
ssl_ciphers HIGH:!aNULL:!MD5;
|
||||||
|
|
||||||
|
root /usr/share/nginx/html;
|
||||||
|
index index.html;
|
||||||
|
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
|
location / {
|
||||||
|
try_files \$uri \$uri/ /index.html;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
NGINX
|
||||||
|
|
||||||
|
else
|
||||||
|
# >>> 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" <<NGINX
|
||||||
|
# Auto-generated - 443 placeholder (DNS failed)
|
||||||
|
server {
|
||||||
|
listen ${LISTEN_PORT} ssl http2;
|
||||||
|
listen [::]:${LISTEN_PORT} ssl http2;
|
||||||
|
server_name $SERVER_NAME;
|
||||||
|
|
||||||
|
ssl_certificate $FULLCHAIN;
|
||||||
|
ssl_certificate_key $PRIVKEY;
|
||||||
|
|
||||||
|
ssl_protocols TLSv1.2 TLSv1.3;
|
||||||
|
ssl_ciphers HIGH:!aNULL:!MD5;
|
||||||
|
|
||||||
|
location / {
|
||||||
|
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>DNS-Auflösung fehlgeschlagen. Bitte später erneut versuchen.</p></body></html>";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
NGINX
|
||||||
|
else
|
||||||
|
# 443 Proxy – DNS ok/unknown: Laufzeit-Auflösung + freundlicher 503 bei Downstreams
|
||||||
|
cat > "$HTTPS_OUT" <<NGINX
|
||||||
|
# Auto-generated - 443 reverse proxy
|
||||||
|
server {
|
||||||
|
listen ${LISTEN_PORT} ssl http2;
|
||||||
|
listen [::]:${LISTEN_PORT} ssl http2;
|
||||||
|
server_name $SERVER_NAME;
|
||||||
|
|
||||||
|
ssl_certificate $FULLCHAIN;
|
||||||
|
ssl_certificate_key $PRIVKEY;
|
||||||
|
|
||||||
|
ssl_protocols TLSv1.2 TLSv1.3;
|
||||||
|
ssl_ciphers HIGH:!aNULL:!MD5;
|
||||||
|
|
||||||
|
# Fehler sauber abfangen und 503 liefern (statt rohe 502/504)
|
||||||
|
proxy_intercept_errors on;
|
||||||
|
error_page 502 503 504 = @service_down;
|
||||||
|
|
||||||
|
location / {
|
||||||
|
# >>> 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 "<!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
|
||||||
|
fi
|
||||||
|
# <<< END NEW
|
||||||
|
fi
|
||||||
|
|
||||||
|
# 80->443 Redirect-Server nur, wenn gewünscht
|
||||||
|
if [ "$HTTP_BEHAVIOR" = "redirect" ]; then
|
||||||
|
cat > "$HTTP_REDIRECT_OUT" <<NGINX
|
||||||
|
# Auto-generated – 80->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."
|
||||||
72
docker-compose.yaml
Executable file → Normal file
72
docker-compose.yaml
Executable file → Normal file
@@ -1,34 +1,86 @@
|
|||||||
services:
|
services:
|
||||||
|
|
||||||
|
openssh-server:
|
||||||
|
image: ghcr.io/linuxserver/openssh-server:latest
|
||||||
|
container_name: appServer_TunnelHead
|
||||||
|
hostname: appServerTunnel
|
||||||
|
ports:
|
||||||
|
- "2255:2222" # Access to R-Tunnel from public Internet
|
||||||
|
- "1883:1883" # Forwarded to Mosqitto
|
||||||
|
- "9222:9222" # SSH to Informatikweb
|
||||||
|
environment:
|
||||||
|
- PUID=1000
|
||||||
|
- PGID=1000
|
||||||
|
- TZ=Europe/Zurich
|
||||||
|
- PASSWORD_ACCESS=false
|
||||||
|
- USER_NAME=tunnel
|
||||||
|
- SUDO_ACCESS=false
|
||||||
|
- CUSTOM_CONT_INIT=true
|
||||||
|
volumes:
|
||||||
|
- /home/chk/Documents/appServerTunnelHead/custom-cont-init.d:/custom-cont-init.d
|
||||||
|
- /home/chk/Documents/appServerTunnelHead/config:/config
|
||||||
|
networks:
|
||||||
|
- appRobotNet
|
||||||
|
restart: unless-stopped
|
||||||
|
|
||||||
AppServerPortalUI:
|
AppServerPortalUI:
|
||||||
image: nginx:alpine
|
image: nginx:alpine
|
||||||
container_name: appServer_PortalUI
|
container_name: appServer_PortalUI
|
||||||
volumes:
|
volumes:
|
||||||
- /home/chk/Documents/AppServerPortalUI/nginx.conf:/etc/nginx/conf.d/default.conf:ro
|
- /home/chk/Documents/appServerPortalUI/nginx.conf:/etc/nginx/conf.d/default.conf:ro
|
||||||
- /home/chk/Documents/AppServerPortalUI/public:/usr/share/nginx/html:ro
|
- /home/chk/Documents/appServerPortalUI/public:/usr/share/nginx/html:ro
|
||||||
- /home/chk/Documents/AppServerPortalUI/certs:/etc/ssl:ro
|
# Let's Encrypt mounts
|
||||||
|
- /home/chk/Documents/appServerPortalUI/letsencrypt/conf:/etc/letsencrypt:ro
|
||||||
|
- /home/chk/Documents/appServerPortalUI/letsencrypt/www:/var/www/certbot:ro
|
||||||
|
# PortForwarding-Script-etc
|
||||||
|
- /home/chk/Documents/appServerPortalUI/forwarding.conf:/etc/nginx/forwarding.conf:ro
|
||||||
|
- /home/chk/Documents/appServerPortalUI/connect-proxies.sh:/docker-entrypoint.d/40-connect-proxies.sh:ro
|
||||||
ports:
|
ports:
|
||||||
- "5080:80"
|
- "80:80"
|
||||||
- "443:443"
|
- "443:443"
|
||||||
networks:
|
networks:
|
||||||
- default
|
- appRobotNet
|
||||||
restart: unless-stopped
|
restart: unless-stopped
|
||||||
command: ["nginx", "-g", "daemon off;"]
|
command: ["nginx", "-g", "daemon off;"]
|
||||||
|
|
||||||
AppServerAuth:
|
appServer_LetsEncryptFetcher:
|
||||||
image: node:18
|
image: certbot/certbot
|
||||||
container_name: appServer_Auth
|
container_name: appServer_LetsEncryptFetcher
|
||||||
volumes:
|
volumes:
|
||||||
- /home/chk/Documents/AppServerPortalUI/auth:/usr/src/app
|
- /home/chk/Documents/appServerPortalUI/letsencrypt/conf:/etc/letsencrypt
|
||||||
|
- /home/chk/Documents/appServerPortalUI/letsencrypt/www:/var/www/certbot
|
||||||
|
entrypoint: "/bin/sh -c 'trap exit TERM; while :; do sleep 3600; done'"
|
||||||
|
|
||||||
|
AppServerAuth:
|
||||||
|
image: node:24-alpine
|
||||||
|
container_name: AppServerAuth
|
||||||
|
volumes:
|
||||||
|
- /home/chk/Documents/appServerPortalUI/auth:/usr/src/app
|
||||||
working_dir: /usr/src/app
|
working_dir: /usr/src/app
|
||||||
command: sh -c "npm install && node auth.js"
|
command: sh -c "npm install && node auth.js"
|
||||||
ports:
|
ports:
|
||||||
- "10300:3000" # optional, für Tests
|
- "10300:3000" # optional, für Tests
|
||||||
networks:
|
networks:
|
||||||
- default
|
- default
|
||||||
|
- appRobotNet
|
||||||
restart: unless-stopped
|
restart: unless-stopped
|
||||||
|
|
||||||
|
appServerGuacamole:
|
||||||
|
image: abesnier/guacamole:latest
|
||||||
|
container_name: appServer_guacamole
|
||||||
|
ports:
|
||||||
|
- "8088:8080"
|
||||||
|
extra_hosts:
|
||||||
|
- "host.docker.internal:host-gateway"
|
||||||
|
volumes:
|
||||||
|
- /home/chk/Documents/appServerGuacamole/config:/config/guacamole
|
||||||
|
- /home/chk/Documents/appServerGuacamole/postgres:/config/postgres
|
||||||
|
networks:
|
||||||
|
- appRobotNet
|
||||||
|
restart: unless-stopped
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
networks:
|
networks:
|
||||||
default:
|
default:
|
||||||
|
appRobotNet:
|
||||||
|
|||||||
813
dokumentation/2026_03_21___q1_Auth.txt
Executable file
813
dokumentation/2026_03_21___q1_Auth.txt
Executable file
@@ -0,0 +1,813 @@
|
|||||||
|
== PortalUI mit User-Verwaltung ==
|
||||||
|
|
||||||
|
Mein Server hat u.A. zwei Docker Container: Einmal das Portal, und einmal einen Authentifikations-Dienst.
|
||||||
|
|
||||||
|
|
||||||
|
AppServerPortalUI:
|
||||||
|
image: nginx:alpine
|
||||||
|
container_name: appServer_PortalUI
|
||||||
|
volumes:
|
||||||
|
- /home/chk/Documents/appServerPortalUI/nginx.conf:/etc/nginx/conf.d/default.conf:ro
|
||||||
|
- /home/chk/Documents/appServerPortalUI/public:/usr/share/nginx/html:ro
|
||||||
|
# Let's Encrypt mounts
|
||||||
|
- /home/chk/Documents/appServerPortalUI/letsencrypt/conf:/etc/letsencrypt:ro
|
||||||
|
- /home/chk/Documents/appServerPortalUI/letsencrypt/www:/var/www/certbot:ro
|
||||||
|
# PortForwarding-Script-etc
|
||||||
|
- /home/chk/Documents/appServerPortalUI/forwarding.conf:/etc/nginx/forwarding.conf:ro
|
||||||
|
- /home/chk/Documents/appServerPortalUI/connect-proxies.sh:/docker-entrypoint.d/40-connect-proxies.sh:ro
|
||||||
|
ports:
|
||||||
|
- "80:80"
|
||||||
|
- "443:443"
|
||||||
|
networks:
|
||||||
|
- appRobotNet
|
||||||
|
restart: unless-stopped
|
||||||
|
command: ["nginx", "-g", "daemon off;"]
|
||||||
|
|
||||||
|
AppServerAuth:
|
||||||
|
image: node:24-alpine
|
||||||
|
container_name: appServer_Auth
|
||||||
|
volumes:
|
||||||
|
- /home/chk/Documents/appServerPortalUI/auth:/usr/src/app
|
||||||
|
working_dir: /usr/src/app
|
||||||
|
command: sh -c "npm install && node auth.js"
|
||||||
|
ports:
|
||||||
|
- "10300:3000" # optional, für Tests
|
||||||
|
networks:
|
||||||
|
- default
|
||||||
|
- appRobotNet
|
||||||
|
restart: unless-stopped
|
||||||
|
|
||||||
|
|
||||||
|
== /home/chk/Documents/appServerPortalUI/nginx.conf ==
|
||||||
|
|
||||||
|
# /etc/nginx/conf.d/default.conf
|
||||||
|
# IMMER aktive HTTP-Konfiguration (Port 80)
|
||||||
|
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";
|
||||||
|
}
|
||||||
|
|
||||||
|
# Deine Default-Page
|
||||||
|
root /usr/share/nginx/html;
|
||||||
|
index index.html;
|
||||||
|
|
||||||
|
location = / { try_files /index.html =404; }
|
||||||
|
location / { try_files $uri $uri/ =404; }
|
||||||
|
}
|
||||||
|
|
||||||
|
== nginxPages/10-server-schooltech.conf ==
|
||||||
|
Soll die "Nutzlast" die Pages, die der User verwenden soll, weiterleiten.
|
||||||
|
|
||||||
|
hier gibt es eine ganze reihe weiterer pages, die bereitstehen.
|
||||||
|
server {
|
||||||
|
listen 443 ssl http2;
|
||||||
|
server_name server.schooltech.ch;
|
||||||
|
|
||||||
|
ssl_certificate /etc/letsencrypt/live/server.schooltech.ch/fullchain.pem;
|
||||||
|
ssl_certificate_key /etc/letsencrypt/live/server.schooltech.ch/privkey.pem;
|
||||||
|
ssl_protocols TLSv1.2 TLSv1.3;
|
||||||
|
ssl_prefer_server_ciphers on;
|
||||||
|
|
||||||
|
root /usr/share/nginx/html;
|
||||||
|
index index.html;
|
||||||
|
|
||||||
|
# UI / SPA
|
||||||
|
location / {
|
||||||
|
try_files $uri $uri/ /index.html;
|
||||||
|
}
|
||||||
|
|
||||||
|
# API forwarding (auth)
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
|
# Internal auth endpoint for auth_request
|
||||||
|
location = /nginxauth {
|
||||||
|
internal;
|
||||||
|
proxy_pass http://appserverauth:3000/internal/auth;
|
||||||
|
proxy_set_header Cookie $http_cookie;
|
||||||
|
proxy_set_header X-Original-URI $request_uri;
|
||||||
|
proxy_set_header X-Original-Host $host;
|
||||||
|
proxy_set_header X-Forwarded-Host $host;
|
||||||
|
}
|
||||||
|
|
||||||
|
# Security headers
|
||||||
|
add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" always;
|
||||||
|
}
|
||||||
|
|
||||||
|
== nginxPages/50-subdomains-userA.conf ==
|
||||||
|
Für jeden User gibt es eine reihe von Pages, die eben hier weitergeleitet werden sollen.
|
||||||
|
|
||||||
|
server {
|
||||||
|
listen 443 ssl http2 default_server;
|
||||||
|
server_name _;
|
||||||
|
|
||||||
|
ssl_certificate /etc/letsencrypt/live/server.schooltech.ch/fullchain.pem;
|
||||||
|
ssl_certificate_key /etc/letsencrypt/live/server.schooltech.ch/privkey.pem;
|
||||||
|
ssl_protocols TLSv1.2 TLSv1.3;
|
||||||
|
|
||||||
|
return 444;
|
||||||
|
}
|
||||||
|
|
||||||
|
# ------------------------------------------------------------
|
||||||
|
# portainer.server.schooltech.ch
|
||||||
|
# ------------------------------------------------------------
|
||||||
|
server {
|
||||||
|
listen 443 ssl http2;
|
||||||
|
server_name portainer.server.schooltech.ch;
|
||||||
|
|
||||||
|
ssl_certificate /etc/letsencrypt/live/server.schooltech.ch/fullchain.pem;
|
||||||
|
ssl_certificate_key /etc/letsencrypt/live/server.schooltech.ch/privkey.pem;
|
||||||
|
ssl_protocols TLSv1.2 TLSv1.3;
|
||||||
|
ssl_prefer_server_ciphers on;
|
||||||
|
|
||||||
|
# Auth nur auf UI
|
||||||
|
location / {
|
||||||
|
auth_request /nginxauth;
|
||||||
|
|
||||||
|
proxy_pass http://portainer:9000;
|
||||||
|
proxy_http_version 1.1;
|
||||||
|
|
||||||
|
proxy_set_header Upgrade $http_upgrade;
|
||||||
|
proxy_set_header Connection "upgrade";
|
||||||
|
|
||||||
|
proxy_set_header Host $host;
|
||||||
|
proxy_set_header X-Forwarded-Proto https;
|
||||||
|
proxy_set_header X-Real-IP $remote_addr;
|
||||||
|
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
||||||
|
|
||||||
|
# iFrame-freundlich
|
||||||
|
proxy_hide_header X-Frame-Options;
|
||||||
|
add_header X-Frame-Options "ALLOWALL" always;
|
||||||
|
proxy_hide_header Content-Security-Policy;
|
||||||
|
add_header Content-Security-Policy "frame-ancestors *" always;
|
||||||
|
}
|
||||||
|
|
||||||
|
location = /nginxauth {
|
||||||
|
internal;
|
||||||
|
proxy_pass http://appserverauth:3000/internal/auth;
|
||||||
|
proxy_set_header Cookie $http_cookie;
|
||||||
|
proxy_set_header X-Original-URI $request_uri;
|
||||||
|
proxy_set_header X-Original-Host $host;
|
||||||
|
proxy_set_header X-Forwarded-Host $host;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
# ------------------------------------------------------------
|
||||||
|
# abc.server.schooltech.ch
|
||||||
|
# ------------------------------------------------------------
|
||||||
|
server {
|
||||||
|
listen 443 ssl http2;
|
||||||
|
server_name abc.server.schooltech.ch;
|
||||||
|
|
||||||
|
ssl_certificate /etc/letsencrypt/live/server.schooltech.ch/fullchain.pem;
|
||||||
|
ssl_certificate_key /etc/letsencrypt/live/server.schooltech.ch/privkey.pem;
|
||||||
|
|
||||||
|
root /usr/share/nginx/abc;
|
||||||
|
index index.html;
|
||||||
|
|
||||||
|
location / {
|
||||||
|
try_files $uri $uri/ /index.html;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
# ------------------------------------------------------------
|
||||||
|
# xyz.server.schooltech.ch
|
||||||
|
# ------------------------------------------------------------
|
||||||
|
server {
|
||||||
|
listen 443 ssl http2;
|
||||||
|
server_name xyz.server.schooltech.ch;
|
||||||
|
|
||||||
|
ssl_certificate /etc/letsencrypt/live/server.schooltech.ch/fullchain.pem;
|
||||||
|
ssl_certificate_key /etc/letsencrypt/live/server.schooltech.ch/privkey.pem;
|
||||||
|
|
||||||
|
root /usr/share/nginx/xyz;
|
||||||
|
index index.html;
|
||||||
|
|
||||||
|
location / {
|
||||||
|
try_files $uri $uri/ /index.html;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
diese sind alle unter xxx.server.schooltech.ch erreichbar.
|
||||||
|
Die ganze nginxPages/50-subdomains-userA.conf werden mit einem Script erstellt:
|
||||||
|
|
||||||
|
== connect-proxies.sh ==========
|
||||||
|
|
||||||
|
#!/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).
|
||||||
|
|
||||||
|
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" <<NGINX
|
||||||
|
# Automatisch generiert – nicht editieren
|
||||||
|
map \$http_upgrade \$connection_upgrade {
|
||||||
|
default upgrade;
|
||||||
|
'' close;
|
||||||
|
}
|
||||||
|
$RESOLVER_LINE
|
||||||
|
NGINX
|
||||||
|
# <<< END CHANGE
|
||||||
|
|
||||||
|
# 2) Alte generierte Confs entfernen
|
||||||
|
rm -f "$CONF_DIR/"*"$HTTPS_SUFFIX" 2>/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" <<NGINX
|
||||||
|
# Auto-generated - 443 static site
|
||||||
|
server {
|
||||||
|
listen ${LISTEN_PORT} ssl http2;
|
||||||
|
listen [::]:${LISTEN_PORT} ssl http2;
|
||||||
|
server_name $SERVER_NAME;
|
||||||
|
|
||||||
|
ssl_certificate $FULLCHAIN;
|
||||||
|
ssl_certificate_key $PRIVKEY;
|
||||||
|
|
||||||
|
ssl_protocols TLSv1.2 TLSv1.3;
|
||||||
|
ssl_ciphers HIGH:!aNULL:!MD5;
|
||||||
|
|
||||||
|
root /usr/share/nginx/html;
|
||||||
|
index index.html;
|
||||||
|
|
||||||
|
location / {
|
||||||
|
try_files \$uri \$uri/ /index.html;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
NGINX
|
||||||
|
|
||||||
|
else
|
||||||
|
# >>> 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" <<NGINX
|
||||||
|
# Auto-generated - 443 placeholder (DNS failed)
|
||||||
|
server {
|
||||||
|
listen ${LISTEN_PORT} ssl http2;
|
||||||
|
listen [::]:${LISTEN_PORT} ssl http2;
|
||||||
|
server_name $SERVER_NAME;
|
||||||
|
|
||||||
|
ssl_certificate $FULLCHAIN;
|
||||||
|
ssl_certificate_key $PRIVKEY;
|
||||||
|
|
||||||
|
ssl_protocols TLSv1.2 TLSv1.3;
|
||||||
|
ssl_ciphers HIGH:!aNULL:!MD5;
|
||||||
|
|
||||||
|
location / {
|
||||||
|
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>DNS-Auflösung fehlgeschlagen. Bitte später erneut versuchen.</p></body></html>";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
NGINX
|
||||||
|
else
|
||||||
|
# 443 Proxy – DNS ok/unknown: Laufzeit-Auflösung + freundlicher 503 bei Downstreams
|
||||||
|
cat > "$HTTPS_OUT" <<NGINX
|
||||||
|
# Auto-generated - 443 reverse proxy
|
||||||
|
server {
|
||||||
|
listen ${LISTEN_PORT} ssl http2;
|
||||||
|
listen [::]:${LISTEN_PORT} ssl http2;
|
||||||
|
server_name $SERVER_NAME;
|
||||||
|
|
||||||
|
ssl_certificate $FULLCHAIN;
|
||||||
|
ssl_certificate_key $PRIVKEY;
|
||||||
|
|
||||||
|
ssl_protocols TLSv1.2 TLSv1.3;
|
||||||
|
ssl_ciphers HIGH:!aNULL:!MD5;
|
||||||
|
|
||||||
|
# Fehler sauber abfangen und 503 liefern (statt rohe 502/504)
|
||||||
|
proxy_intercept_errors on;
|
||||||
|
error_page 502 503 504 = @service_down;
|
||||||
|
|
||||||
|
location / {
|
||||||
|
# >>> 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 "<!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
|
||||||
|
fi
|
||||||
|
# <<< END NEW
|
||||||
|
fi
|
||||||
|
|
||||||
|
# 80->443 Redirect-Server nur, wenn gewünscht
|
||||||
|
if [ "$HTTP_BEHAVIOR" = "redirect" ]; then
|
||||||
|
cat > "$HTTP_REDIRECT_OUT" <<NGINX
|
||||||
|
# Auto-generated – 80->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."
|
||||||
|
|
||||||
|
=====
|
||||||
|
wobei die daten dann im forwarding.conf stehen:
|
||||||
|
|
||||||
|
|
||||||
|
# 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
|
||||||
|
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
|
||||||
|
|
||||||
|
|
||||||
|
=== Das PortalUI stellt neben den Weiterleitungen auch noch eine Navigations-Page
|
||||||
|
zur Verfügung: index.html mit app.js
|
||||||
|
|
||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="de">
|
||||||
|
<head>
|
||||||
|
<meta charset="utf-8" />
|
||||||
|
<title>Service Portal</title>
|
||||||
|
<link rel="stylesheet" href="style.css" />
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
|
||||||
|
<header id="header">
|
||||||
|
<div class="logo">schooltech</div>
|
||||||
|
<nav id="services"></nav>
|
||||||
|
<div class="user">
|
||||||
|
<button id="login-btn">Login</button>
|
||||||
|
</div>
|
||||||
|
</header>
|
||||||
|
|
||||||
|
<main>
|
||||||
|
<h1>server.schooltech.ch - Service Portal</h1>
|
||||||
|
|
||||||
|
<!-- iFrame für Services -->
|
||||||
|
<iframe id="service-frame" style="width:100%;height:80vh;display:none;"></iframe>
|
||||||
|
|
||||||
|
<!-- Login Modal -->
|
||||||
|
<div id="login-modal" style="display:none;">
|
||||||
|
<label>User: <input type="text" id="username"/></label>
|
||||||
|
<label>Pass: <input type="password" id="password"/></label>
|
||||||
|
<button id="login-submit">Login</button>
|
||||||
|
<div id="login-msg"></div>
|
||||||
|
</div>
|
||||||
|
</main>
|
||||||
|
|
||||||
|
|
||||||
|
<script src="app.js"></script>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
|
|
||||||
|
|
||||||
|
// ==== FRONTEND app.js ====
|
||||||
|
|
||||||
|
// Service-Liste
|
||||||
|
const services = [
|
||||||
|
{ id: "abc", name: "Control GamePad", url: "https://abc.server.schooltech.ch/" },
|
||||||
|
{ id: "xyz", name: "Guacamole", url: "https://xyz.server.schooltech.ch/" },
|
||||||
|
{ id: "sim", name: "Simulation", url: "https://simulation.server.schooltech.ch/" },
|
||||||
|
{ id: "portainer", name: "Portainer", url: "https://portainer.server.schooltech.ch/" }
|
||||||
|
];
|
||||||
|
|
||||||
|
// DOM-Elemente
|
||||||
|
const iframe = document.getElementById("service-frame");
|
||||||
|
const loginModal = document.getElementById("login-modal");
|
||||||
|
const loginBtn = document.getElementById("login-btn");
|
||||||
|
const loginSubmit = document.getElementById("login-submit");
|
||||||
|
const loginMsg = document.getElementById("login-msg");
|
||||||
|
const nav = document.getElementById("services");
|
||||||
|
|
||||||
|
const usernameInput = document.getElementById("username");
|
||||||
|
const passwordInput = document.getElementById("password");
|
||||||
|
|
||||||
|
let loggedIn = false;
|
||||||
|
|
||||||
|
// ===========================
|
||||||
|
// Login anzeigen
|
||||||
|
// ===========================
|
||||||
|
function switchToLogin() {
|
||||||
|
loginBtn.textContent = "Login";
|
||||||
|
loginBtn.onclick = () => {
|
||||||
|
loginModal.style.display = "block";
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
// ===========================
|
||||||
|
// Logout anzeigen
|
||||||
|
// ===========================
|
||||||
|
function switchToLogout() {
|
||||||
|
loginBtn.textContent = "Logout";
|
||||||
|
loginBtn.onclick = async () => {
|
||||||
|
try {
|
||||||
|
await fetch("/api/logout", { method: "POST" });
|
||||||
|
} catch (e) {
|
||||||
|
console.warn("Logout request failed:", e);
|
||||||
|
}
|
||||||
|
performLocalLogout();
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
// ===========================
|
||||||
|
// Lokales Logout
|
||||||
|
// ===========================
|
||||||
|
function performLocalLogout() {
|
||||||
|
loggedIn = false;
|
||||||
|
iframe.src = "";
|
||||||
|
iframe.style.display = "none";
|
||||||
|
nav.innerHTML = "";
|
||||||
|
loginModal.style.display = "block";
|
||||||
|
switchToLogin();
|
||||||
|
}
|
||||||
|
|
||||||
|
// ===========================
|
||||||
|
// Login-Logik
|
||||||
|
// ===========================
|
||||||
|
async function doLogin() {
|
||||||
|
const user = usernameInput.value;
|
||||||
|
const pass = passwordInput.value;
|
||||||
|
|
||||||
|
try {
|
||||||
|
const res = await fetch("/api/login", {
|
||||||
|
method: "POST",
|
||||||
|
headers: { "Content-Type": "application/json" },
|
||||||
|
body: JSON.stringify({ user, pass })
|
||||||
|
});
|
||||||
|
|
||||||
|
if (res.ok) {
|
||||||
|
loggedIn = true;
|
||||||
|
loginModal.style.display = "none";
|
||||||
|
loginMsg.textContent = "";
|
||||||
|
setupServiceButtons();
|
||||||
|
switchToLogout();
|
||||||
|
} else {
|
||||||
|
loginMsg.textContent = "Login fehlgeschlagen";
|
||||||
|
}
|
||||||
|
} catch (e) {
|
||||||
|
loginMsg.textContent = "Fehler: " + e.message;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
loginSubmit.onclick = doLogin;
|
||||||
|
|
||||||
|
// Enter-Taste Login
|
||||||
|
[usernameInput, passwordInput].forEach(input => {
|
||||||
|
input.addEventListener('keydown', (e) => {
|
||||||
|
if (e.key === 'Enter') {
|
||||||
|
e.preventDefault();
|
||||||
|
doLogin();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
// ===========================
|
||||||
|
// Buttons erzeugen
|
||||||
|
// ===========================
|
||||||
|
function setupServiceButtons() {
|
||||||
|
nav.innerHTML = "";
|
||||||
|
services.forEach(svc => {
|
||||||
|
const btn = document.createElement("button");
|
||||||
|
btn.textContent = svc.name;
|
||||||
|
btn.onclick = async () => {
|
||||||
|
try {
|
||||||
|
await fetch('/api/event', {
|
||||||
|
method: 'POST',
|
||||||
|
headers: { 'Content-Type': 'application/json' },
|
||||||
|
body: JSON.stringify({
|
||||||
|
event: 'open',
|
||||||
|
service: svc.id,
|
||||||
|
url: svc.url
|
||||||
|
})
|
||||||
|
});
|
||||||
|
} catch(e) {
|
||||||
|
console.error('Event log failed', e);
|
||||||
|
}
|
||||||
|
openService(svc);
|
||||||
|
};
|
||||||
|
nav.appendChild(btn);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
// ===========================
|
||||||
|
// Service öffnen
|
||||||
|
// ===========================
|
||||||
|
function openService(svc) {
|
||||||
|
iframe.src = svc.url;
|
||||||
|
iframe.style.display = "block";
|
||||||
|
window.scrollTo(0,0);
|
||||||
|
}
|
||||||
|
|
||||||
|
// ===========================
|
||||||
|
// Session Status beim Laden prüfen
|
||||||
|
// ===========================
|
||||||
|
(async function checkStatus() {
|
||||||
|
try {
|
||||||
|
const r = await fetch('/api/status');
|
||||||
|
if (r.ok) {
|
||||||
|
loggedIn = true;
|
||||||
|
setupServiceButtons();
|
||||||
|
switchToLogout();
|
||||||
|
} else {
|
||||||
|
switchToLogin();
|
||||||
|
}
|
||||||
|
} catch (e) {
|
||||||
|
switchToLogin();
|
||||||
|
}
|
||||||
|
})();
|
||||||
|
|
||||||
|
|
||||||
|
app.js muss sicherlich noch ausgebaut werden. Hier sind nur ein Bruchteil der relevanten
|
||||||
|
Pages verlinkt. Aber das kann später erfolgen.
|
||||||
|
|
||||||
|
== auth/auth.js
|
||||||
|
import express from "express";
|
||||||
|
import cookieParser from "cookie-parser";
|
||||||
|
import bcrypt from "bcrypt";
|
||||||
|
import fs from "fs";
|
||||||
|
import crypto from "crypto";
|
||||||
|
|
||||||
|
const USERS = JSON.parse(fs.readFileSync("./users.json"));
|
||||||
|
const SESSIONS = {}; // in-memory session store
|
||||||
|
|
||||||
|
const app = express();
|
||||||
|
app.use(express.json());
|
||||||
|
app.use(cookieParser());
|
||||||
|
|
||||||
|
app.post("/api/login", async (req,res)=>{
|
||||||
|
const { user, pass } = req.body;
|
||||||
|
|
||||||
|
console.log(`Auth-Service login attempt for ${user}`);
|
||||||
|
|
||||||
|
const hash = USERS[user];
|
||||||
|
if(!hash) return res.status(401).send({ ok:false });
|
||||||
|
|
||||||
|
const valid = await bcrypt.compare(pass, hash);
|
||||||
|
if(!valid) return res.status(401).send({ ok:false });
|
||||||
|
|
||||||
|
// create secure random session
|
||||||
|
const sessionID = crypto.randomBytes(32).toString("hex");
|
||||||
|
SESSIONS[sessionID] = {
|
||||||
|
user,
|
||||||
|
created: Date.now()
|
||||||
|
};
|
||||||
|
|
||||||
|
res.cookie("SESSIONID", sessionID, {
|
||||||
|
httpOnly: true,
|
||||||
|
secure: true,
|
||||||
|
domain: ".server.schooltech.ch",
|
||||||
|
sameSite: "None",
|
||||||
|
path: "/"
|
||||||
|
});
|
||||||
|
|
||||||
|
res.status(200).send({ ok:true });
|
||||||
|
});
|
||||||
|
|
||||||
|
// Logout endpoint
|
||||||
|
app.post("/api/logout", (req, res) => {
|
||||||
|
const sid = req.cookies.SESSIONID;
|
||||||
|
if (sid && SESSIONS[sid]) {
|
||||||
|
delete SESSIONS[sid];
|
||||||
|
}
|
||||||
|
// Cookie löschen
|
||||||
|
res.clearCookie("SESSIONID", {
|
||||||
|
httpOnly: true,
|
||||||
|
secure: true,
|
||||||
|
domain: ".server.schooltech.ch",
|
||||||
|
sameSite: "None",
|
||||||
|
path: "/"
|
||||||
|
});
|
||||||
|
return res.status(200).send({ ok: true });
|
||||||
|
});
|
||||||
|
|
||||||
|
// Event logging endpoint for frontend button presses
|
||||||
|
app.post('/api/event', (req,res)=>{
|
||||||
|
const svc = req.body.service || req.body.action || 'unknown';
|
||||||
|
const user = req.cookies.SESSIONID || 'anonymous';
|
||||||
|
|
||||||
|
console.log(`Event: user=${user} service=${svc} payload=${JSON.stringify(req.body)}`);
|
||||||
|
res.status(200).send({ ok:true });
|
||||||
|
});
|
||||||
|
|
||||||
|
// Optional für Nginx auth_request
|
||||||
|
app.get("/internal/auth", (req,res)=>{
|
||||||
|
const sid = req.cookies.SESSIONID;
|
||||||
|
if (sid && SESSIONS[sid]) {
|
||||||
|
return res.sendStatus(200);
|
||||||
|
}
|
||||||
|
return res.sendStatus(401);
|
||||||
|
});
|
||||||
|
|
||||||
|
// Status endpoint (unter /api so dass Nginx /api/ auf appserverauth proxyt)
|
||||||
|
app.get("/api/status", (req, res) => {
|
||||||
|
const sid = req.cookies.SESSIONID;
|
||||||
|
if (sid && SESSIONS[sid]) {
|
||||||
|
return res.status(200).send({ ok: true, user: SESSIONS[sid].user });
|
||||||
|
}
|
||||||
|
return res.status(401).send({ ok: false });
|
||||||
|
});
|
||||||
|
|
||||||
|
app.listen(3000, ()=>console.log("Auth-Service läuft auf 3000"));
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
==============
|
||||||
|
==============
|
||||||
|
|
||||||
|
Das läuft alles. Das ist leicht erweiterbar. Und soll eigentlich nicht geändert werden.
|
||||||
|
Aber ich brauche Authentifikation. User sollen sich einmal einloggen, wenn sei auf
|
||||||
|
die portalUI Index.html kommen. Das ist ja unter server.schooltech.ch erreichbar.
|
||||||
|
|
||||||
|
Danach soll für alle weiteren xyzABC.server.schooltech.ch Pages die Identifikation
|
||||||
|
akzeptiert werden.
|
||||||
|
|
||||||
|
Soweit ich das sehe, kann ich eine cookie basierte Identifikation auf server.schooltech.ch
|
||||||
|
laufen lassen, und dann später genau diese cookies in den einzelnen Pages überprüfen.
|
||||||
|
|
||||||
|
Fragen:
|
||||||
|
|
||||||
|
1) ist der aufbau für dich einigermassen klar? Stell Fragen falls etwas unklar ist
|
||||||
|
|
||||||
|
2) Wie kann ich die Page server.schooltech.ch Passwort-Schützen? Was muss ich einstellen,
|
||||||
|
dass per default nur die "Login" Option kommt, und sonst keine Links angezeigt werden?
|
||||||
|
|
||||||
|
|
||||||
0
dokumentation/2026_03_21___q2_WS.txt
Executable file
0
dokumentation/2026_03_21___q2_WS.txt
Executable file
40
forwarding.conf
Normal file
40
forwarding.conf
Normal file
@@ -0,0 +1,40 @@
|
|||||||
|
# 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
|
||||||
|
|
||||||
|
# ThinkCentre ist ein MiniPC der neben dem einen Roboter steht. Hier sind die 97xx Ports zugewiesen
|
||||||
|
tcGuac.server.schooltech.ch http://appServer_TunnelHead:9780 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
|
||||||
|
#tcVideocontroller.server.schooltech.ch https://tcvideo:9443 redirect true false
|
||||||
|
robotHoming.server.schooltech.ch https://appServer_TunnelHead:9793 redirect false false
|
||||||
|
tcControl.server.schooltech.ch https://appServer_TunnelHead:9710 redirect true false
|
||||||
|
|
||||||
|
|
||||||
|
# Beispiel mit abweichendem Zertifikats-Ordner (Lineage-Suffix)
|
||||||
|
# tcGuac.server.schooltech.ch https://guac:8443 redirect true false server.schooltech.ch-0002
|
||||||
|
|
||||||
|
# Beispiel für WS auf port+1 (zwei Einträge, einer nur für WS-Endpunkt)
|
||||||
|
# wsApp.server.schooltech.ch https://wsapp:443 redirect true false
|
||||||
@@ -1 +1,39 @@
|
|||||||
docker exec -it appServer_LetsEncryptFetcher certbot renew --dry-run
|
for d in server.schooltech.ch \
|
||||||
|
tcControl.server.schooltech.ch \
|
||||||
|
tcGuac.server.schooltech.ch \
|
||||||
|
tcPortainer.server.schooltech.ch \
|
||||||
|
tcSimulation.server.schooltech.ch \
|
||||||
|
tcVideocontroller.server.schooltech.ch \
|
||||||
|
infGuac.server.schooltech.ch \
|
||||||
|
infPortainer.server.schooltech.ch \
|
||||||
|
infSimulation.server.schooltech.ch \
|
||||||
|
rp5Portainer.server.schooltech.ch \
|
||||||
|
rp5Guac.server.schooltech.ch \
|
||||||
|
rp5Simulation.server.schooltech.ch \
|
||||||
|
rp5Control.server.schooltech.ch \
|
||||||
|
rp3Portainer.server.schooltech.ch \
|
||||||
|
rp3Guac.server.schooltech.ch \
|
||||||
|
fluidncWhite.server.schooltech.ch \
|
||||||
|
scaraGreen.server.schooltech.ch \
|
||||||
|
scaraRed.server.schooltech.ch \
|
||||||
|
scaraGray.server.schooltech.ch \
|
||||||
|
scaraSilver.server.schooltech.ch \
|
||||||
|
scaraBlack.server.schooltech.ch \
|
||||||
|
scaraBlue.server.schooltech.ch \
|
||||||
|
scaraWhite.server.schooltech.ch \
|
||||||
|
scaraPortainer.server.schooltech.ch \
|
||||||
|
scaraSimu.server.schooltech.ch \
|
||||||
|
fluidncRed.server.schooltech.ch \
|
||||||
|
robotHoming.server.schooltech.ch \
|
||||||
|
robotControl.server.schooltech.ch \
|
||||||
|
robotVideo.server.schooltech.ch
|
||||||
|
|
||||||
|
do
|
||||||
|
docker exec -it appServer_LetsEncryptFetcher certbot certonly \
|
||||||
|
--webroot -w /var/www/certbot \
|
||||||
|
--cert-name "$d" \
|
||||||
|
-d "$d" \
|
||||||
|
--email admin@server.schooltech.ch \
|
||||||
|
--agree-tos --no-eff-email \
|
||||||
|
--keep-until-expiring
|
||||||
|
done
|
||||||
|
|||||||
0
letsEncrypt_crontab.txt
Executable file → Normal file
0
letsEncrypt_crontab.txt
Executable file → Normal file
@@ -1,12 +0,0 @@
|
|||||||
docker exec -it appServer_LetsEncryptFetcher certbot certonly \
|
|
||||||
--webroot \
|
|
||||||
-w /var/www/certbot \
|
|
||||||
-d server.schooltech.ch \
|
|
||||||
-d abc.server.schooltech.ch \
|
|
||||||
-d xyz.server.schooltech.ch \
|
|
||||||
-d portainer.server.schooltech.ch \
|
|
||||||
-d simulation3a29.server.schooltech.ch \
|
|
||||||
-d controller.server.schooltech.ch \
|
|
||||||
--email admin@server.schooltech.ch \
|
|
||||||
--agree-tos \
|
|
||||||
--no-eff-email
|
|
||||||
@@ -16,6 +16,6 @@ server.schooltech.ch = /var/www/certbot
|
|||||||
xyz.server.schooltech.ch = /var/www/certbot
|
xyz.server.schooltech.ch = /var/www/certbot
|
||||||
controller.server.schooltech.ch = /var/www/certbot
|
controller.server.schooltech.ch = /var/www/certbot
|
||||||
portainer.server.schooltech.ch = /var/www/certbot
|
portainer.server.schooltech.ch = /var/www/certbot
|
||||||
simulation3a29.server.schooltech.ch = /var/www/certbot
|
simulation.server.schooltech.ch = /var/www/certbot
|
||||||
[acme_renewal_info]
|
[acme_renewal_info]
|
||||||
ari_retry_after = 2026-02-14T07:10:40
|
ari_retry_after = 2026-02-19T08:25:19
|
||||||
|
|||||||
423
nginx.conf
423
nginx.conf
@@ -1,432 +1,29 @@
|
|||||||
error_log /var/log/nginx/error.log info;
|
# /etc/nginx/conf.d/default.conf
|
||||||
|
|
||||||
resolver 127.0.0.11 valid=30s;
|
|
||||||
resolver_timeout 5s;
|
|
||||||
|
|
||||||
map $http_upgrade $connection_upgrade {
|
|
||||||
default upgrade;
|
|
||||||
'' close;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
# ------------------------------------------------------------
|
|
||||||
# Default HTTP -> HTTPS redirect
|
|
||||||
# ------------------------------------------------------------
|
|
||||||
server {
|
server {
|
||||||
listen 80 default_server;
|
listen 80 default_server;
|
||||||
server_name _;
|
listen [::]:80 default_server;
|
||||||
|
|
||||||
location /.well-known/acme-challenge/ {
|
# ACME HTTP-01 Challenge (Certbot)
|
||||||
|
location ^~ /.well-known/acme-challenge/ {
|
||||||
root /var/www/certbot;
|
root /var/www/certbot;
|
||||||
|
default_type "text/plain; charset=utf-8";
|
||||||
}
|
}
|
||||||
|
|
||||||
location / {
|
# PortalUI root
|
||||||
return 301 https://$host$request_uri;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
# ------------------------------------------------------------
|
|
||||||
# #***# DEFAULT 443 SERVER (NEU)
|
|
||||||
# Verhindert, dass der erste 443-vHost andere Subdomains "abfängt"
|
|
||||||
# ------------------------------------------------------------
|
|
||||||
server {
|
|
||||||
listen 443 ssl http2 default_server;
|
|
||||||
server_name _;
|
|
||||||
|
|
||||||
ssl_certificate /etc/letsencrypt/live/server.schooltech.ch/fullchain.pem;
|
|
||||||
ssl_certificate_key /etc/letsencrypt/live/server.schooltech.ch/privkey.pem;
|
|
||||||
ssl_protocols TLSv1.2 TLSv1.3;
|
|
||||||
ssl_prefer_server_ciphers on;
|
|
||||||
|
|
||||||
# Einfach Verbindung schließen für unbekannte Hosts
|
|
||||||
return 444;
|
|
||||||
}
|
|
||||||
|
|
||||||
# ------------------------------------------------------------
|
|
||||||
# UI (portal) - nur für server.schooltech.ch
|
|
||||||
# ------------------------------------------------------------
|
|
||||||
server {
|
|
||||||
listen 443 ssl http2;
|
|
||||||
server_name server.schooltech.ch;
|
|
||||||
|
|
||||||
ssl_certificate /etc/letsencrypt/live/server.schooltech.ch/fullchain.pem;
|
|
||||||
ssl_certificate_key /etc/letsencrypt/live/server.schooltech.ch/privkey.pem;
|
|
||||||
ssl_protocols TLSv1.2 TLSv1.3;
|
|
||||||
ssl_prefer_server_ciphers on;
|
|
||||||
|
|
||||||
|
|
||||||
root /usr/share/nginx/html;
|
root /usr/share/nginx/html;
|
||||||
index index.html;
|
index index.html;
|
||||||
|
|
||||||
location / {
|
# === API forwarding for Auth-Service ===
|
||||||
try_files $uri $uri/ /index.html;
|
|
||||||
}
|
|
||||||
|
|
||||||
# API forwarding to auth (wie vorher) - nur für server.schooltech.ch
|
|
||||||
location /api/ {
|
location /api/ {
|
||||||
proxy_pass http://appServer_Auth: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;
|
||||||
proxy_set_header X-Forwarded-Proto $scheme;
|
proxy_set_header X-Forwarded-Proto $scheme;
|
||||||
|
|
||||||
proxy_buffering off;
|
|
||||||
proxy_request_buffering off;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
# ------------------------------------------------------------
|
# === SPA routing (Portal UI) ===
|
||||||
# Internal auth endpoint for auth_request (used by other server blocks)
|
|
||||||
# Einheitlicher nginxauth-Block: Host + URI an Auth-Service
|
|
||||||
# ------------------------------------------------------------
|
|
||||||
location = /nginxauth {
|
|
||||||
internal;
|
|
||||||
proxy_pass http://appServer_Auth:3000/internal/auth; #***# AUTH: proxy_pass (wichtig)
|
|
||||||
proxy_set_header Cookie $http_cookie; #***# AUTH: Cookie weitergeben
|
|
||||||
|
|
||||||
#***# AUTH HEADER ERWEITERUNG
|
|
||||||
proxy_set_header X-Original-URI $request_uri;
|
|
||||||
proxy_set_header X-Original-Host $host;
|
|
||||||
proxy_set_header X-Forwarded-Host $host;
|
|
||||||
}
|
|
||||||
|
|
||||||
# Security
|
|
||||||
add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" always;
|
|
||||||
|
|
||||||
# SSL
|
|
||||||
tcp_nopush on;
|
|
||||||
tcp_nodelay on;
|
|
||||||
}
|
|
||||||
|
|
||||||
# ------------------------------------------------------------
|
|
||||||
# abc.server.schooltech.ch - Controller on ThinkCentre
|
|
||||||
# ------------------------------------------------------------
|
|
||||||
server {
|
|
||||||
listen 443 ssl http2;
|
|
||||||
server_name abc.server.schooltech.ch;
|
|
||||||
|
|
||||||
ssl_certificate /etc/letsencrypt/live/server.schooltech.ch/fullchain.pem;
|
|
||||||
ssl_certificate_key /etc/letsencrypt/live/server.schooltech.ch/privkey.pem;
|
|
||||||
ssl_protocols TLSv1.2 TLSv1.3;
|
|
||||||
ssl_prefer_server_ciphers on;
|
|
||||||
|
|
||||||
set $serverBackendControl "appRobot_Control:10010";
|
|
||||||
set $auth_backend "appServer_Auth:3000";
|
|
||||||
|
|
||||||
|
|
||||||
location @fallback {
|
|
||||||
default_type text/html;
|
|
||||||
return 200 '
|
|
||||||
<html>
|
|
||||||
<head>
|
|
||||||
<title>Dienst offline</title>
|
|
||||||
</head>
|
|
||||||
<body style="font-family:sans-serif;text-align:center;padding-top:10%">
|
|
||||||
<h1>Ein Dienst ist momentan nicht erreichbar</h1>
|
|
||||||
<p>Bitte Seite neu laden - Verbindung wird automatisch erneut versucht.</p>
|
|
||||||
</body>
|
|
||||||
</html>';
|
|
||||||
}
|
|
||||||
|
|
||||||
# ---- Static assets: keine Auth, damit Browser die .js/.css korrekt erhält ----
|
|
||||||
location ~* \.(?:js|css|png|jpg|jpeg|gif|ico|svg|webp)$ {
|
|
||||||
proxy_pass https://$serverBackendControl;
|
|
||||||
proxy_set_header Host thinkcentre.local;
|
|
||||||
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 https;
|
|
||||||
# kein proxy_set_header Connection / Upgrade hier
|
|
||||||
}
|
|
||||||
|
|
||||||
# ---- WebSocket-Endpoint (falls z.B. /echo) - auth prüfen ----
|
|
||||||
location /echo {
|
|
||||||
auth_request /nginxauth;
|
|
||||||
proxy_pass https://$serverBackendControl/echo;
|
|
||||||
|
|
||||||
proxy_http_version 1.1;
|
|
||||||
proxy_set_header Upgrade $http_upgrade;
|
|
||||||
proxy_set_header Connection $connection_upgrade;
|
|
||||||
|
|
||||||
proxy_ssl_server_name on;
|
|
||||||
proxy_ssl_name thinkcentre.local;
|
|
||||||
proxy_ssl_verify off;
|
|
||||||
|
|
||||||
proxy_set_header Host thinkcentre.local;
|
|
||||||
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 https;
|
|
||||||
}
|
|
||||||
|
|
||||||
# ---- Hauptanwendung (HTML, API-Aufrufe) - auth prüfen ----
|
|
||||||
location / {
|
location / {
|
||||||
auth_request /nginxauth;
|
try_files $uri $uri/ /index.html;
|
||||||
|
|
||||||
proxy_pass https://$serverBackendControl/;
|
|
||||||
|
|
||||||
proxy_http_version 1.1;
|
|
||||||
proxy_set_header Upgrade $http_upgrade;
|
|
||||||
proxy_set_header Connection $connection_upgrade;
|
|
||||||
|
|
||||||
proxy_ssl_server_name on;
|
|
||||||
proxy_ssl_name thinkcentre.local;
|
|
||||||
proxy_ssl_verify off;
|
|
||||||
|
|
||||||
proxy_set_header Host thinkcentre.local;
|
|
||||||
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 https;
|
|
||||||
proxy_set_header Origin $http_origin;
|
|
||||||
|
|
||||||
proxy_hide_header X-Frame-Options;
|
|
||||||
add_header X-Frame-Options "ALLOWALL" always;
|
|
||||||
|
|
||||||
proxy_hide_header Content-Security-Policy;
|
|
||||||
add_header Content-Security-Policy "frame-ancestors https://server.schooltech.ch" always;
|
|
||||||
}
|
|
||||||
|
|
||||||
# /nginxauth (lokal für diesen vhost, aber internal request wird an auth-service weitergeleitet)
|
|
||||||
location = /nginxauth {
|
|
||||||
internal;
|
|
||||||
proxy_pass http://$auth_backend/internal/auth; #***# AUTH
|
|
||||||
proxy_set_header Cookie $http_cookie; #***# AUTH
|
|
||||||
|
|
||||||
#***# AUTH HEADER ERWEITERUNG
|
|
||||||
proxy_set_header X-Original-URI $request_uri;
|
|
||||||
proxy_set_header X-Original-Host $host;
|
|
||||||
proxy_set_header X-Forwarded-Host $host;
|
|
||||||
}
|
|
||||||
|
|
||||||
proxy_intercept_errors on;
|
|
||||||
error_page 502 503 504 = @fallback;
|
|
||||||
}
|
|
||||||
|
|
||||||
# ------------------------------------------------------------
|
|
||||||
# simulation3a29.server.schooltech.ch
|
|
||||||
# ------------------------------------------------------------
|
|
||||||
server {
|
|
||||||
listen 443 ssl http2;
|
|
||||||
server_name simulation3a29.server.schooltech.ch;
|
|
||||||
|
|
||||||
ssl_certificate /etc/letsencrypt/live/server.schooltech.ch/fullchain.pem;
|
|
||||||
ssl_certificate_key /etc/letsencrypt/live/server.schooltech.ch/privkey.pem;
|
|
||||||
ssl_protocols TLSv1.2 TLSv1.3;
|
|
||||||
ssl_prefer_server_ciphers on;
|
|
||||||
|
|
||||||
set $serverBackendSimulation "appRobot_Simulation:1003";
|
|
||||||
set $auth_backend "appServer_Auth:3000";
|
|
||||||
|
|
||||||
location @fallback {
|
|
||||||
default_type text/html;
|
|
||||||
return 200 '
|
|
||||||
<html>
|
|
||||||
<head>
|
|
||||||
<title>Dienst (Simulation) offline</title>
|
|
||||||
</head>
|
|
||||||
<body style="font-family:sans-serif;text-align:center;padding-top:10%">
|
|
||||||
<h1>Ein Dienst ist momentan nicht erreichbar</h1>
|
|
||||||
<p>Bitte Seite neu laden - Verbindung wird automatisch erneut versucht.</p>
|
|
||||||
</body>
|
|
||||||
</html>';
|
|
||||||
}
|
|
||||||
|
|
||||||
# ---- Static assets: keine Auth ----
|
|
||||||
location ~* \.(?:js|css|png|jpg|jpeg|gif|ico|svg|webp|stl)$ {
|
|
||||||
proxy_pass https://$serverBackendSimulation;
|
|
||||||
|
|
||||||
proxy_ssl_server_name on;
|
|
||||||
proxy_ssl_name thinkcentre.local;
|
|
||||||
proxy_ssl_verify off;
|
|
||||||
|
|
||||||
proxy_set_header Host thinkcentre.local;
|
|
||||||
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 https;
|
|
||||||
# kein proxy_set_header Connection / Upgrade hier
|
|
||||||
proxy_intercept_errors on;
|
|
||||||
error_page 502 503 504 = @fallback;
|
|
||||||
}
|
|
||||||
|
|
||||||
# ---- WebSocket-Endpoint ----
|
|
||||||
location /echo {
|
|
||||||
auth_request /nginxauth;
|
|
||||||
proxy_pass https://$serverBackendSimulation/echo;
|
|
||||||
|
|
||||||
proxy_ssl_server_name on;
|
|
||||||
proxy_ssl_name thinkcentre.local;
|
|
||||||
proxy_ssl_verify off;
|
|
||||||
|
|
||||||
proxy_http_version 1.1;
|
|
||||||
proxy_set_header Upgrade $http_upgrade;
|
|
||||||
proxy_set_header Connection $connection_upgrade;
|
|
||||||
|
|
||||||
proxy_set_header Host thinkcentre.local;
|
|
||||||
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 https;
|
|
||||||
|
|
||||||
proxy_intercept_errors on;
|
|
||||||
error_page 502 503 504 = @fallback;
|
|
||||||
}
|
|
||||||
|
|
||||||
# ---- Hauptanwendung ----
|
|
||||||
location / {
|
|
||||||
auth_request /nginxauth;
|
|
||||||
|
|
||||||
proxy_pass https://$serverBackendSimulation/;
|
|
||||||
|
|
||||||
proxy_ssl_server_name on;
|
|
||||||
proxy_ssl_name thinkcentre.local;
|
|
||||||
proxy_ssl_verify off;
|
|
||||||
|
|
||||||
proxy_http_version 1.1;
|
|
||||||
proxy_set_header Upgrade $http_upgrade;
|
|
||||||
proxy_set_header Connection $connection_upgrade;
|
|
||||||
|
|
||||||
proxy_set_header Host thinkcentre.local;
|
|
||||||
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 https;
|
|
||||||
proxy_set_header Origin $http_origin;
|
|
||||||
|
|
||||||
proxy_hide_header X-Frame-Options;
|
|
||||||
add_header X-Frame-Options "ALLOWALL" always;
|
|
||||||
|
|
||||||
proxy_hide_header Content-Security-Policy;
|
|
||||||
add_header Content-Security-Policy "frame-ancestors https://server.schooltech.ch" always;
|
|
||||||
|
|
||||||
proxy_intercept_errors on;
|
|
||||||
error_page 502 503 504 = @fallback;
|
|
||||||
}
|
|
||||||
|
|
||||||
# ------------------------------------------------------------
|
|
||||||
# location = /nginxauth (SIMULATION FIX)
|
|
||||||
# ------------------------------------------------------------
|
|
||||||
location = /nginxauth {
|
|
||||||
internal;
|
|
||||||
proxy_pass http://$auth_backend/internal/auth; #***# AUTH
|
|
||||||
proxy_set_header Cookie $http_cookie; #***# AUTH
|
|
||||||
|
|
||||||
#***# AUTH HEADER ERWEITERUNG
|
|
||||||
proxy_set_header X-Original-URI $request_uri;
|
|
||||||
proxy_set_header X-Original-Host $host;
|
|
||||||
proxy_set_header X-Forwarded-Host $host;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
# ------------------------------------------------------------
|
|
||||||
# xyz.server.schooltech.ch (Guacamole )
|
|
||||||
# ------------------------------------------------------------
|
|
||||||
server {
|
|
||||||
listen 443 ssl http2;
|
|
||||||
server_name xyz.server.schooltech.ch;
|
|
||||||
|
|
||||||
ssl_certificate /etc/letsencrypt/live/server.schooltech.ch/fullchain.pem;
|
|
||||||
ssl_certificate_key /etc/letsencrypt/live/server.schooltech.ch/privkey.pem;
|
|
||||||
ssl_protocols TLSv1.2 TLSv1.3;
|
|
||||||
ssl_prefer_server_ciphers on;
|
|
||||||
|
|
||||||
set $serverBackendGuacamole "appServer_guacamole:8080";
|
|
||||||
|
|
||||||
location @fallback {
|
|
||||||
default_type text/html;
|
|
||||||
return 200 '
|
|
||||||
<html>
|
|
||||||
<head>
|
|
||||||
<title>Dienst (Guacamole) offline</title>
|
|
||||||
</head>
|
|
||||||
<body style="font-family:sans-serif;text-align:center;padding-top:10%">
|
|
||||||
<h1>Ein Dienst ist momentan nicht erreichbar</h1>
|
|
||||||
<p>Bitte Seite neu laden - Verbindung wird automatisch erneut versucht.</p>
|
|
||||||
</body>
|
|
||||||
</html>';
|
|
||||||
}
|
|
||||||
|
|
||||||
location / {
|
|
||||||
proxy_pass http://$serverBackendGuacamole;
|
|
||||||
|
|
||||||
proxy_http_version 1.1;
|
|
||||||
proxy_set_header Upgrade $http_upgrade;
|
|
||||||
proxy_set_header Connection $connection_upgrade;
|
|
||||||
|
|
||||||
proxy_buffering off;
|
|
||||||
proxy_request_buffering off;
|
|
||||||
|
|
||||||
proxy_set_header Host $host;
|
|
||||||
proxy_set_header X-Forwarded-Proto https;
|
|
||||||
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
|
||||||
proxy_set_header X-Real-IP $remote_addr;
|
|
||||||
|
|
||||||
add_header Content-Security-Policy "frame-ancestors https://server.schooltech.ch" always;
|
|
||||||
|
|
||||||
proxy_intercept_errors on;
|
|
||||||
error_page 502 503 504 = @fallback;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
## ------------------------------------------------------------
|
|
||||||
# portainer.server.schooltech.ch
|
|
||||||
# ------------------------------------------------------------
|
|
||||||
server {
|
|
||||||
listen 443 ssl http2;
|
|
||||||
server_name portainer.server.schooltech.ch;
|
|
||||||
|
|
||||||
ssl_certificate /etc/letsencrypt/live/server.schooltech.ch/fullchain.pem;
|
|
||||||
ssl_certificate_key /etc/letsencrypt/live/server.schooltech.ch/privkey.pem;
|
|
||||||
|
|
||||||
set $auth_backend "appServer_Auth:3000";
|
|
||||||
|
|
||||||
location @fallback {
|
|
||||||
default_type text/html;
|
|
||||||
return 200 '
|
|
||||||
<html>
|
|
||||||
<head>
|
|
||||||
<title>Dienst (Portainer) offline</title>
|
|
||||||
</head>
|
|
||||||
<body style="font-family:sans-serif;text-align:center;padding-top:10%">
|
|
||||||
<h1>Ein Dienst ist momentan nicht erreichbar</h1>
|
|
||||||
<p>Bitte Seite neu laden - Verbindung wird automatisch erneut versucht.</p>
|
|
||||||
</body>
|
|
||||||
</html>';
|
|
||||||
}
|
|
||||||
|
|
||||||
location / {
|
|
||||||
|
|
||||||
proxy_pass http://portainer:9000;
|
|
||||||
proxy_http_version 1.1;
|
|
||||||
|
|
||||||
proxy_set_header Upgrade $http_upgrade;
|
|
||||||
#proxy_set_header Connection "upgrade";
|
|
||||||
proxy_set_header Connection $http_connection_upgrade;
|
|
||||||
|
|
||||||
proxy_set_header Host $host;
|
|
||||||
proxy_set_header X-Forwarded-Proto https;
|
|
||||||
proxy_set_header X-Real-IP $remote_addr;
|
|
||||||
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
|
||||||
|
|
||||||
# WICHTIG FÜR IFRAME
|
|
||||||
proxy_hide_header X-Frame-Options;
|
|
||||||
proxy_hide_header Content-Security-Policy;
|
|
||||||
|
|
||||||
add_header X-Frame-Options "SAMEORIGIN" always;
|
|
||||||
add_header Content-Security-Policy "frame-ancestors https://server.schooltech.ch" always;
|
|
||||||
|
|
||||||
proxy_intercept_errors on;
|
|
||||||
error_page 502 503 504 = @fallback; # <-- Fallback
|
|
||||||
}
|
|
||||||
|
|
||||||
location = /nginxauth {
|
|
||||||
internal;
|
|
||||||
proxy_pass http://$auth_backend/internal/auth;
|
|
||||||
proxy_set_header Cookie $http_cookie;
|
|
||||||
|
|
||||||
#***# AUTH HEADER ERWEITERUNG
|
|
||||||
proxy_set_header X-Original-URI $request_uri;
|
|
||||||
proxy_set_header X-Original-Host $host;
|
|
||||||
proxy_set_header X-Forwarded-Host $host;
|
|
||||||
|
|
||||||
proxy_intercept_errors on;
|
|
||||||
error_page 502 503 504 = @fallback; # <-- Fallback
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1,10 +1,16 @@
|
|||||||
error_log /var/log/nginx/error.log info;
|
error_log /var/log/nginx/error.log info;
|
||||||
|
|
||||||
|
resolver 127.0.0.11 valid=30s;
|
||||||
|
resolver_timeout 5s;
|
||||||
|
|
||||||
map $http_upgrade $connection_upgrade {
|
map $http_upgrade $connection_upgrade {
|
||||||
default upgrade;
|
default upgrade;
|
||||||
'' close;
|
'' close;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
# ------------------------------------------------------------
|
# ------------------------------------------------------------
|
||||||
# Default HTTP -> HTTPS redirect
|
# Default HTTP -> HTTPS redirect
|
||||||
# ------------------------------------------------------------
|
# ------------------------------------------------------------
|
||||||
@@ -32,6 +38,7 @@ server {
|
|||||||
ssl_certificate /etc/letsencrypt/live/server.schooltech.ch/fullchain.pem;
|
ssl_certificate /etc/letsencrypt/live/server.schooltech.ch/fullchain.pem;
|
||||||
ssl_certificate_key /etc/letsencrypt/live/server.schooltech.ch/privkey.pem;
|
ssl_certificate_key /etc/letsencrypt/live/server.schooltech.ch/privkey.pem;
|
||||||
ssl_protocols TLSv1.2 TLSv1.3;
|
ssl_protocols TLSv1.2 TLSv1.3;
|
||||||
|
ssl_prefer_server_ciphers on;
|
||||||
|
|
||||||
# Einfach Verbindung schließen für unbekannte Hosts
|
# Einfach Verbindung schließen für unbekannte Hosts
|
||||||
return 444;
|
return 444;
|
||||||
@@ -49,6 +56,7 @@ server {
|
|||||||
ssl_protocols TLSv1.2 TLSv1.3;
|
ssl_protocols TLSv1.2 TLSv1.3;
|
||||||
ssl_prefer_server_ciphers on;
|
ssl_prefer_server_ciphers on;
|
||||||
|
|
||||||
|
|
||||||
root /usr/share/nginx/html;
|
root /usr/share/nginx/html;
|
||||||
index index.html;
|
index index.html;
|
||||||
|
|
||||||
@@ -58,11 +66,14 @@ server {
|
|||||||
|
|
||||||
# API forwarding to auth (wie vorher) - nur für server.schooltech.ch
|
# API forwarding to auth (wie vorher) - nur für server.schooltech.ch
|
||||||
location /api/ {
|
location /api/ {
|
||||||
proxy_pass http://appserverauth:3000/api/;
|
proxy_pass http://appServer_Auth: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;
|
||||||
proxy_set_header X-Forwarded-Proto $scheme;
|
proxy_set_header X-Forwarded-Proto $scheme;
|
||||||
|
|
||||||
|
proxy_buffering off;
|
||||||
|
proxy_request_buffering off;
|
||||||
}
|
}
|
||||||
|
|
||||||
# ------------------------------------------------------------
|
# ------------------------------------------------------------
|
||||||
@@ -71,7 +82,7 @@ server {
|
|||||||
# ------------------------------------------------------------
|
# ------------------------------------------------------------
|
||||||
location = /nginxauth {
|
location = /nginxauth {
|
||||||
internal;
|
internal;
|
||||||
proxy_pass http://appserverauth:3000/internal/auth; #***# AUTH: proxy_pass (wichtig)
|
proxy_pass http://appServer_Auth:3000/internal/auth; #***# AUTH: proxy_pass (wichtig)
|
||||||
proxy_set_header Cookie $http_cookie; #***# AUTH: Cookie weitergeben
|
proxy_set_header Cookie $http_cookie; #***# AUTH: Cookie weitergeben
|
||||||
|
|
||||||
#***# AUTH HEADER ERWEITERUNG
|
#***# AUTH HEADER ERWEITERUNG
|
||||||
@@ -82,6 +93,10 @@ server {
|
|||||||
|
|
||||||
# Security
|
# Security
|
||||||
add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" always;
|
add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" always;
|
||||||
|
|
||||||
|
# SSL
|
||||||
|
tcp_nopush on;
|
||||||
|
tcp_nodelay on;
|
||||||
}
|
}
|
||||||
|
|
||||||
# ------------------------------------------------------------
|
# ------------------------------------------------------------
|
||||||
@@ -96,9 +111,27 @@ server {
|
|||||||
ssl_protocols TLSv1.2 TLSv1.3;
|
ssl_protocols TLSv1.2 TLSv1.3;
|
||||||
ssl_prefer_server_ciphers on;
|
ssl_prefer_server_ciphers on;
|
||||||
|
|
||||||
|
set $serverBackendControl "appRobot_Control:10010";
|
||||||
|
set $auth_backend "appServer_Auth:3000";
|
||||||
|
|
||||||
|
|
||||||
|
location @fallback {
|
||||||
|
default_type text/html;
|
||||||
|
return 200 '
|
||||||
|
<html>
|
||||||
|
<head>
|
||||||
|
<title>Dienst offline</title>
|
||||||
|
</head>
|
||||||
|
<body style="font-family:sans-serif;text-align:center;padding-top:10%">
|
||||||
|
<h1>Ein Dienst ist momentan nicht erreichbar</h1>
|
||||||
|
<p>Bitte Seite neu laden - Verbindung wird automatisch erneut versucht.</p>
|
||||||
|
</body>
|
||||||
|
</html>';
|
||||||
|
}
|
||||||
|
|
||||||
# ---- Static assets: keine Auth, damit Browser die .js/.css korrekt erhält ----
|
# ---- Static assets: keine Auth, damit Browser die .js/.css korrekt erhält ----
|
||||||
location ~* \.(?:js|css|png|jpg|jpeg|gif|ico|svg|webp)$ {
|
location ~* \.(?:js|css|png|jpg|jpeg|gif|ico|svg|webp)$ {
|
||||||
proxy_pass https://thinkcentre.local:10010;
|
proxy_pass https://$serverBackendControl;
|
||||||
proxy_set_header Host thinkcentre.local;
|
proxy_set_header Host thinkcentre.local;
|
||||||
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;
|
||||||
@@ -109,7 +142,7 @@ server {
|
|||||||
# ---- WebSocket-Endpoint (falls z.B. /echo) - auth prüfen ----
|
# ---- WebSocket-Endpoint (falls z.B. /echo) - auth prüfen ----
|
||||||
location /echo {
|
location /echo {
|
||||||
auth_request /nginxauth;
|
auth_request /nginxauth;
|
||||||
proxy_pass https://thinkcentre.local:10010/echo;
|
proxy_pass https://$serverBackendControl/echo;
|
||||||
|
|
||||||
proxy_http_version 1.1;
|
proxy_http_version 1.1;
|
||||||
proxy_set_header Upgrade $http_upgrade;
|
proxy_set_header Upgrade $http_upgrade;
|
||||||
@@ -129,7 +162,7 @@ server {
|
|||||||
location / {
|
location / {
|
||||||
auth_request /nginxauth;
|
auth_request /nginxauth;
|
||||||
|
|
||||||
proxy_pass https://thinkcentre.local:10010/;
|
proxy_pass https://$serverBackendControl/;
|
||||||
|
|
||||||
proxy_http_version 1.1;
|
proxy_http_version 1.1;
|
||||||
proxy_set_header Upgrade $http_upgrade;
|
proxy_set_header Upgrade $http_upgrade;
|
||||||
@@ -155,7 +188,7 @@ server {
|
|||||||
# /nginxauth (lokal für diesen vhost, aber internal request wird an auth-service weitergeleitet)
|
# /nginxauth (lokal für diesen vhost, aber internal request wird an auth-service weitergeleitet)
|
||||||
location = /nginxauth {
|
location = /nginxauth {
|
||||||
internal;
|
internal;
|
||||||
proxy_pass http://appserverauth:3000/internal/auth; #***# AUTH
|
proxy_pass http://$auth_backend/internal/auth; #***# AUTH
|
||||||
proxy_set_header Cookie $http_cookie; #***# AUTH
|
proxy_set_header Cookie $http_cookie; #***# AUTH
|
||||||
|
|
||||||
#***# AUTH HEADER ERWEITERUNG
|
#***# AUTH HEADER ERWEITERUNG
|
||||||
@@ -163,6 +196,9 @@ server {
|
|||||||
proxy_set_header X-Original-Host $host;
|
proxy_set_header X-Original-Host $host;
|
||||||
proxy_set_header X-Forwarded-Host $host;
|
proxy_set_header X-Forwarded-Host $host;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
proxy_intercept_errors on;
|
||||||
|
error_page 502 503 504 = @fallback;
|
||||||
}
|
}
|
||||||
|
|
||||||
# ------------------------------------------------------------
|
# ------------------------------------------------------------
|
||||||
@@ -177,24 +213,26 @@ server {
|
|||||||
ssl_protocols TLSv1.2 TLSv1.3;
|
ssl_protocols TLSv1.2 TLSv1.3;
|
||||||
ssl_prefer_server_ciphers on;
|
ssl_prefer_server_ciphers on;
|
||||||
|
|
||||||
# ---- Static assets: keine Auth ----
|
set $serverBackendSimulation "appRobot_Simulation:1003";
|
||||||
location ~* \.(?:js|css|png|jpg|jpeg|gif|ico|svg|webp)$ {
|
set $auth_backend "appServer_Auth:3000";
|
||||||
proxy_pass https://thinkcentre.local:1003;
|
|
||||||
proxy_set_header Host thinkcentre.local;
|
location @fallback {
|
||||||
proxy_set_header X-Real-IP $remote_addr;
|
default_type text/html;
|
||||||
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
return 200 '
|
||||||
proxy_set_header X-Forwarded-Proto https;
|
<html>
|
||||||
# kein proxy_set_header Connection / Upgrade hier
|
<head>
|
||||||
|
<title>Dienst (Simulation) offline</title>
|
||||||
|
</head>
|
||||||
|
<body style="font-family:sans-serif;text-align:center;padding-top:10%">
|
||||||
|
<h1>Ein Dienst ist momentan nicht erreichbar</h1>
|
||||||
|
<p>Bitte Seite neu laden - Verbindung wird automatisch erneut versucht.</p>
|
||||||
|
</body>
|
||||||
|
</html>';
|
||||||
}
|
}
|
||||||
|
|
||||||
# ---- WebSocket-Endpoint ----
|
# ---- Static assets: keine Auth ----
|
||||||
location /echo {
|
location ~* \.(?:js|css|png|jpg|jpeg|gif|ico|svg|webp|stl)$ {
|
||||||
auth_request /nginxauth;
|
proxy_pass https://$serverBackendSimulation;
|
||||||
proxy_pass https://thinkcentre.local:1003/echo;
|
|
||||||
|
|
||||||
proxy_http_version 1.1;
|
|
||||||
proxy_set_header Upgrade $http_upgrade;
|
|
||||||
proxy_set_header Connection $connection_upgrade;
|
|
||||||
|
|
||||||
proxy_ssl_server_name on;
|
proxy_ssl_server_name on;
|
||||||
proxy_ssl_name thinkcentre.local;
|
proxy_ssl_name thinkcentre.local;
|
||||||
@@ -204,22 +242,47 @@ server {
|
|||||||
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;
|
||||||
proxy_set_header X-Forwarded-Proto https;
|
proxy_set_header X-Forwarded-Proto https;
|
||||||
|
# kein proxy_set_header Connection / Upgrade hier
|
||||||
|
proxy_intercept_errors on;
|
||||||
|
error_page 502 503 504 = @fallback;
|
||||||
|
}
|
||||||
|
|
||||||
|
# ---- WebSocket-Endpoint ----
|
||||||
|
location /echo {
|
||||||
|
auth_request /nginxauth;
|
||||||
|
proxy_pass https://$serverBackendSimulation/echo;
|
||||||
|
|
||||||
|
proxy_ssl_server_name on;
|
||||||
|
proxy_ssl_name thinkcentre.local;
|
||||||
|
proxy_ssl_verify off;
|
||||||
|
|
||||||
|
proxy_http_version 1.1;
|
||||||
|
proxy_set_header Upgrade $http_upgrade;
|
||||||
|
proxy_set_header Connection $connection_upgrade;
|
||||||
|
|
||||||
|
proxy_set_header Host thinkcentre.local;
|
||||||
|
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 https;
|
||||||
|
|
||||||
|
proxy_intercept_errors on;
|
||||||
|
error_page 502 503 504 = @fallback;
|
||||||
}
|
}
|
||||||
|
|
||||||
# ---- Hauptanwendung ----
|
# ---- Hauptanwendung ----
|
||||||
location / {
|
location / {
|
||||||
auth_request /nginxauth;
|
auth_request /nginxauth;
|
||||||
|
|
||||||
proxy_pass https://thinkcentre.local:1003/;
|
proxy_pass https://$serverBackendSimulation/;
|
||||||
|
|
||||||
proxy_http_version 1.1;
|
|
||||||
proxy_set_header Upgrade $http_upgrade;
|
|
||||||
proxy_set_header Connection $connection_upgrade;
|
|
||||||
|
|
||||||
proxy_ssl_server_name on;
|
proxy_ssl_server_name on;
|
||||||
proxy_ssl_name thinkcentre.local;
|
proxy_ssl_name thinkcentre.local;
|
||||||
proxy_ssl_verify off;
|
proxy_ssl_verify off;
|
||||||
|
|
||||||
|
proxy_http_version 1.1;
|
||||||
|
proxy_set_header Upgrade $http_upgrade;
|
||||||
|
proxy_set_header Connection $connection_upgrade;
|
||||||
|
|
||||||
proxy_set_header Host thinkcentre.local;
|
proxy_set_header Host thinkcentre.local;
|
||||||
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;
|
||||||
@@ -231,6 +294,9 @@ server {
|
|||||||
|
|
||||||
proxy_hide_header Content-Security-Policy;
|
proxy_hide_header Content-Security-Policy;
|
||||||
add_header Content-Security-Policy "frame-ancestors https://server.schooltech.ch" always;
|
add_header Content-Security-Policy "frame-ancestors https://server.schooltech.ch" always;
|
||||||
|
|
||||||
|
proxy_intercept_errors on;
|
||||||
|
error_page 502 503 504 = @fallback;
|
||||||
}
|
}
|
||||||
|
|
||||||
# ------------------------------------------------------------
|
# ------------------------------------------------------------
|
||||||
@@ -238,10 +304,10 @@ server {
|
|||||||
# ------------------------------------------------------------
|
# ------------------------------------------------------------
|
||||||
location = /nginxauth {
|
location = /nginxauth {
|
||||||
internal;
|
internal;
|
||||||
proxy_pass http://appserverauth:3000/internal/auth; #***# SIMULATION: fehlende proxy_pass eingefügt
|
proxy_pass http://$auth_backend/internal/auth; #***# AUTH
|
||||||
proxy_set_header Cookie $http_cookie; #***# SIMULATION: Cookie weitergeben
|
proxy_set_header Cookie $http_cookie; #***# AUTH
|
||||||
|
|
||||||
#***# AUTH HEADER ERWEITERUNG (nur einmal)
|
#***# AUTH HEADER ERWEITERUNG
|
||||||
proxy_set_header X-Original-URI $request_uri;
|
proxy_set_header X-Original-URI $request_uri;
|
||||||
proxy_set_header X-Original-Host $host;
|
proxy_set_header X-Original-Host $host;
|
||||||
proxy_set_header X-Forwarded-Host $host;
|
proxy_set_header X-Forwarded-Host $host;
|
||||||
@@ -249,7 +315,7 @@ server {
|
|||||||
}
|
}
|
||||||
|
|
||||||
# ------------------------------------------------------------
|
# ------------------------------------------------------------
|
||||||
# xyz.server.schooltech.ch (Guacamole on ThinkCentre)
|
# xyz.server.schooltech.ch (Guacamole )
|
||||||
# ------------------------------------------------------------
|
# ------------------------------------------------------------
|
||||||
server {
|
server {
|
||||||
listen 443 ssl http2;
|
listen 443 ssl http2;
|
||||||
@@ -260,44 +326,46 @@ server {
|
|||||||
ssl_protocols TLSv1.2 TLSv1.3;
|
ssl_protocols TLSv1.2 TLSv1.3;
|
||||||
ssl_prefer_server_ciphers on;
|
ssl_prefer_server_ciphers on;
|
||||||
|
|
||||||
location / {
|
set $serverBackendGuacamole "appServer_guacamole:8080";
|
||||||
auth_request /nginxauth; # Auth prüfen
|
|
||||||
|
|
||||||
proxy_pass http://thinkcentre.local:8080/;
|
location @fallback {
|
||||||
|
default_type text/html;
|
||||||
|
return 200 '
|
||||||
|
<html>
|
||||||
|
<head>
|
||||||
|
<title>Dienst (Guacamole) offline</title>
|
||||||
|
</head>
|
||||||
|
<body style="font-family:sans-serif;text-align:center;padding-top:10%">
|
||||||
|
<h1>Ein Dienst ist momentan nicht erreichbar</h1>
|
||||||
|
<p>Bitte Seite neu laden - Verbindung wird automatisch erneut versucht.</p>
|
||||||
|
</body>
|
||||||
|
</html>';
|
||||||
|
}
|
||||||
|
|
||||||
|
location / {
|
||||||
|
proxy_pass http://$serverBackendGuacamole;
|
||||||
|
|
||||||
proxy_http_version 1.1;
|
proxy_http_version 1.1;
|
||||||
proxy_set_header Upgrade $http_upgrade;
|
proxy_set_header Upgrade $http_upgrade;
|
||||||
proxy_set_header Connection $connection_upgrade;
|
proxy_set_header Connection $connection_upgrade;
|
||||||
|
|
||||||
# Proxy Header (Upstream erwartet thinkcentre.local)
|
proxy_buffering off;
|
||||||
proxy_set_header Host thinkcentre.local; # bewusst: Upstream Host-Expectation
|
proxy_request_buffering off;
|
||||||
proxy_set_header Origin $http_origin;
|
|
||||||
proxy_set_header X-Real-IP $remote_addr;
|
proxy_set_header Host $host;
|
||||||
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
|
||||||
proxy_set_header X-Forwarded-Proto https;
|
proxy_set_header X-Forwarded-Proto https;
|
||||||
|
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
||||||
|
proxy_set_header X-Real-IP $remote_addr;
|
||||||
|
|
||||||
# iFrame erlauben
|
add_header Content-Security-Policy "frame-ancestors https://server.schooltech.ch" always;
|
||||||
proxy_hide_header X-Frame-Options;
|
|
||||||
add_header X-Frame-Options "ALLOWALL" always;
|
|
||||||
|
|
||||||
proxy_hide_header Content-Security-Policy;
|
proxy_intercept_errors on;
|
||||||
add_header Content-Security-Policy "frame-ancestors *" always;
|
error_page 502 503 504 = @fallback;
|
||||||
}
|
}
|
||||||
|
|
||||||
location = /nginxauth {
|
|
||||||
internal;
|
|
||||||
proxy_pass http://appserverauth:3000/internal/auth; #***# XYZ: proxy_pass wie überall
|
|
||||||
proxy_set_header Cookie $http_cookie;
|
|
||||||
|
|
||||||
proxy_set_header X-Original-URI $request_uri;
|
|
||||||
|
|
||||||
#***# XYZ AUTH HOST: Original-Host weitergeben (wichtig für Redirects/Checks)
|
|
||||||
proxy_set_header X-Original-Host $host;
|
|
||||||
proxy_set_header X-Forwarded-Host $host;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
# ------------------------------------------------------------
|
## ------------------------------------------------------------
|
||||||
# portainer.server.schooltech.ch
|
# portainer.server.schooltech.ch
|
||||||
# ------------------------------------------------------------
|
# ------------------------------------------------------------
|
||||||
server {
|
server {
|
||||||
@@ -306,17 +374,31 @@ server {
|
|||||||
|
|
||||||
ssl_certificate /etc/letsencrypt/live/server.schooltech.ch/fullchain.pem;
|
ssl_certificate /etc/letsencrypt/live/server.schooltech.ch/fullchain.pem;
|
||||||
ssl_certificate_key /etc/letsencrypt/live/server.schooltech.ch/privkey.pem;
|
ssl_certificate_key /etc/letsencrypt/live/server.schooltech.ch/privkey.pem;
|
||||||
ssl_protocols TLSv1.2 TLSv1.3;
|
|
||||||
ssl_prefer_server_ciphers on;
|
set $auth_backend "appServer_Auth:3000";
|
||||||
|
|
||||||
|
location @fallback {
|
||||||
|
default_type text/html;
|
||||||
|
return 200 '
|
||||||
|
<html>
|
||||||
|
<head>
|
||||||
|
<title>Dienst (Portainer) offline</title>
|
||||||
|
</head>
|
||||||
|
<body style="font-family:sans-serif;text-align:center;padding-top:10%">
|
||||||
|
<h1>Ein Dienst ist momentan nicht erreichbar</h1>
|
||||||
|
<p>Bitte Seite neu laden - Verbindung wird automatisch erneut versucht.</p>
|
||||||
|
</body>
|
||||||
|
</html>';
|
||||||
|
}
|
||||||
|
|
||||||
location / {
|
location / {
|
||||||
auth_request /nginxauth;
|
|
||||||
|
|
||||||
proxy_pass http://portainer:9000;
|
proxy_pass http://portainer:9000;
|
||||||
proxy_http_version 1.1;
|
proxy_http_version 1.1;
|
||||||
|
|
||||||
proxy_set_header Upgrade $http_upgrade;
|
proxy_set_header Upgrade $http_upgrade;
|
||||||
proxy_set_header Connection "upgrade";
|
#proxy_set_header Connection "upgrade";
|
||||||
|
proxy_set_header Connection $http_connection_upgrade;
|
||||||
|
|
||||||
proxy_set_header Host $host;
|
proxy_set_header Host $host;
|
||||||
proxy_set_header X-Forwarded-Proto https;
|
proxy_set_header X-Forwarded-Proto https;
|
||||||
@@ -329,17 +411,22 @@ server {
|
|||||||
|
|
||||||
add_header X-Frame-Options "SAMEORIGIN" always;
|
add_header X-Frame-Options "SAMEORIGIN" always;
|
||||||
add_header Content-Security-Policy "frame-ancestors https://server.schooltech.ch" always;
|
add_header Content-Security-Policy "frame-ancestors https://server.schooltech.ch" always;
|
||||||
}
|
|
||||||
|
|
||||||
|
proxy_intercept_errors on;
|
||||||
|
error_page 502 503 504 = @fallback; # <-- Fallback
|
||||||
|
}
|
||||||
|
|
||||||
location = /nginxauth {
|
location = /nginxauth {
|
||||||
internal;
|
internal;
|
||||||
proxy_pass http://appserverauth:3000/internal/auth; #***# AUTH
|
proxy_pass http://$auth_backend/internal/auth;
|
||||||
proxy_set_header Cookie $http_cookie; #***# AUTH
|
proxy_set_header Cookie $http_cookie;
|
||||||
|
|
||||||
#***# AUTH HEADER ERWEITERUNG
|
#***# AUTH HEADER ERWEITERUNG
|
||||||
proxy_set_header X-Original-URI $request_uri;
|
proxy_set_header X-Original-URI $request_uri;
|
||||||
proxy_set_header X-Original-Host $host;
|
proxy_set_header X-Original-Host $host;
|
||||||
proxy_set_header X-Forwarded-Host $host;
|
proxy_set_header X-Forwarded-Host $host;
|
||||||
|
|
||||||
|
proxy_intercept_errors on;
|
||||||
|
error_page 502 503 504 = @fallback; # <-- Fallback
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -10,6 +10,8 @@ server {
|
|||||||
root /usr/share/nginx/html;
|
root /usr/share/nginx/html;
|
||||||
index index.html;
|
index index.html;
|
||||||
|
|
||||||
|
auth_request /nginxauth;
|
||||||
|
|
||||||
# UI / SPA
|
# UI / SPA
|
||||||
location / {
|
location / {
|
||||||
try_files $uri $uri/ /index.html;
|
try_files $uri $uri/ /index.html;
|
||||||
|
|||||||
@@ -2,10 +2,10 @@
|
|||||||
|
|
||||||
// Service-Liste
|
// Service-Liste
|
||||||
const services = [
|
const services = [
|
||||||
{ id: "abc", name: "Control GamePad", url: "https://abc.server.schooltech.ch/" },
|
{ id: "abc", name: "Control GamePad", url: "https://tccontrol.server.schooltech.ch/" },
|
||||||
{ id: "xyz", name: "Guacamole", url: "https://xyz.server.schooltech.ch/" },
|
{ id: "xyz", name: "Guacamole", url: "https://rp5guac.server.schooltech.ch/" },
|
||||||
{ id: "sim", name: "Simulation", url: "https://simulation3a29.server.schooltech.ch/" },
|
{ id: "sim", name: "Simulation", url: "https://tcSimulation.server.schooltech.ch/" },
|
||||||
{ id: "portainer", name: "Portainer", url: "https://portainer.server.schooltech.ch/" }
|
{ id: "portainer", name: "Portainer", url: "https://rp5portainer.server.schooltech.ch/" }
|
||||||
];
|
];
|
||||||
|
|
||||||
// DOM-Elemente
|
// DOM-Elemente
|
||||||
|
|||||||
Reference in New Issue
Block a user