Zum Hauptinhalt springen

Reverse-Proxy und TLS

Die App lauscht per einfachem HTTP auf Port 3000. Schalten Sie einen Reverse-Proxy davor, der TLS (HTTPS) auf Ihrer Domain terminiert. Geben Sie Port 3000 nicht direkt ins Internet frei. Erst der Proxy macht Client-Adressen vertrauenswürdig.

Was jeder Proxy tun muss:

  1. HTTPS auf dem Host aus APP_URL ausliefern und an http://127.0.0.1:3000 weiterleiten.
  2. Host und die Header X-Forwarded-Proto / X-Forwarded-Host weitergeben.
  3. Die Adresse des Clients an X-Forwarded-For anhängen (und den Header nicht durch etwas ersetzen, das der Client geschickt hat).
  4. Request-Bodys erlauben, die etwas größer sind als die Chunk-Größe für Uploads (Standard 8 MB).
  5. Lang laufende Antworten für Downloads und Exporte erlauben (keine kurzen Read-Timeouts).

Caddy​

Caddy holt und erneuert Zertifikate selbst und setzt die Forwarding-Header standardmäßig.

flow.example.com {
encode zstd gzip
reverse_proxy 127.0.0.1:3000
}

Caddy hat standardmäßig kein Limit für Request-Bodys.

nginx​

server {
listen 443 ssl;
http2 on;
server_name flow.example.com;

ssl_certificate /etc/letsencrypt/live/flow.example.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/flow.example.com/privkey.pem;

# uploads arrive in chunks (default 8 MB): allow a bit more, and stream them through
client_max_body_size 16m;
proxy_request_buffering off;

location / {
proxy_pass http://127.0.0.1:3000;
proxy_http_version 1.1;
proxy_set_header Host $host;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header X-Forwarded-Host $host;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_read_timeout 300s;
}
}

server {
listen 80;
server_name flow.example.com;
return 301 https://$host$request_uri;
}
Das Standard-Body-Limit von nginx ist 1 MB

Ohne client_max_body_size schlagen Uploads fehl, sobald ein Chunk größer als 1 MB ist. Wenn Sie das Chunking unter Admin → Allgemein → Uploads ausschalten, muss das Limit über der größten Datei liegen, die Sie erlauben.

Traefik​

Mit dem Docker-Provider fügen Sie dem Service app Labels hinzu (und entfernen seine ports:-Zuordnung):

labels:
- traefik.enable=true
- traefik.http.routers.sol2flow.rule=Host(`flow.example.com`)
- traefik.http.routers.sol2flow.entrypoints=websecure
- traefik.http.routers.sol2flow.tls.certresolver=letsencrypt
- traefik.http.services.sol2flow.loadbalancer.server.port=3000

Traefik hängt an X-Forwarded-For an und hat standardmäßig kein Body-Limit.

Client-IP-Adressen​

sol2flow verwendet die IP-Adresse des Clients für die Ratenbegrenzung (zum Beispiel gegen das Erraten von Passwörtern) und zeigt sie in der Liste der Sitzungen. Jeder Proxy hängt die Adresse, von der er die Anfrage erhalten hat, an X-Forwarded-For an; sol2flow nimmt den Eintrag, der TRUST_PROXY_HOPS Stellen von rechts steht. Einträge weiter links stammen vom Client und können gefälscht sein.

SetupTRUST_PROXY_HOPS
Ein Proxy (Caddy, nginx oder Traefik) vor der App1 (Standard)
Ein CDN oder Load Balancer plus Ihr eigener Proxy2

Ist der Wert zu niedrig, scheinen alle von der Adresse Ihres Proxys zu kommen und teilen sich ein gemeinsames Limit. Ist er zu hoch, können Clients ihre eigene Adresse bestimmen.

Unterpfade​

sol2flow muss im Root seines eigenen Hostnamens laufen (https://flow.example.com/), nicht unter einem Pfad wie https://example.com/flow/.

Nach einem Domainwechsel​

APP_URL muss der neuen Adresse entsprechen. Zwei Dinge sind an den Hostnamen gebunden:

  • Passkeys funktionieren nur auf dem Host, für den sie erstellt wurden: Nach einem Domainwechsel müssen Personen sie neu hinzufügen (anmelden können sie sich weiterhin mit Passwort oder Single Sign-on).
  • Single Sign-on: Aktualisieren Sie die bei jedem Identity-Provider registrierte Redirect-URI (angezeigt unter Admin → Authentifizierung).