You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

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

  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:

    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.

    # 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:

    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.