# HTTPS-Erkennung beim Praxisexport / HTTPS proxy setup ## Ursache und Korrektur Der Browser ruft die Anwendung über HTTPS auf. Ein äußerer Reverse Proxy beendet TLS und leitet intern über HTTP weiter. Die bisherige Frontend-Nginx-Konfiguration ersetzte dessen `X-Forwarded-Proto: https` durch `$scheme`, also `http`. Rails lehnte den Export deshalb mit HTTP 426 ab. Das neue Frontend übernimmt einen **einzelnen, exakt passenden** `X-Forwarded-Proto`-Wert nur vom ausdrücklich konfigurierten unmittelbaren Proxy. Ohne passenden Absender bleibt das tatsächlich am internen Nginx verwendete Protokoll maßgeblich. Alternative Protokoll-Header werden entfernt. Die Rails-HTTPS-Prüfung bleibt unverändert aktiv. `APP_PROTOCOL=https` allein betrifft URL-Erzeugung und behebt die Anfrageerkennung nicht. ## Einrichtung auf dem Server 1. Die vorhandene `.env` und Schlüssel behalten. Den äußersten Proxy so konfigurieren, dass er HTTP nach HTTPS umleitet und den Header **überschreibt**, statt einen vom Browser gelieferten Wert durchzureichen. Bei Nginx im HTTPS-Serverblock: ```nginx proxy_set_header Host $host; proxy_set_header X-Forwarded-Proto $scheme; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_pass http://127.0.0.1:13131; ``` 2. In der bestehenden `.env` `TRUSTED_TLS_PROXY_CIDR` auf die Quell-IP des unmittelbaren Proxys setzen, **wie sie im Frontend-Container ankommt**. Diese lässt sich mit `docker compose logs --tail=30 frontend` bei einem eigenen Aufruf prüfen. Hinter Docker kann es die Bridge-Gateway-IP sein; diese nicht raten. IPv4 mit `/32`, IPv6 mit `/128`; ein größeres Netz nur, wenn ausschließlich vertrauenswürdige Proxys darin liegen. Niemals `0.0.0.0/0` oder `::/0`. Vorgabe ist `127.0.0.1/32`; das passt nicht automatisch zu Docker-Bridge-Netzen. ```dotenv # Beispielstruktur, IP durch den tatsächlich geprüften Proxy-Absender ersetzen: TRUSTED_TLS_PROXY_CIDR=192.0.2.10/32 ASSUME_SSL=false API_BIND_ADDRESS=127.0.0.1 FRONTEND_BIND_ADDRESS=127.0.0.1 ``` Die neue Compose-Datei veröffentlicht API und Frontend standardmäßig nur auf Loopback. Für einen Proxy in einem anderen Container ein gemeinsames privates Docker-Netz und `frontend:80` verwenden; für einen separaten Proxy-Server eine private Bind-Adresse und Firewall-Freigabe ausschließlich für diesen Proxy konfigurieren. Nicht blind auf alle Schnittstellen umstellen. Direkten öffentlichen HTTP-Zugriff auf API und Frontend ausschließen. 3. Im Verzeichnis `praktikumsverwaltung` bauen und Container neu erstellen: ```sh docker compose up -d --build api frontend docker compose exec frontend nginx -t ``` Ein bloßes `docker compose restart` übernimmt geänderte Umgebungsvariablen nicht. Es gibt für dieses Patch-Release keine neue Datenbankmigration. 4. Anwendung über `https://praktikum.marzell.net` öffnen und den Export mit einem kleinen Testzeitraum erneut ausführen. Erwartet: HTTP 200 mit verschlüsselter `.pcmtransfer`-Datei. Ohne gültige Anmeldung bleibt der Zugriff gesperrt. Die Browser-URL allein beweist nicht, dass der interne Header korrekt ist. ## Soforthilfe für den bisherigen Build Der bisherige Build unterstützt bereits `ASSUME_SSL=true`. **Nur wenn sämtliche externen Anfragen ausschließlich über einen vertrauenswürdigen HTTPS-Proxy eintreffen und die internen HTTP-Ports nicht öffentlich erreichbar sind**, kann in der bestehenden `.env` dieser Wert gesetzt und `docker compose up -d --force-recreate api` ausgeführt werden. Rails behandelt dann alle Anfragen als HTTPS. Diese Annahme ist ungeeignet bei gemischtem HTTP-/HTTPS-Zugriff. Die neue, absendergebundene Headerweitergabe mit `ASSUME_SSL=false` ist vorzuziehen. ## Test und Rollback `python3 test/proxy_transport_test.py /path/to/nginx` prüft 14 Kombinationen gegen einen lokalen Echo-Upstream: vertrauenswürdiges HTTPS/HTTP, fehlende und ungültige Header sowie gefälschte HTTPS-Behauptungen von anderen Absendern. Es werden keine Produktivdaten verwendet. Ein durchgehender Exporttest mit der realen TLS- und Rails-Installation ist zusätzlich erforderlich. Rollback: zuvor gesicherte Anwendungsversion und passende Compose-Konfiguration wiederherstellen, Images neu bauen oder zuvor gesicherte Images verwenden und Container neu erstellen. Die eigenen `.env`-Werte und Datenbankvolumes behalten. HTTPS-Schutz nicht entfernen. Keine Datenbankrückmigration nötig. ## English The internal Nginx previously overwrote the TLS proxy's HTTPS scheme with HTTP, causing Rails to reject the export with 426. Configure `TRUSTED_TLS_PROXY_CIDR` with the verified immediate proxy address as seen inside the frontend container. Only this sender may assert an exact `X-Forwarded-Proto: https`; other scheme headers are removed. Keep `ASSUME_SSL=false`, enforce HTTPS at the public edge and prevent direct public access to internal ports. Ports now bind to loopback by default; container or remote proxies need an explicitly configured private network path. Rebuild/recreate `api` and `frontend`, validate Nginx and test a small encrypted export. No new migration. The previous build's `ASSUME_SSL=true` workaround is safe only behind an exclusively HTTPS, trusted, isolated ingress. Never remove the export's HTTPS check.