diff --git a/README.md b/README.md index 9d8fc4a..ac2f5c3 100644 --- a/README.md +++ b/README.md @@ -28,23 +28,29 @@ Basisrouten nach dem Start: - `http://localhost:8080/hints.html` -> Hint Cheatsheet - `http://localhost:8080/solutions.html` -> Musterloesungen -## Voraussetzungen (WSL oder Linux) +## Voraussetzungen (Linux / macOS / Windows WSL) 1. Docker + Compose (`docker compose` oder `docker-compose`) -2. Bei Windows: Docker Desktop + WSL Integration aktiv -3. Optional fuer TLS-Challenges: `easy-rsa`, `openssl`, `wireshark` +2. Optional fuer TLS-Challenges: `easy-rsa`, `openssl`, `wireshark` + +Plattformhinweise: + +- Linux: Docker Engine oder Docker Desktop +- macOS: Docker Desktop +- Windows: Docker Desktop + WSL Integration aktiv +- macOS: falls `make` fehlt -> `xcode-select --install` ## Schnellstart +### Linux / macOS + ```bash ./scripts/bootstrap.sh ``` -### Start auf Windows +### Windows (WSL) -Empfohlen: ueber WSL starten (nicht nativ in PowerShell ohne WSL). - -Option A (WSL Terminal): +Option A (im WSL-Terminal): ```bash ./scripts/bootstrap.sh @@ -56,7 +62,7 @@ Option B (PowerShell Wrapper): ./scripts/workshop.ps1 -Action bootstrap ``` -Der PowerShell-Wrapper braucht kein `make` und ruft die Linux-Skripte direkt in WSL auf. +Der PowerShell-Wrapper braucht kein `make` und ruft Linux-Skripte direkt in WSL auf. Falls PowerShell das Script blockiert: @@ -64,12 +70,13 @@ Falls PowerShell das Script blockiert: Set-ExecutionPolicy -Scope Process Bypass ``` -Weitere Aktionen aus PowerShell: +Weitere Aktionen in PowerShell: ```powershell ./scripts/workshop.ps1 -Action redeploy ./scripts/workshop.ps1 -Action proxy-reload ./scripts/workshop.ps1 -Action reset +./scripts/workshop.ps1 -Action reset-hard ``` Wenn mehrere Distros installiert sind: @@ -78,23 +85,31 @@ Wenn mehrere Distros installiert sind: ./scripts/workshop.ps1 -Action bootstrap -Distro Ubuntu-24.04 ``` -Der Script: +Das Skript: - prueft Docker + Compose - erstellt `.env` aus `.env.example` (falls nicht vorhanden) - startet den Stack +Hinweis zu Skriptnamen: + +- `scripts/bootstrap.sh` ist der empfohlene Einstieg +- intern nutzt es `scripts/bootstrap-unix.sh` +- `scripts/bootstrap-wsl.sh` existiert nur noch als Kompatibilitaets-Wrapper + ## Neu deployen / resetten ```bash make redeploy make proxy-reload make reset +make reset-hard ``` - `redeploy`: build + restart aller Services - `proxy-reload`: nur Reverse Proxy restart - `reset`: Container/Netzwerk/Volumes aufraeumen +- `reset-hard`: wie `reset`, plus lokale Git-Aenderungen verwerfen (falls Git-Repo) Hinweis: `make redeploy` startet zusaetzlich den Reverse Proxy neu, damit Nginx-Config-Aenderungen sicher aktiv sind. diff --git a/backends/a2/index.html b/backends/a2/index.html new file mode 100644 index 0000000..7387421 --- /dev/null +++ b/backends/a2/index.html @@ -0,0 +1,47 @@ + + + + + + Backend A2 + + + +
+

Reverse Proxy Target A2

+

Use this page to validate load balancing between backend-a and backend-a2.

+
+ + diff --git a/backends/c/index.html b/backends/c/index.html new file mode 100644 index 0000000..1451557 --- /dev/null +++ b/backends/c/index.html @@ -0,0 +1,74 @@ + + + + + + Backend C + + + +
+ Backend C +

Reverse Proxy Target C

+

This is a starter page for challenge 2.

+

Route example: /service/c

+
+ + diff --git a/challenges/README.md b/challenges/README.md index e44004d..dda1d91 100644 --- a/challenges/README.md +++ b/challenges/README.md @@ -1,32 +1,33 @@ # Workshop Challenges (Reverse Proxy + TLS Focus) -Diese Aufgaben sind auf **manuelle Proxy-Konfiguration** ausgelegt. +Diese Aufgaben sind bewusst auf **manuelle Proxy-Konfiguration** ausgelegt. -Abgabe pro Aufgabe: +## Abgabe-Format pro Challenge -- kurzer Demo-Run (1-3 Minuten) -- Done-Check Command -- 2-3 Saetze: Was wurde geaendert und warum? +- 1-3 Minuten Demo +- Done-Check Command live ausfuehren +- 2-3 Saetze erklaeren: was geaendert, warum, welche Wirkung ## Arbeitsmodus -1. Datei anpassen (`proxy/nginx.conf`, `docker-compose.yml`). +1. Dateien anpassen (`proxy/nginx.conf`, `docker-compose.yml`). 2. Deployen mit `make redeploy` oder `make proxy-reload`. -3. Testen mit `curl`/`openssl`. -4. Wenn etwas kaputt ist: `./scripts/compose.sh logs reverse-proxy`. +3. Testen mit `curl` / `openssl` / Wireshark. +4. Bei Problemen: `./scripts/compose.sh logs reverse-proxy`. --- ## Easy -### 1) Routing verstehen +### 1) Routing verstehen (aktiv) **Ziel** -- Reverse Proxy leitet Requests auf unterschiedliche Backends. +- Verstehen, wie Nginx Requests per Pfad an unterschiedliche Upstreams schickt. **Muss** -- `service/a` und `service/b` aufrufen. -- Unterschiede in den Antworten erklaeren. +- Vor dem Test in `proxy/nginx.conf` nachsehen, welche `location` auf welchen `upstream` zeigt. +- Dann erst Requests ausfuehren. +- In eigenen Worten erklaeren, warum die Antworten unterschiedlich sind. **Done-Check** ```bash @@ -37,32 +38,36 @@ curl http://localhost:8080/service/b ### 2) Drittes Backend manuell hinzufuegen **Ziel** -- Proxy auf ein neues Backend erweitern. +- Setup sicher erweitern, ohne bestehende Routen kaputt zu machen. **Dateien** - `docker-compose.yml` - `proxy/nginx.conf` +- `backends/c/index.html` (vorhanden, darf angepasst werden) **Muss** -- Service `backend-c` anlegen. -- Upstream + Route `/service/c` konfigurieren. +- Service `backend-c` in Compose einbauen. +- Upstream + Route `/service/c` in Nginx anlegen. +- A/B muessen weiterhin funktionieren. **Done-Check** ```bash curl http://localhost:8080/service/c +curl http://localhost:8080/service/a +curl http://localhost:8080/service/b ``` -### 3) Eigene Route mit Rewrite +### 3) Eigene Route mit Rewrite oder Alias-Route **Ziel** -- URL-Struktur im Proxy gestalten. +- URL-Design vom Backend-Pfad entkoppeln. **Datei** - `proxy/nginx.conf` **Muss** -- Route `/demo/a` soll intern auf Backend A zeigen. -- Implementierung ueber `rewrite` oder eigene `location`. +- Route `/demo/a` anbieten, die auf Backend A fuehrt. +- Entweder per rewrite oder per eigener proxy-Route loesen. **Done-Check** ```bash @@ -76,13 +81,13 @@ curl http://localhost:8080/demo/a ### 4) Security Headers setzen **Ziel** -- Grundlegende Header-Haertung im Proxy. +- Browserseitige Basishaertung aktivieren. **Datei** - `proxy/nginx.conf` **Muss** -- Setze mindestens: +- Mindestens setzen: - `X-Content-Type-Options: nosniff` - `X-Frame-Options: DENY` - `Referrer-Policy: no-referrer` @@ -95,31 +100,38 @@ curl -I http://localhost:8080/ ### 5) Interne Route absichern **Ziel** -- Route nur lokal erreichbar machen. +- Zugriff auf eine interne Route gezielt begrenzen. **Datei** - `proxy/nginx.conf` **Muss** -- Neue Route `/internal/status` bauen. +- Route `/internal/status` bauen. - Nur `127.0.0.1` erlauben, alle anderen verbieten. +**Wichtiger Hinweis** +- Host-Request ueber `localhost:8080` kommt aus Docker-Sicht oft **nicht** von `127.0.0.1`. + **Done-Check** ```bash +# Erwartet typischerweise 403 vom Host (by design) curl -i http://localhost:8080/internal/status + +# Muss innerhalb des Proxy-Containers funktionieren +./scripts/compose.sh exec -T reverse-proxy sh -lc "wget -qO- http://127.0.0.1/internal/status" ``` ### 6) Logging verbessern **Ziel** -- Proxy-Debugging ueber bessere Logs. +- Besser debuggen koennen. **Datei** - `proxy/nginx.conf` **Muss** -- Eigenes `log_format` mit Upstream-Infos erstellen. -- Access Log auf dieses Format umstellen. +- Eigenes `log_format` mit Upstream-Infos anlegen. +- Access-Log auf das neue Format umstellen. **Done-Check** ```bash @@ -127,6 +139,65 @@ curl http://localhost:8080/service/a ./scripts/compose.sh logs reverse-proxy ``` +### 6a) Load Balancing konfigurieren + +**Ziel** +- Kernfunktion eines Reverse Proxys praktisch zeigen. + +**Dateien** +- `docker-compose.yml` +- `proxy/nginx.conf` + +**Muss** +- Zweite Instanz von Backend A (`backend-a2`) anlegen. +- `upstream backend_a` auf beide Instanzen erweitern. +- Mehrfach-Requests zeigen, dass beide Instanzen antworten. + +**Done-Check (Beispiel)** +```bash +for i in $(seq 1 8); do + curl -s http://localhost:8080/service/a | grep -o "Target A2\|Target A" +done +``` + +### 6b) Header Stripping (Response) + +**Ziel** +- Unnoetige Header aus Upstream-Responses entfernen. + +**Datei** +- `proxy/nginx.conf` + +**Muss** +- Mit `proxy_hide_header` mindestens einen durchgereichten Backend-Header ausblenden + (z. B. `ETag`, `Last-Modified`). +- Kurz erklaeren, warum weniger Fingerprinting-Infos hilfreich sind. + +**Done-Check** +```bash +curl -I http://localhost:8080/service/a +``` + +### 6c) Debugging Challenge (kaputte Config reparieren) + +**Ziel** +- Fehlerdiagnose in Nginx ueben. + +**Datei** +- `proxy/nginx.broken.conf` + +**Muss** +- Defekte Config testweise als aktive Config verwenden. +- Mindestens 2-3 Fehler finden und fixen. +- Symptome und Diagnoseweg erklaeren. + +**Done-Check** +```bash +curl http://localhost:8080/service/a +curl http://localhost:8080/service/b +./scripts/compose.sh logs reverse-proxy +``` + --- ## Hard (TLS) @@ -134,16 +205,16 @@ curl http://localhost:8080/service/a ### 7) HTTPS von 0 mit Easy-RSA **Ziel** -- Eigene CA + Server-Zertifikat fuer `localhost`. +- Eigene CA + Server-Zertifikat fuer `localhost` erstellen. **Dateien** - `docker-compose.yml` - `proxy/nginx.conf` **Muss** -- Cert fuer `localhost` erzeugen. -- Proxy auf `443` aktivieren (z. B. `8443:443`). -- Root-CA importieren. +- Zertifikat fuer `localhost` erstellen. +- Proxy auf `443` erweitern (z. B. `8443:443`). +- Root-CA importieren und ohne `-k` testen. **Done-Check** ```bash @@ -152,14 +223,18 @@ curl https://localhost:8443/service/a ### 8) HTTP -> HTTPS Redirect +**Voraussetzung** +- Challenge 7 muss abgeschlossen sein. +- Nutze deine bestehende `nginx.conf` aus Challenge 7 als Basis. + **Ziel** -- Klarer Redirect-Flow. +- HTTP sauber auf HTTPS umlenken. **Datei** - `proxy/nginx.conf` **Muss** -- HTTP Requests auf HTTPS umleiten. +- HTTP Requests auf HTTPS redirecten. - `/healthz` darf optional auf HTTP bleiben. **Done-Check** @@ -167,20 +242,25 @@ curl https://localhost:8443/service/a curl -I http://localhost:8080/service/a ``` -### 9) TLS Haertung + Chain Check +### 9) TLS Haertung + Chain Check + HSTS + +**Voraussetzung** +- Challenge 7 und 8 muessen abgeschlossen sein. +- Erweitere dieselbe `nginx.conf` weiter. **Ziel** -- Bessere TLS-Defaults + saubere Validierung. +- TLS nicht nur aktivieren, sondern sauber haerten. **Datei** - `proxy/nginx.conf` **Muss** - TLS auf 1.2/1.3 beschraenken. -- HSTS aktivieren (`Strict-Transport-Security`). -- Zertifikatskette pruefen. +- HSTS setzen (`Strict-Transport-Security`). +- Zertifikatskette pruefen und kurz erklaeren. -Hinweis: Im HTTP-Basissetup ist HSTS absichtlich **noch nicht** aktiv. Das ist Teil der Aufgabe. +**Hinweis** +- Im HTTP-Basissetup ist HSTS absichtlich **noch nicht** aktiv. Das ist Teil der Aufgabe. **Done-Check** ```bash @@ -192,23 +272,22 @@ openssl s_client -connect localhost:8443 -servername localhost ## Bonus Expert -### 10) Wireshark: HTTP vs HTTPS +### 10) Wireshark: HTTP vs HTTPS sauber analysieren **Ziel** -- Sichtbar machen, was verschluesselt ist und was nicht. +- Nachweisbar zeigen, was im Klartext sichtbar ist und was durch TLS geschuetzt wird. **Muss** -- HTTP Traffic auf `8080` mitschneiden. -- HTTPS Traffic auf `8443` mitschneiden. -- TLS Handshake markieren (`ClientHello`, `ServerHello`, `Certificate`). -- Technisch erklaeren, warum HTTP lesbar ist und HTTPS nicht. +- HTTP auf `8080` mitschneiden. +- HTTPS auf `8443` mitschneiden. +- `ClientHello`, `ServerHello`, `Certificate` markieren. +- Technisch erklaeren, warum HTTP lesbar ist und HTTPS ohne Keys nicht. **Vorgehen (empfohlen)** -1. Capture auf `lo` (oder passendes Interface) starten, Filter `tcp.port == 8080`. -2. `curl http://localhost:8080/service/a` senden und HTTP-Stream zeigen. -3. Capture auf `tcp.port == 8443` oder `tls` umstellen. -4. `curl https://localhost:8443/service/a` senden. -5. Handshake-Pakete markieren und kurz erklaeren. +1. Capture auf passendem Interface starten (lokal meist `lo`). +2. HTTP Request senden und lesbaren Stream zeigen. +3. HTTPS Request senden und TLS Handshake analysieren. +4. Ergebnisse in 3-5 Bulletpoints zusammenfassen. **Optional** - TLS Decrypt mit `SSLKEYLOGFILE`. diff --git a/proxy/html/challenges.html b/proxy/html/challenges.html index a07dc53..54d58b7 100644 --- a/proxy/html/challenges.html +++ b/proxy/html/challenges.html @@ -150,7 +150,7 @@

Challenges - Reverse Proxy & TLS

-

Fokus: manuelle Proxy-Konfiguration, saubere Security-Entscheidungen, TLS von Grund auf.

+

Manuelle Proxy-Konfiguration, Security-Entscheidungen und TLS von Grund auf.

-

Abgabe-Format (fuer jede Challenge)

+

Abgabe-Format

@@ -173,45 +173,28 @@

Easy

- Easy 1) Routing verstehen -

Ziel: Verstehen, wie der Reverse Proxy Requests anhand des Pfads verteilt.

-

Muss:

+ Easy 1) Routing verstehen (aktiv) +

Muss: zuerst in proxy/nginx.conf nachsehen, dann testen.

-

Done-Check:

curl http://localhost:8080/service/a
 curl http://localhost:8080/service/b
- Easy 2) backend-c manuell hinzufuegen -

Ziel: Proxy-Setup sinnvoll erweitern, ohne bestehenden Traffic zu brechen.

-

Dateien: docker-compose.yml, proxy/nginx.conf

-

Muss:

- -

Done-Check:

+ Easy 2) backend-c hinzufuegen +

Muss: Compose-Service + Upstream + Route /service/c.

+

Zusatz: backends/c/index.html ist vorhanden und darf angepasst werden.

curl http://localhost:8080/service/c
 curl http://localhost:8080/service/a
 curl http://localhost:8080/service/b
- Easy 3) Eigene Route mit Rewrite -

Ziel: URL-Design vom Backend entkoppeln.

-

Muss:

- -

Done-Check:

+ Easy 3) Eigene Route /demo/a +

Muss: Alias-Route bauen, die auf Backend A fuehrt.

curl http://localhost:8080/demo/a
@@ -220,43 +203,45 @@ curl http://localhost:8080/service/b

Medium

- Medium 4) Security Headers setzen -

Ziel: Browser-Schutzmechanismen bewusst aktivieren.

-

Muss:

- -

Done-Check:

+ Medium 4) Security Headers +

Setze mindestens nosniff, DENY, no-referrer.

curl -I http://localhost:8080/
-

Abgabe: kurz erklaeren, welchen Angriff jeder Header erschwert.

Medium 5) Interne Route absichern -

Ziel: Zugangskontrolle direkt im Proxy umsetzen.

-

Muss:

- -

Done-Check:

-
curl -i http://localhost:8080/internal/status
+

Muss: /internal/status nur fuer 127.0.0.1.

+

Wichtig: Host-Request zeigt typischerweise 403 (Docker-Netzwerk).

+
curl -i http://localhost:8080/internal/status
+./scripts/compose.sh exec -T reverse-proxy sh -lc "wget -qO- http://127.0.0.1/internal/status"
Medium 6) Logging verbessern -

Ziel: Fehler schneller eingrenzen koennen.

-

Muss:

- -

Done-Check:

+

Eigenes log_format mit Upstream-Infos einbauen.

curl http://localhost:8080/service/a
+./scripts/compose.sh logs reverse-proxy
+
+ +
+ Medium 6a) Load Balancing +

Zweite Instanz von Backend A (backend-a2) einbauen und Round-Robin zeigen.

+
for i in $(seq 1 8); do
+  curl -s http://localhost:8080/service/a | grep -o "Target A2\|Target A"
+done
+
+ +
+ Medium 6b) Header Stripping +

Mindestens einen Backend-Response-Header per proxy_hide_header ausblenden.

+
curl -I http://localhost:8080/service/a
+
+ +
+ Medium 6c) Debugging Challenge +

Mit proxy/nginx.broken.conf arbeiten, Fehler finden und reparieren.

+
curl http://localhost:8080/service/a
+curl http://localhost:8080/service/b
 ./scripts/compose.sh logs reverse-proxy
@@ -266,41 +251,19 @@ curl http://localhost:8080/service/b
Hard 7) HTTPS von 0 (Easy-RSA) -

Ziel: Eigene PKI und TLS-Endpoint fuer den Proxy aufbauen.

-

Muss:

- -

Done-Check:

+

Zertifikat fuer localhost, Port 8443:443, Root-CA importiert.

curl https://localhost:8443/service/a
Hard 8) HTTP -> HTTPS Redirect -

Ziel: Client sauber auf TLS umleiten.

-

Muss:

- -

Done-Check:

+

Voraussetzung: Challenge 7 abgeschlossen. Bestehende Config weiterverwenden.

curl -I http://localhost:8080/service/a
- Hard 9) TLS Haertung + Chain Check + HSTS -

Ziel: TLS nicht nur aktivieren, sondern sinnvoll haerten.

-

Muss:

- -

Hinweis: Im HTTP-Basissetup ist HSTS absichtlich noch nicht aktiv.

-

Done-Check:

+ Hard 9) TLS Haertung + Chain + HSTS +

Voraussetzung: Challenge 7 und 8 abgeschlossen. Gleiche Config weiter erweitern.

curl -I https://localhost:8443/service/a
 openssl s_client -connect localhost:8443 -servername localhost
@@ -311,21 +274,14 @@ openssl s_client -connect localhost:8443 -servername localhost
Expert 10) Wireshark: HTTP vs HTTPS sauber ausarbeiten -

Ziel: Nachweisbar zeigen, was bei HTTP lesbar und bei HTTPS geschuetzt ist.

-

Muss:

    -
  1. HTTP Capture auf Port 8080, Request erzeugen, Klartext markieren.
  2. -
  3. HTTPS Capture auf Port 8443, TLS Handshake markieren.
  4. -
  5. Pakete mit ClientHello, ServerHello, Certificate zeigen.
  6. -
  7. Kurze Analyse: Was sieht ein Angreifer im HTTP-Fall vs im HTTPS-Fall?
  8. +
  9. HTTP auf 8080 mitschneiden und Klartext zeigen.
  10. +
  11. HTTPS auf 8443 mitschneiden.
  12. +
  13. ClientHello, ServerHello, Certificate markieren.
  14. +
  15. 3-5 Bulletpoints: was ist sichtbar, was ist geschuetzt?
-

Optional: TLS Decrypt via SSLKEYLOGFILE und Unterschied vorher/nachher erklaeren.

-

Done-Check / Abgabe:

- +

Optional: TLS Decrypt mit SSLKEYLOGFILE.

+

Abgabe: mind. 3 Screenshots + technische Interpretation.

diff --git a/proxy/html/solutions.html b/proxy/html/solutions.html index 0f0f174..7e84af9 100644 --- a/proxy/html/solutions.html +++ b/proxy/html/solutions.html @@ -190,12 +190,12 @@ location /service/c { proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; }

Check: curl http://localhost:8080/service/c

+

Hinweis: Stelle sicher, dass backends/c/index.html existiert (Starterdatei liegt bereits im Repo).

Easy 3) Rewrite Route
location = /demo/a {
-  rewrite ^ /service/a break;
   proxy_pass http://backend_a/;
 }

Check: curl http://localhost:8080/demo/a

@@ -221,7 +221,9 @@ add_header Referrer-Policy "no-referrer" always; default_type text/plain; return 200 "internal ok\n"; } -

Check: curl -i http://localhost:8080/internal/status

+

Check (Host): curl -i http://localhost:8080/internal/status (typisch 403)

+

Check (Container-intern):

+
./scripts/compose.sh exec -T reverse-proxy sh -lc "wget -qO- http://127.0.0.1/internal/status"
@@ -235,6 +237,44 @@ access_log /var/log/nginx/access.log workshop;
curl http://localhost:8080/service/a
 ./scripts/compose.sh logs reverse-proxy
+ +
+ Medium 6a) Load Balancing +

Compose (backend-a2):

+
backend-a2:
+  image: nginx:1.27-alpine
+  container_name: workshop-backend-a2
+  volumes:
+    - ./backends/a2:/usr/share/nginx/html:ro,z
+

Nginx (upstream erweitern):

+
upstream backend_a {
+  server backend-a:80;
+  server backend-a2:80;
+}
+

Check:

+
for i in $(seq 1 8); do
+  curl -s http://localhost:8080/service/a | grep -o "Target A2\|Target A"
+done
+
+ +
+ Medium 6b) Header Stripping +
location /service/a {
+  proxy_pass http://backend_a/;
+  proxy_hide_header ETag;
+  proxy_hide_header Last-Modified;
+}
+

Check: curl -I http://localhost:8080/service/a

+
+ +
+ Medium 6c) Debugging Challenge +

Kopiere testweise proxy/nginx.broken.conf auf proxy/nginx.conf, behebe die Fehler und stelle danach die funktionierende Konfiguration wieder her.

+
cp proxy/nginx.broken.conf proxy/nginx.conf
+make proxy-reload
+./scripts/compose.sh logs reverse-proxy
+

Check: beide Routen funktionieren wieder.

+
@@ -261,6 +301,7 @@ cd certs/easyrsa
Hard 8) HTTP -> HTTPS Redirect +

Voraussetzung: Challenge 7 abgeschlossen (gleiches Config-File weiterverwenden).

server {
   listen 80;
   server_name _;
@@ -279,6 +320,7 @@ cd certs/easyrsa
 
         
Hard 9) TLS Haertung + HSTS +

Voraussetzung: Challenge 7 und 8 abgeschlossen.

ssl_protocols TLSv1.2 TLSv1.3;
 ssl_prefer_server_ciphers on;
 add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" always;
diff --git a/proxy/nginx.broken.conf b/proxy/nginx.broken.conf new file mode 100644 index 0000000..f5b8d1a --- /dev/null +++ b/proxy/nginx.broken.conf @@ -0,0 +1,47 @@ +events { + worker_connections 1024; +} + +http { + include /etc/nginx/mime.types; + default_type application/octet-stream; + sendfile on; + server_tokens off; + + upstream backend_a_typo { + server backend-a:8080; + } + + upstream backend_b { + server backend-b:80; + } + + server { + listen 80; + server_name _; + + location / { + root /usr/share/nginx/html; + try_files $uri $uri/ /index.html; + } + + location /service/a { + proxy_pass http://backend_a/; + proxy_set_header Host $host; + proxy_set_header X-Forwarded-Proto http; + proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; + } + + location /service/b { + proxy_pass http://backend_b; + proxy_set_header Host $host; + proxy_set_header X-Forwarded-Proto http; + proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; + } + + location = /healthz { + default_type text/plain; + return 200 "ok\n"; + } + } +} diff --git a/proxy/nginx.conf b/proxy/nginx.conf index e64d448..e519aee 100644 --- a/proxy/nginx.conf +++ b/proxy/nginx.conf @@ -39,7 +39,7 @@ http { proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; } - location /healthz { + location = /healthz { default_type text/plain; return 200 "ok\n"; } diff --git a/scripts/bootstrap-unix.sh b/scripts/bootstrap-unix.sh new file mode 100755 index 0000000..126ae9a --- /dev/null +++ b/scripts/bootstrap-unix.sh @@ -0,0 +1,36 @@ +#!/usr/bin/env bash +set -euo pipefail + +SCRIPT_DIR="$(cd -- "$(dirname -- "${BASH_SOURCE[0]}")" && pwd)" +PROJECT_ROOT="$(cd -- "$SCRIPT_DIR/.." && pwd)" + +cd "$PROJECT_ROOT" + +if ! command -v docker >/dev/null 2>&1; then + echo "[error] docker nicht gefunden. Bitte Docker installieren (Linux/macOS) oder Docker Desktop + WSL Integration aktivieren." + exit 1 +fi + +if ! docker info >/dev/null 2>&1; then + echo "[error] Docker Daemon nicht erreichbar. Bitte Docker starten." + exit 1 +fi + +if ! "$SCRIPT_DIR/compose.sh" version >/dev/null 2>&1; then + echo "[error] Weder docker compose noch docker-compose verfuegbar." + exit 1 +fi + +if [[ ! -f .env ]]; then + cp .env.example .env + echo "[ok] .env aus .env.example erstellt" +else + echo "[skip] .env existiert bereits" +fi + +"$SCRIPT_DIR/compose.sh" up -d --build + +echo +echo "[ok] Workshop-Stack laeuft" +echo " Landing Page: http://localhost:8080" +echo " Test (backend-a): curl http://localhost:8080/service/a" diff --git a/scripts/bootstrap-wsl.sh b/scripts/bootstrap-wsl.sh index 0e10af0..50f3674 100755 --- a/scripts/bootstrap-wsl.sh +++ b/scripts/bootstrap-wsl.sh @@ -2,35 +2,5 @@ set -euo pipefail SCRIPT_DIR="$(cd -- "$(dirname -- "${BASH_SOURCE[0]}")" && pwd)" -PROJECT_ROOT="$(cd -- "$SCRIPT_DIR/.." && pwd)" - -cd "$PROJECT_ROOT" - -if ! command -v docker >/dev/null 2>&1; then - echo "[error] docker nicht gefunden. Bitte Docker installieren (Linux) oder Docker Desktop + WSL Integration aktivieren." - exit 1 -fi - -if ! docker info >/dev/null 2>&1; then - echo "[error] Docker Daemon nicht erreichbar. Bitte Docker starten." - exit 1 -fi - -if ! "$SCRIPT_DIR/compose.sh" version >/dev/null 2>&1; then - echo "[error] Weder docker compose noch docker-compose verfuegbar." - exit 1 -fi - -if [[ ! -f .env ]]; then - cp .env.example .env - echo "[ok] .env aus .env.example erstellt" -else - echo "[skip] .env existiert bereits" -fi - -"$SCRIPT_DIR/compose.sh" up -d --build - -echo -echo "[ok] Workshop-Stack laeuft" -echo " Landing Page: http://localhost:8080" -echo " Test (backend-a): curl http://localhost:8080/service/a" +echo "[warn] scripts/bootstrap-wsl.sh ist deprecated. Nutze bitte scripts/bootstrap.sh" +"$SCRIPT_DIR/bootstrap-unix.sh" diff --git a/scripts/bootstrap.sh b/scripts/bootstrap.sh index 767793f..0dda692 100755 --- a/scripts/bootstrap.sh +++ b/scripts/bootstrap.sh @@ -2,4 +2,4 @@ set -euo pipefail SCRIPT_DIR="$(cd -- "$(dirname -- "${BASH_SOURCE[0]}")" && pwd)" -"$SCRIPT_DIR/bootstrap-wsl.sh" +"$SCRIPT_DIR/bootstrap-unix.sh" diff --git a/scripts/workshop.ps1 b/scripts/workshop.ps1 index 8ebcd00..b36e2aa 100644 --- a/scripts/workshop.ps1 +++ b/scripts/workshop.ps1 @@ -1,5 +1,5 @@ param( - [ValidateSet("bootstrap", "up", "redeploy", "proxy-reload", "down", "logs", "reset")] + [ValidateSet("bootstrap", "up", "redeploy", "proxy-reload", "down", "logs", "reset", "reset-hard")] [string]$Action = "bootstrap", [string]$Distro = "" ) @@ -25,6 +25,7 @@ switch ($Action) { "down" { $linuxCommand = "./scripts/compose.sh down" } "logs" { $linuxCommand = "./scripts/compose.sh logs -f" } "reset" { $linuxCommand = "./scripts/reset-lab.sh" } + "reset-hard" { $linuxCommand = "./scripts/reset-lab.sh --hard" } } $wslArgs = @()