Stabiler machen
This commit is contained in:
23
README.md
23
README.md
@@ -34,8 +34,8 @@ Diensten ist nicht die Domain, sondern **wohin der Upstream zeigt**:
|
||||
|
||||

|
||||
|
||||
> Diagramm-Quelle: [`doc/Architektur.svg`](doc/Architektur.svg) (daraus lässt
|
||||
> sich bei Bedarf eine PDF/PNG erzeugen).
|
||||
> Diagramm-Quelle: [`doc/Architektur.svg`](doc/Architektur.svg) — auch als
|
||||
> [`doc/Architektur.png`](doc/Architektur.png) (für Viewer ohne SVG-Support).
|
||||
|
||||
**Bausteine (Docker-Container, siehe `docker-compose.yaml`):**
|
||||
|
||||
@@ -77,8 +77,8 @@ Ruft man die nackte Domain `server.schooltech.ch` auf, erscheint die
|
||||

|
||||
|
||||
*Oben die Navigationsleiste mit Logo und Dienst-Buttons, darunter der gewählte
|
||||
Dienst im iFrame. (Quelle: [`doc/Portal.svg`](doc/Portal.svg), auch als
|
||||
[`doc/Portal.pdf`](doc/Portal.pdf).)*
|
||||
Dienst im iFrame. (Quelle: [`doc/Portal.svg`](doc/Portal.svg) — auch als
|
||||
[`doc/Portal.png`](doc/Portal.png) und [`doc/Portal.pdf`](doc/Portal.pdf).)*
|
||||
|
||||
1. Seite öffnen → ist man nicht eingeloggt, zeigt der Button **„Login“**.
|
||||
2. Login (User/Passwort) → der Auth-Service setzt ein Session-Cookie für die
|
||||
@@ -205,7 +205,9 @@ Läuft **automatisch beim Containerstart** des nginx-Containers (liegt als
|
||||
`/docker-entrypoint.d/40-connect-proxies.sh`). Pro `forwarding.conf`-Zeile:
|
||||
|
||||
1. **Globale Map + Resolver** schreiben (`_globals.generated.conf`) – nötig für
|
||||
WebSockets und für die DNS-Auflösung der Upstreams zur Laufzeit.
|
||||
WebSockets und für die DNS-Auflösung der Upstreams zur Laufzeit. Außerdem ein
|
||||
**443-Default-Server** (`00-default-server.generated.conf`), der unbekanntes
|
||||
SNI per `ssl_reject_handshake` abweist (siehe Hinweis unten).
|
||||
2. **Alte generierte Configs** löschen (`*-https.generated.conf`,
|
||||
`*-http-redirect.generated.conf`).
|
||||
3. Pro Dienst eine vHost-Datei erzeugen – mit Fallunterscheidung:
|
||||
@@ -215,7 +217,8 @@ Läuft **automatisch beim Containerstart** des nginx-Containers (liegt als
|
||||
optional `proxy_ssl_verify`, optional `auth_request`-Schutz.
|
||||
- **DNS nicht auflösbar** → statt Proxy ein **503-Platzhalter** („Service
|
||||
nicht erreichbar“), damit nginx trotzdem startet.
|
||||
- **Kein Zertifikat vorhanden** → vHost wird **übersprungen** (keine 443-Conf).
|
||||
- **Kein Zertifikat vorhanden** → vHost wird **übersprungen** (keine 443-Conf);
|
||||
solche Anfragen fängt der 443-Default-Server ab (siehe Hinweis unten).
|
||||
- Bei `http_behavior = redirect` zusätzlich ein **80→443-Redirect** (mit
|
||||
Ausnahme für die ACME-Challenge).
|
||||
4. Abschließend **`nginx -t`** zur Syntaxprüfung.
|
||||
@@ -223,6 +226,14 @@ Läuft **automatisch beim Containerstart** des nginx-Containers (liegt als
|
||||
So ist das System robust: fehlt ein Zertifikat oder ein Backend, fällt nur der
|
||||
betroffene Dienst aus – nginx selbst läuft weiter.
|
||||
|
||||
> **Anti-Leak / Default-Server:** Ohne expliziten Default bedient nginx eine
|
||||
> Anfrage mit unbekanntem `server_name` mit dem *ersten* 443-Block (alphabetisch –
|
||||
> das war `ai.server.schooltech.ch`). Damit eine Domain ohne passenden vHost
|
||||
> (z. B. fehlendes Zertifikat) **nicht still** bei einem fremden Dienst landet,
|
||||
> erzeugt das Skript einen Catch-all `listen 443 ssl default_server;
|
||||
> ssl_reject_handshake on;` – unbekanntes SNI bekommt einen sauberen TLS-Abbruch.
|
||||
> `server.schooltech.ch` & Co. treffen ihren eigenen vHost weiterhin per SNI-Match.
|
||||
|
||||
> **Aktiver Pfad vs. Referenz:** Die vHosts werden zur Laufzeit von
|
||||
> `connect-proxies.sh` aus `forwarding.conf` erzeugt. Die statischen Dateien in
|
||||
> `nginxPages/` sind **nicht** in `docker-compose.yaml` gemountet und dienen nur
|
||||
|
||||
@@ -40,6 +40,23 @@ map \$http_upgrade \$connection_upgrade {
|
||||
$RESOLVER_LINE
|
||||
NGINX
|
||||
|
||||
# 1b) Default-Server für 443: weist unbekanntes/leeres SNI sauber ab,
|
||||
# statt es an den alphabetisch ersten vHost zu "vererben" (Anti-Leak).
|
||||
# Greift auch dann, wenn einer Domain das Zertifikat fehlt.
|
||||
DEFAULT_443_FILE="$CONF_DIR/00-default-server.generated.conf"
|
||||
cat > "$DEFAULT_443_FILE" <<'NGINX'
|
||||
# Automatisch generiert – nicht editieren
|
||||
# Fängt alle HTTPS-Verbindungen ab, deren SNI auf keinen echten vHost passt,
|
||||
# und lehnt den TLS-Handshake ab. So landet eine unbekannte/zertifikatslose
|
||||
# Domain NIE still beim ersten vHost. Braucht per ssl_reject_handshake
|
||||
# bewusst KEIN eigenes Zertifikat.
|
||||
server {
|
||||
listen 443 ssl http2 default_server;
|
||||
listen [::]:443 ssl http2 default_server;
|
||||
ssl_reject_handshake on;
|
||||
}
|
||||
NGINX
|
||||
|
||||
# 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
|
||||
|
||||
BIN
doc/Architektur.png
Normal file
BIN
doc/Architektur.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 147 KiB |
BIN
doc/Portal.png
Normal file
BIN
doc/Portal.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 195 KiB |
Reference in New Issue
Block a user