79a13f0919
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>
171 lines
4.2 KiB
Markdown
171 lines
4.2 KiB
Markdown
# Easy-RSA Hint Card (optional)
|
|
|
|
Diese Hinweise koennen Teams nutzen, wenn sie bei der HTTPS-Challenge feststecken.
|
|
|
|
## 1) Easy-RSA installieren (WSL/Linux)
|
|
|
|
Fedora:
|
|
|
|
```bash
|
|
sudo dnf install -y easy-rsa openssl
|
|
```
|
|
|
|
Ubuntu/WSL:
|
|
|
|
```bash
|
|
sudo apt update
|
|
sudo apt install -y easy-rsa openssl
|
|
```
|
|
|
|
## 2) PKI vorbereiten
|
|
|
|
```bash
|
|
mkdir -p certs/easyrsa
|
|
cp -r /usr/share/easy-rsa/* certs/easyrsa/
|
|
cd certs/easyrsa
|
|
./easyrsa init-pki
|
|
```
|
|
|
|
## 3) CA erstellen
|
|
|
|
```bash
|
|
./easyrsa build-ca nopass
|
|
```
|
|
|
|
## 4) Server-Zertifikat fuer localhost
|
|
|
|
```bash
|
|
./easyrsa gen-req localhost nopass
|
|
./easyrsa --subject-alt-name="DNS:localhost,IP:127.0.0.1" sign-req server localhost
|
|
```
|
|
|
|
Wichtig: Das `--subject-alt-name` ist nicht optional. Moderne Clients (curl, Browser) ignorieren den CN und pruefen ausschliesslich den SAN. Ohne SAN scheitert `curl https://localhost:8443` trotz korrekt importierter CA mit `no alternative certificate subject name matches target host name`.
|
|
|
|
## 5) Nur Runtime-Zertifikate bereitstellen (nicht komplette PKI mounten)
|
|
|
|
Nutze fuer den Container nur die benoetigten Laufzeitdateien:
|
|
|
|
- `localhost.crt` (Server-Zertifikat)
|
|
- `localhost.key` (Server-Private-Key)
|
|
|
|
Beispiel:
|
|
|
|
```bash
|
|
mkdir -p ../../live
|
|
cp pki/issued/localhost.crt ../../live/
|
|
cp pki/private/localhost.key ../../live/
|
|
chmod 600 ../../live/localhost.key
|
|
```
|
|
|
|
Warum nicht die ganze PKI mounten?
|
|
|
|
- In `pki/` liegen CA-relevante Dateien.
|
|
- Runtime-Container sollen keine unnoetigen PKI/CA-Dateien sehen.
|
|
- Prinzip: minimal noetige Secrets in Runtime.
|
|
|
|
Danach in `proxy/nginx.conf` TLS aktivieren und in `docker-compose.yml` Port `443` + Cert-Volume mappen.
|
|
|
|
### Compose-Mindestbeispiel
|
|
|
|
```yaml
|
|
services:
|
|
reverse-proxy:
|
|
ports:
|
|
- "${HTTP_PORT:-8080}:80"
|
|
- "${HTTPS_PORT:-8443}:443"
|
|
volumes:
|
|
- ./proxy/nginx.conf:/etc/nginx/nginx.conf:ro,z
|
|
- ./proxy/html:/usr/share/nginx/html:ro,z
|
|
- ./certs/live:/etc/nginx/certs:ro,z
|
|
```
|
|
|
|
### Nginx-Mindestbeispiel (HTTP + HTTPS)
|
|
|
|
```nginx
|
|
server {
|
|
listen 80;
|
|
server_name _;
|
|
|
|
location = /healthz {
|
|
default_type text/plain;
|
|
return 200 "ok\n";
|
|
}
|
|
|
|
location / {
|
|
return 301 https://$host:8443$request_uri;
|
|
}
|
|
}
|
|
|
|
server {
|
|
listen 443 ssl;
|
|
server_name localhost;
|
|
|
|
ssl_certificate /etc/nginx/certs/localhost.crt;
|
|
ssl_certificate_key /etc/nginx/certs/localhost.key;
|
|
ssl_protocols TLSv1.2 TLSv1.3;
|
|
add_header Strict-Transport-Security "max-age=3600; includeSubDomains" always;
|
|
|
|
add_header X-Content-Type-Options "nosniff" always;
|
|
add_header X-Frame-Options "DENY" always;
|
|
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;
|
|
|
|
location /service/a {
|
|
proxy_pass http://backend_a/;
|
|
}
|
|
|
|
location /service/b {
|
|
proxy_pass http://backend_b/;
|
|
}
|
|
}
|
|
```
|
|
|
|
## 6) Root-CA importieren (Trust Store)
|
|
|
|
Wichtig: In den Trust-Store **der Umgebung importieren, in der du testest**.
|
|
- Test mit `curl` aus **WSL** (der Standardweg im Workshop): in den **Linux**-Trust-Store importieren -> Ubuntu/Debian-Befehle unten.
|
|
- Test im **Windows-Browser**: zusaetzlich der Windows-Import (`certutil`).
|
|
|
|
Fedora:
|
|
|
|
```bash
|
|
sudo cp certs/easyrsa/pki/ca.crt /etc/pki/ca-trust/source/anchors/htl-workshop-root-ca.crt
|
|
sudo update-ca-trust
|
|
```
|
|
|
|
Ubuntu/Debian:
|
|
|
|
```bash
|
|
sudo cp certs/easyrsa/pki/ca.crt /usr/local/share/ca-certificates/htl-workshop-root-ca.crt
|
|
sudo update-ca-certificates
|
|
```
|
|
|
|
Windows (PowerShell als Admin, optional):
|
|
|
|
```powershell
|
|
certutil -addstore -f Root C:\path\to\ca.crt
|
|
```
|
|
|
|
## 7) Test ohne -k
|
|
|
|
Nach Import sollte HTTPS ohne Insecure-Flag funktionieren:
|
|
|
|
```bash
|
|
curl https://localhost:8443/service/a
|
|
```
|
|
|
|
Falls CA nicht global importiert ist:
|
|
|
|
```bash
|
|
curl --cacert certs/easyrsa/pki/ca.crt https://localhost:8443/service/a
|
|
```
|
|
|
|
## 8) Typische Fehlerbilder
|
|
|
|
- `curl: (60) SSL certificate problem` -> Root-CA nicht importiert oder falsche CA.
|
|
- Browser war offen waehrend CA-Import -> Browser neu starten.
|
|
- `permission denied` beim Nginx-Config-Mount (Fedora/SELinux) -> Volumes mit `:z` mounten.
|
|
- Zertifikat ohne `localhost` -> SAN/CN passt nicht zum Hostnamen.
|