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:
- HTTPS auf dem Host aus
APP_URLausliefern und anhttp://127.0.0.1:3000weiterleiten. Hostund die HeaderX-Forwarded-Proto/X-Forwarded-Hostweitergeben.- Die Adresse des Clients an
X-Forwarded-Foranhängen (und den Header nicht durch etwas ersetzen, das der Client geschickt hat). - Request-Bodys erlauben, die etwas größer sind als die Chunk-Größe für Uploads (Standard 8 MB).
- 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;
}
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.
| Setup | TRUST_PROXY_HOPS |
|---|---|
| Ein Proxy (Caddy, nginx oder Traefik) vor der App | 1 (Standard) |
| Ein CDN oder Load Balancer plus Ihr eigener Proxy | 2 |
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).