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

191 lines
7.3 KiB

# Con Nginx Proxy Manager delante
[Nginx Proxy Manager](https://nginxproxymanager.com/) 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:
```sh
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:
```sh
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`:
```sh
sudo systemctl restart senzapaura
```
## 5. Y antes que todo lo anterior
Que el servicio exista y esté arrancado, que es lo que hoy falta:
```sh
sudo bash /var/www/senzapaura/despliegue/instalar.sh
```
Comprobación desde cualquier máquina de la red, sin pasar por el proxy:
```sh
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:
```sh
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:
```sh
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:
```sh
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.