You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
senzapaura_es/despliegue/con-proxy-manager.md

7.3 KiB

Con Nginx Proxy Manager delante

Nginx Proxy Manager es un Nginx con panel web: en vez de escribir archivos de configuración a mano, se dan de alta los dominios desde un formulario y él pide los certificados de Let's Encrypt y los renueva solo. Se suele montar como contenedor y hace de puerta única para todo lo que se publica desde una red.

Ojo con la abreviatura. En este proyecto npm es el gestor de paquetes de Node, el de npm run dev. No tienen nada que ver, así que aquí el proxy se escribe siempre con el nombre entero.

Este es el montaje cuando quien recibe del exterior no es el Nginx de la propia máquina, sino un Nginx Proxy Manager en otro sitio de la red:

internet → router (80, 443) → Nginx Proxy Manager → 192.168.18.171:3000 → Node

Con Proxy Manager delante, el Nginx de la máquina de la web sobra. Se puede dejar instalado sin más, pero no tiene que estar en medio: adapter-node ya sirve los estáticos con sus cabeceras de caché correctas, y meter un segundo proxy solo añade un salto y complica el recuento de direcciones IP, que sí importa (ver más abajo).

1. DNS, en Hostinger

Hoy el dominio apunta al alojamiento del registrador. Hay que cambiar dos registros y no tocar los demás:

Acción Tipo Nombre Contenido
Borrar ALIAS @ senzapaura.es.cdn.hstgr.net
Crear A @ 89.46.247.16
Borrar CNAME www www.senzapaura.es.cdn.hstgr.net
Crear A www 89.46.247.16

Lo que NO se toca, bajo ningún concepto:

  • Los dos MX a mx1/mx2.titan.email — son el correo del dominio.
  • El TXT de @ con v=spf1 include:spf.titan.email ~all — sin él, el correo que se envía desde el dominio acaba en spam.
  • El TXT de titan1._domainkey — la firma DKIM de ese mismo correo.

Borrar cualquiera de esos tres deja el correo del dominio inservible, y el síntoma aparece días después, cuando alguien no recibe algo.

El registro A de ftp (89.116.53.14) es del alojamiento antiguo. No estorba; se puede borrar cuando se abandone del todo.

Con TTL de 300 segundos el cambio se ve en cinco minutos. Comprobación:

dig +short senzapaura.es @1.1.1.1        # tiene que decir 89.46.247.16
dig +short www.senzapaura.es @1.1.1.1

2. Router

Redirigir al equipo donde corre Proxy Manager:

80  TCP → <IP de Proxy Manager>:80
443 TCP → <IP de Proxy Manager>:443

El 80 hace falta aunque todo vaya por HTTPS: es por donde Let's Encrypt hace su comprobación.

3. El proxy, en Proxy Manager

Hosts → Proxy Hosts → Add Proxy Host

Campo Valor
Domain Names senzapaura.es, www.senzapaura.es
Scheme http
Forward Hostname / IP 192.168.18.171
Forward Port 3000
Cache Assets apagado
Block Common Exploits encendido
Websockets Support apagado

«Cache Assets» apagado a propósito: SvelteKit ya manda Cache-Control bien puesto —eterno para lo que lleva huella en el nombre, corto para lo demás—, y una caché por encima que no distinga las dos cosas acaba sirviendo una versión vieja de la web después de un despliegue.

En la pestaña SSL: «Request a new SSL Certificate», con Force SSL y HTTP/2 encendidos.

En Advanced, nada. En particular, no hace falta tocar las cabeceras: Proxy Manager ya manda X-Forwarded-For, X-Forwarded-Proto y X-Forwarded-Host.

4. El .env del servidor

Dos variables, y las dos importan:

ORIGIN=https://senzapaura.es
ADDRESS_HEADER=X-Forwarded-For
XFF_DEPTH=1

ORIGIN es el error más fácil de cometer y el más desconcertante: sin él, SvelteKit rechaza todos los formularios con un 403 por comprobación de origen. La web se ve perfectamente y nada funciona.

ADDRESS_HEADER y XFF_DEPTH son menos evidentes y hacen falta igual. Sin ellos, getClientAddress() devuelve la IP del proxy, no la de quien pide. Y esa función es la que usa el limitador del formulario de acceso: con todas las peticiones pareciendo venir de la misma dirección, el límite salta con una sola persona insistiendo y nadie más puede pedir su código.

XFF_DEPTH=1 porque hay un proxy entre internet y Node. Si algún día se mete otro delante —un Cloudflare, por ejemplo—, hay que subirlo a 2: la cuenta es desde el final de la cadena hacia atrás, y equivocarla deja la IP a merced de quien mande su propia cabecera.

Después de tocar el .env:

sudo systemctl restart senzapaura

5. Y antes que todo lo anterior

Que el servicio exista y esté arrancado, que es lo que hoy falta:

sudo bash /var/www/senzapaura/despliegue/instalar.sh

Comprobación desde cualquier máquina de la red, sin pasar por el proxy:

curl -I http://192.168.18.171:3000/

Si eso no contesta 200, el problema está en el servidor y no en el DNS ni en Proxy Manager, y es ahí donde hay que mirar:

journalctl -u senzapaura -n 50 --no-pager

El portón de «muy pronto»

Mientras la web no esté abierta al público, en el .env del servidor:

PROXIMAMENTE=1
PROXIMAMENTE_PERMITIDAS=89.46.247.16

Esa dirección es la IP pública fija de la línea —contratada como fija, no depende de renovaciones—, así que la lista no hay que revisarla.

Y ahí está lo que despista: hace falta ponerla aunque estés en casa.

La regla «la red local entra siempre» no sirve para esto. Cuando desde la propia red se pide senzapaura.es, el nombre resuelve a la IP pública, la petición sale al router y vuelve, y el router la reescribe: al proxy le llega como 89.46.247.16, no como 192.168.18.x. Es NAT de retorno, y lo hacen casi todos los routers domésticos. Sin la IP pública en la lista, verías tu propia página de espera en tu propio ordenador y no habría forma de entender por qué.

Se comprueba en el registro del proxy:

tail -3 /data/logs/proxy-host-5_access.log     # [Client 89.46.247.16]

De paso, algo que conviene saber que funciona: mandar a mano un X-Forwarded-For: 8.8.8.8 no abre el portón. El proxy añade la dirección real al final de la cabecera y XFF_DEPTH=1 es la que se lee. Por eso el número tiene que ser exacto: si algún día se mete otro proxy delante y no se sube a 2, la dirección pasa a ser la que mande quien pide.

Si el operador bloquea el 80 y el 443

No es el caso aquí: la línea tiene IP pública fija contratada y los puertos 80 y 443 llegan. Queda escrito por si algún día se mueve el montaje a otra conexión, porque el síntoma es de los que se confunden con un fallo de configuración: el DNS resuelve bien, desde dentro de casa se ve, y desde fuera —desde los datos del móvil, por ejemplo— no responde nada.

Si eso pasara, hay dos salidas: pedir al operador la IP pública sin filtrar, o montar un túnel —Cloudflare Tunnel es lo más directo— que sale desde la red hacia fuera y no necesita ningún puerto abierto.

Powered by TurnKey Linux.