Saltar al contenido principal

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:

  1. Servir HTTPS en el host de APP_URL y reenviar a http://127.0.0.1:3000.
  2. Transmitir Host y las cabeceras X-Forwarded-Proto / X-Forwarded-Host.
  3. Añadir la dirección del cliente a X-Forwarded-For (no sustituirla por algo que haya enviado el cliente).
  4. Permitir cuerpos de petición algo mayores que el tamaño de bloque de las subidas (8 MB por defecto).
  5. 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;
}
El límite de cuerpo por defecto de nginx es 1 MB

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ónTRUST_PROXY_HOPS
Un proxy (Caddy, nginx o Traefik) delante de la app1 (por defecto)
Un CDN o balanceador de carga más tu propio proxy2

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).