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

148 lines
5.4 KiB

# Con Nginx Proxy Manager delante
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 NPM 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 NPM:
```
80 TCP → <IP de NPM>:80
443 TCP → <IP de NPM>:443
```
El 80 hace falta aunque todo vaya por HTTPS: es por donde Let's Encrypt hace su
comprobación.
## 3. El proxy, en NPM
**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: NPM 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
NPM, y es ahí donde hay que mirar:
```sh
journalctl -u senzapaura -n 50 --no-pager
```
## Si el operador bloquea el 80 y el 443
Avatel es fibra residencial, y ahí es habitual encontrarse los puertos de
entrada cerrados o direcciones compartidas entre varios clientes (CGNAT). El
síntoma es claro: el DNS resuelve bien, desde dentro de casa se ve, y desde
fuera —desde datos del móvil, por ejemplo— no responde nada.
Si pasa, hay dos salidas: pedirles 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. Con túnel, el paso 2 sobra y el certificado lo
pone Cloudflare.

Powered by TurnKey Linux.