Proxy inverso y TLS
La app escucha en HTTP sin cifrar, en el puerto 3000. Pon delante un proxy inverso que termine TLS (HTTPS) en tu dominio. No expongas el puerto 3000 directamente a internet: el proxy es lo que hace fiables las direcciones de los clientes.
Lo que debe hacer cualquier proxy:
- Servir HTTPS en el host de
APP_URLy reenviar ahttp://127.0.0.1:3000. - Transmitir
Hosty las cabecerasX-Forwarded-Proto/X-Forwarded-Host. - Añadir la dirección del cliente a
X-Forwarded-For(no sustituirla por algo que haya enviado el cliente). - Permitir cuerpos de petición algo mayores que el tamaño de bloque de las subidas (8 MB por defecto).
- Permitir respuestas de larga duración para descargas y exportaciones (sin tiempos de lectura cortos).
Caddy
Caddy obtiene y renueva los certificados por sí mismo y define las cabeceras de reenvío por defecto.
flow.example.com {
encode zstd gzip
reverse_proxy 127.0.0.1:3000
}
Caddy no tiene límite de tamaño del cuerpo de la petición por defecto.
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;
}
Sin client_max_body_size, las subidas fallan en cuanto un bloque supera 1 MB. Si desactivas la subida por bloques en
Administración → General → Subidas, el límite debe estar por encima del archivo más grande que permitas.
Traefik
Con el proveedor de Docker, añade labels al servicio app (y quita su mapeo ports:):
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 añade la dirección a X-Forwarded-For y no tiene límite de cuerpo por defecto.
Direcciones IP de los clientes
sol2flow usa la dirección IP del cliente para los límites de frecuencia (por ejemplo, contra intentos de adivinar contraseñas) y la muestra en la
lista de sesiones. Cada proxy añade a X-Forwarded-For la dirección desde la que recibió la petición; sol2flow toma la
entrada que está TRUST_PROXY_HOPS posiciones desde la derecha. Las entradas más a la izquierda vienen del cliente y se pueden falsificar.
| Configuración | TRUST_PROXY_HOPS |
|---|---|
| Un proxy (Caddy, nginx o Traefik) delante de la app | 1 (por defecto) |
| Un CDN o balanceador de carga más tu propio proxy | 2 |
Si el valor es demasiado bajo, parece que todo el mundo viene de la dirección de tu proxy y todos comparten un mismo límite de frecuencia. Si es demasiado alto, los clientes pueden elegir su propia dirección.
Subrutas
sol2flow debe funcionar en la raíz de su propio nombre de host (https://flow.example.com/), no bajo una ruta como
https://example.com/flow/.
Después de cambiar el dominio
APP_URL debe coincidir con la nueva dirección. Hay dos cosas vinculadas al nombre de host:
- Las llaves de acceso solo funcionan en el host para el que se crearon: las personas tienen que añadirlas de nuevo tras un cambio de dominio (pueden seguir iniciando sesión con su contraseña o con el inicio de sesión único).
- Inicio de sesión único: actualiza la URI de redirección registrada en cada proveedor de identidad (se muestra en Administración → Autenticación).