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.
148 lines
5.4 KiB
148 lines
5.4 KiB
|
4 weeks ago
|
# 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.
|