Verbessere Challenge-Angaben, TLS-Fixes und Windows-Tauglichkeit
Fachliche Fixes: - Easy-RSA: explizites --subject-alt-name (SAN) ergaenzt, sonst scheitert curl trotz CA-Import - HSTS: max-age auf 3600 reduziert, includeSubDomains erklaert, Warnung zur host-weiten Browser-Falle + Reset-Weg - Challenge 9: Backup-/Restore-Schritte fuer nginx.conf - Compose-Portwechsel: redeploy statt proxy-reload klargestellt - log_format-Platzierung (http-Block) dokumentiert - add_header-Vererbungsfalle erklaert (Ch. 4 + Abgrenzung Ch. 8) Angabe-Struktur (alle 13 Challenges): - Einheitliches Schema: Ausgangszustand, Schritte (Muss), Zielzustand/Akzeptanz, erwartete Done-Check-Ausgaben - Arbeitsweise global geklaert (additiv, Ausnahme Ch. 9, Reset) Robustheit/Kosmetik: - Load-Balancing: eindeutiger INSTANCE-Marker statt fragilem grep - Challenge-3-Titel auf "Alias-Route" korrigiert - HTTPS_PORT in .env.example parametrisiert - Umlaut-Konsistenz (ASCII) Windows-Tauglichkeit: - Klargestellt: Test-Kommandos laufen in WSL bash, nicht PowerShell (curl-Alias-Falle), Stack-Steuerung per Wrapper oder WSL - Wireshark: empfohlener Capture-Weg in WSL (tshark), npcap-Hinweis - CA-Import: Linux-Trust-Store (WSL) vs Windows-Browser (certutil) Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
@@ -215,7 +215,7 @@ location /service/c {
|
||||
</details>
|
||||
|
||||
<details>
|
||||
<summary><span class="badge easy">Easy</span> 3) Rewrite Route</summary>
|
||||
<summary><span class="badge easy">Easy</span> 3) Alias-Route /demo/a</summary>
|
||||
<p><span class="kw">Dateien:</span> <code>proxy/nginx.conf</code></p>
|
||||
<p><span class="kw">Commands noetig:</span> ja</p>
|
||||
<pre><code>location = /demo/a {
|
||||
@@ -238,6 +238,7 @@ add_header Referrer-Policy "strict-origin-when-cross-origin" always;
|
||||
add_header Permissions-Policy "camera=(), microphone=(), geolocation=()" always;
|
||||
add_header Cross-Origin-Opener-Policy "same-origin" always;
|
||||
add_header Cross-Origin-Resource-Policy "same-origin" always;</code></pre>
|
||||
<p><span class="kw">Platzierung:</span> in den <code>server {}</code>-Block, damit alle Locations sie erben. Sobald eine Location ein eigenes <code>add_header</code> hat, verwirft Nginx dort die Server-Header und sie muessen wiederholt werden.</p>
|
||||
<p><span class="kw">Optional CSP (statisch, inline styles erlaubt):</span></p>
|
||||
<pre><code>add_header Content-Security-Policy "default-src 'self'; style-src 'self' 'unsafe-inline'; img-src 'self' data:; object-src 'none'; base-uri 'none'; frame-ancestors 'none'" always;</code></pre>
|
||||
<p><span class="kw">Check:</span> <code>curl -I http://localhost:8080/</code></p>
|
||||
@@ -262,6 +263,7 @@ add_header Cross-Origin-Resource-Policy "same-origin" always;</code></pre>
|
||||
<summary><span class="badge medium">Medium</span> 6) Logging verbessern</summary>
|
||||
<p><span class="kw">Dateien:</span> <code>proxy/nginx.conf</code></p>
|
||||
<p><span class="kw">Commands noetig:</span> ja</p>
|
||||
<p><span class="kw">Platzierung:</span> <code>log_format</code> muss in den <code>http {}</code>-Block (sonst startet Nginx nicht). <code>access_log</code> darf in <code>http</code>, <code>server</code> oder <code>location</code>.</p>
|
||||
<pre><code>log_format workshop '$remote_addr - $request '
|
||||
'status=$status upstream=$upstream_addr '
|
||||
'rt=$request_time urt=$upstream_response_time';
|
||||
@@ -289,8 +291,9 @@ access_log /var/log/nginx/access.log workshop;</code></pre>
|
||||
}</code></pre>
|
||||
<p><span class="kw">Check:</span></p>
|
||||
<pre><code>for i in $(seq 1 8); do
|
||||
curl -s http://localhost:8080/service/a | grep -o "Target A2\|Target A"
|
||||
curl -s http://localhost:8080/service/a | grep -o "INSTANCE=[A-Za-z0-9]*"
|
||||
done</code></pre>
|
||||
<p><span class="kw">Marker:</span> Backend A/A2 enthalten unsichtbar <code><!-- INSTANCE=A --></code> bzw. <code>INSTANCE=A2</code>. <code>[A-Za-z0-9]*</code> matched das ganze Token (kein Prefix-Problem A vs. A2).</p>
|
||||
</details>
|
||||
|
||||
<details>
|
||||
@@ -298,6 +301,7 @@ done</code></pre>
|
||||
<p><span class="kw">Dateien:</span> <code>proxy/nginx.conf</code></p>
|
||||
<p><span class="kw">Commands noetig:</span> ja</p>
|
||||
<p><span class="kw">Abgrenzung zu #4:</span> #4 fuegt Schutz-Header hinzu, #8 entfernt unnoetige Upstream-Metadaten.</p>
|
||||
<p><span class="kw">Gut zu wissen:</span> <code>proxy_hide_header</code> ist kein <code>add_header</code> → es loest die Vererbungsfalle aus #4 nicht aus. Die Server-Header bleiben in dieser Location erhalten.</p>
|
||||
<pre><code>location /service/a {
|
||||
proxy_pass http://backend_a/;
|
||||
proxy_hide_header ETag;
|
||||
@@ -310,10 +314,14 @@ done</code></pre>
|
||||
<summary><span class="badge medium">Medium</span> 9) Debugging Challenge</summary>
|
||||
<p><span class="kw">Dateien:</span> <code>proxy/nginx.broken.conf</code>, <code>proxy/nginx.conf</code></p>
|
||||
<p><span class="kw">Commands noetig:</span> ja</p>
|
||||
<p><span class="kw">Ablauf:</span> Kopiere testweise <code>proxy/nginx.broken.conf</code> auf <code>proxy/nginx.conf</code>, behebe die Fehler und stelle danach die funktionierende Konfiguration wieder her.</p>
|
||||
<pre><code>cp proxy/nginx.broken.conf proxy/nginx.conf
|
||||
<p><span class="kw">Ablauf:</span> Zuerst die eigene Config sichern (diese Challenge ueberschreibt sie!), dann die kaputte aktivieren, Fehler beheben und am Ende die eigene Config wiederherstellen.</p>
|
||||
<pre><code>cp proxy/nginx.conf proxy/nginx.conf.bak # 1. eigene Config sichern
|
||||
cp proxy/nginx.broken.conf proxy/nginx.conf # 2. kaputte aktivieren
|
||||
make proxy-reload
|
||||
./scripts/compose.sh logs reverse-proxy</code></pre>
|
||||
./scripts/compose.sh logs reverse-proxy # 3. Fehler finden + fixen</code></pre>
|
||||
<p><span class="kw">Am Ende eigene Config zurueck:</span></p>
|
||||
<pre><code>cp proxy/nginx.conf.bak proxy/nginx.conf
|
||||
make proxy-reload</code></pre>
|
||||
<p><span class="kw">Konkrete Fehler und Fixes:</span></p>
|
||||
<ol>
|
||||
<li><span class="kw">Upstream-Mismatch:</span> <code>backend_a_typo</code> ist definiert, aber <code>backend_a</code> wird referenziert -> Namen angleichen.</li>
|
||||
@@ -340,15 +348,16 @@ cd certs/easyrsa
|
||||
./easyrsa init-pki
|
||||
./easyrsa build-ca nopass
|
||||
./easyrsa gen-req localhost nopass
|
||||
./easyrsa sign-req server localhost</code></pre>
|
||||
./easyrsa --subject-alt-name="DNS:localhost,IP:127.0.0.1" sign-req server localhost</code></pre>
|
||||
<p><span class="kw">Compose:</span></p>
|
||||
<pre><code>reverse-proxy:
|
||||
ports:
|
||||
- "8080:80"
|
||||
- "8443:443"
|
||||
- "${HTTP_PORT:-8080}:80"
|
||||
- "${HTTPS_PORT:-8443}:443"
|
||||
volumes:
|
||||
- ./certs/live:/etc/nginx/certs:ro,z</code></pre>
|
||||
<p><span class="kw">Wichtig:</span> Nicht die komplette PKI in den Container mounten. Nur Runtime-Zertifikat + Key bereitstellen.</p>
|
||||
<p><span class="kw">Deploy:</span> Port- und Volume-Aenderungen sind Compose-Aenderungen → <code>make redeploy</code> (nicht <code>make proxy-reload</code>), sonst greift der neue Port nicht.</p>
|
||||
<p><span class="kw">Nginx TLS-Pfade:</span> <code>ssl_certificate /etc/nginx/certs/localhost.crt;</code> und <code>ssl_certificate_key /etc/nginx/certs/localhost.key;</code></p>
|
||||
<p><span class="kw">Check:</span> <code>curl https://localhost:8443/service/a</code> (ohne <code>-k</code> nach CA-Import)</p>
|
||||
</details>
|
||||
@@ -381,7 +390,7 @@ cd certs/easyrsa
|
||||
<p><span class="kw">Commands noetig:</span> ja</p>
|
||||
<pre><code>ssl_protocols TLSv1.2 TLSv1.3;
|
||||
ssl_prefer_server_ciphers on;
|
||||
add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" always;</code></pre>
|
||||
add_header Strict-Transport-Security "max-age=3600; includeSubDomains" always;</code></pre>
|
||||
<p><span class="kw">Check:</span></p>
|
||||
<pre><code>curl -I https://localhost:8443/service/a
|
||||
openssl s_client -connect localhost:8443 -servername localhost</code></pre>
|
||||
|
||||
Reference in New Issue
Block a user