Ir al contenido

HTTPS y proxy inverso

Ver en Markdown

El contenedor web escucha en HTTP sin cifrar (puerto 8080 por defecto). Pon delante un proxy inverso que termine el TLS. Todo pasa por web: el proxy solo necesita un destino y nunca habla directamente con api ni con gateway.

Ruta Tráfico Requisito del proxy
/ Interfaz estática Nada especial.
/api/ API REST y eventos del servidor (progreso en directo de altas y trabajos) No guardar las respuestas en búfer. Permitir conexiones inactivas de al menos 1 hora.
/gateway/ WebSocket de la terminal web Pasar las cabeceras Upgrade y Connection. Permitir conexiones de hasta 9 horas (el gateway cierra las sesiones inactivas a los 15 minutos y cualquier sesión a las 8 horas).

Además:

  • Pon en INFRAWARD_PUBLIC_URL (en .env) la URL pública exacta, por ejemplo https://infraward.example.com, y ejecuta docker compose up -d después de cambiarla. La API compara con ella la cabecera Origin de las escrituras y el comando de alta se construye a partir de ella.
  • Publica web solo en la interfaz de loopback (INFRAWARD_HTTP_PORT=127.0.0.1:8080) cuando el proxy esté en el mismo host, para que el puerto 8080 no sea accesible desde la red.
  • Envía X-Forwarded-For y X-Forwarded-Proto, y pon en INFRAWARD_TRUSTED_PROXY (en .env) la dirección IP (o CIDR) del proxy tal como la ve el contenedor web. El contenedor web solo se cree esas cabeceras si llegan desde esa dirección, y pasa a la API y al gateway una única IP del cliente. La usan el registro de auditoría, los límites de intentos de login y las sesiones de la terminal. Mientras no la definas, registran la IP del proxy. Consulta Averigua la dirección del proxy.
  • No escribas en el log de accesos del proxy las peticiones a /api/enroll/: el token de alta, de un solo uso, viaja en la ruta. El contenedor web ya las excluye de su propio log.
  • El contenedor web ya envía X-Frame-Options, Content-Security-Policy: frame-ancestors 'none', Strict-Transport-Security, X-Content-Type-Options y Referrer-Policy. No las vuelvas a añadir en el proxy.

Caddy obtiene y renueva el certificado automáticamente y gestiona la actualización a WebSocket sin ajustes adicionales.

/etc/caddy/Caddyfile
infraward.example.com {
# Caddy no escribe logs de accesos salvo que actives la directiva log.
# Si lo haces, excluye /api/enroll/*: el token de alta va en la ruta.
reverse_proxy 127.0.0.1:8080 {
# Eventos del servidor: envía cada evento en cuanto llega.
flush_interval -1
}
}

El valor de INFRAWARD_TRUSTED_PROXY es la dirección desde la que llegan las conexiones dentro del contenedor, que no siempre es la que esperas:

  • Proxy en el mismo host (Caddy o nginx conectando a 127.0.0.1:8080): con Docker suele ser la puerta de enlace de la red de Compose, no 127.0.0.1.
  • Proxy en un contenedor (Traefik): la IP del contenedor del proxy en la red que comparte con web, o el CIDR de esa red si solo hay contenedores de proxy conectados a ella.

Para averiguarla, abre InfraWard a través del proxy y lee la dirección de origen de las peticiones en el log de web:

Ventana de terminal
docker compose logs --tail 5 web

Defínela en .env y vuelve a crear web:

.env
INFRAWARD_TRUSTED_PROXY=172.18.0.1
Ventana de terminal
docker compose up -d web

A partir de ahí, el mismo log muestra las IP reales de los clientes. El valor por defecto (127.0.0.1) no confía en ningún proxy. No uses nunca un rango desde el que los clientes puedan conectarse directamente: cualquiera dentro de él podría elegir la IP que aparece en la auditoría.

  1. Abre https://infraward.example.com y entra. Si la página de login carga pero al entrar vuelves a ella, el navegador está descartando la cookie de sesión: comprueba que el sitio se sirve por HTTPS.
  2. Da de alta un servidor o lanza un escaneo y mira la página de progreso. Si los pasos solo se actualizan al recargar, el proxy está guardando /api/ en búfer.
  3. Abre una terminal en un servidor con acceso de administración. Si muestra enseguida Se ha perdido la conexión con el gateway, el proxy no está reenviando la actualización a WebSocket en /gateway/.
  4. Busca tu acceso en Ajustes → Auditoría. Si muestra la IP del proxy en lugar de la tuya, INFRAWARD_TRUSTED_PROXY no está definida o no coincide con el proxy.