5.2 KiB
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
-
Die vorhandene
.envund 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: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; -
In der bestehenden
.envTRUSTED_TLS_PROXY_CIDRauf die Quell-IP des unmittelbaren Proxys setzen, wie sie im Frontend-Container ankommt. Diese lässt sich mitdocker compose logs --tail=30 frontendbei 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. Niemals0.0.0.0/0oder::/0. Vorgabe ist127.0.0.1/32; das passt nicht automatisch zu Docker-Bridge-Netzen.# 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.1Die 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:80verwenden; 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. -
Im Verzeichnis
praktikumsverwaltungbauen und Container neu erstellen:docker compose up -d --build api frontend docker compose exec frontend nginx -tEin bloßes
docker compose restartübernimmt geänderte Umgebungsvariablen nicht. Es gibt für dieses Patch-Release keine neue Datenbankmigration. -
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.