Cuenta de externas, arreglos de seguridad, títulos arriba y despliegue
- Rol «externas» para la asamblea de externas: pide sin cupo, siempre con el colectivo de fuera y su contacto, y sus solicitudes salen en naranja hasta que la asamblea de la Enre las confirma. - /pedir/ explica en una línea que los colectivos externos piden fecha en la asamblea de externas, los lunes de 19:00 a 20:00. - Seguridad: argon2 limitado a dos cálculos a la vez y el intento se cuenta antes de calcular (60 accesos simultáneos llevaban el proceso a 3,8 GB); bloqueo por cuenta a 20 fallos para que no se pueda dejar fuera a la asamblea; avisos por sesión en vez de por URL; sig sin «..»; eventos de 31 días como mucho; parámetros de argon2 acotados. - Títulos pegados arriba en todas las páginas; la franja de la enredadera recupera ese alto para seguir llenando la pantalla. - despliegue/: instalar.sh, cuenta.sh, servicio de systemd con el proceso encerrado, fragmento de nginx que además deja de servir .git y las notas internas, y configuración de ejemplo. Ninguna contraseña en el repositorio.
This commit is contained in:
parent
ce3127baff
commit
7d5dbeec60
24 changed files with 606 additions and 96 deletions
69
despliegue/README.md
Normal file
69
despliegue/README.md
Normal file
|
|
@ -0,0 +1,69 @@
|
|||
# Despliegue de /pedir/
|
||||
|
||||
El gestor de reservas es un programa en Go que escucha en `127.0.0.1:8090`.
|
||||
nginx le pasa `/pedir/` y sigue sirviendo el resto de la web como hasta ahora.
|
||||
|
||||
| Qué | Dónde |
|
||||
|---|---|
|
||||
| programa y plantillas | `/opt/enrecal/` |
|
||||
| configuración | `/etc/enrecal/config.json` |
|
||||
| datos (registro, solo crece) | `/var/lib/enrecal/registro.jsonl` |
|
||||
| accesos, para fail2ban | `/var/log/enrecal/auth.log` |
|
||||
| servicio | `enrecal.service`, usuario `enrecal` |
|
||||
|
||||
## Primera vez
|
||||
|
||||
En el servidor, en la carpeta de la web (la que ya es un clon del repo):
|
||||
|
||||
git fetch && git checkout pedir-evento
|
||||
sudo ./despliegue/instalar.sh
|
||||
|
||||
Después, dos cosas a mano:
|
||||
|
||||
1. Añadir esta línea dentro del `server{}` de www.laenre.net y recargar:
|
||||
|
||||
include /etc/nginx/snippets/enrecal.conf;
|
||||
|
||||
sudo nginx -t && sudo systemctl reload nginx
|
||||
|
||||
El fragmento también deja de servir `.git`, `gestor/`, `despliegue/`,
|
||||
`README.md`, `context.txt` e `info.txt`, que ahora mismo se pueden
|
||||
descargar desde la web.
|
||||
|
||||
2. Crear las cuentas. `cuenta.sh` para el servicio, crea la cuenta y lo
|
||||
vuelve a arrancar:
|
||||
|
||||
sudo ./despliegue/cuenta.sh -usuario asamblea -nombre "Asamblea de La Enre" -rol enre -clave 'LA-CLAVE' -definitiva cuenta
|
||||
sudo ./despliegue/cuenta.sh -usuario externas -nombre "Asamblea de externas" -rol externas cuenta
|
||||
sudo ./despliegue/cuenta.sh -usuario hacklab -nombre "Hacklab La Raíz" cuenta
|
||||
|
||||
Sin `-clave`, se genera una al azar y se imprime: se entrega en mano y se
|
||||
cambia al entrar. Con `-clave X` sin `-definitiva`, también se pide
|
||||
cambiarla al entrar. Ninguna clave va en el repositorio.
|
||||
|
||||
Comprobar: `https://www.laenre.net/pedir/` carga y `https://www.laenre.net/.git/HEAD`
|
||||
da 403.
|
||||
|
||||
## Actualizar
|
||||
|
||||
git pull
|
||||
sudo ./despliegue/instalar.sh
|
||||
|
||||
No toca la configuración ni los datos.
|
||||
|
||||
## Si el servidor no tiene Go
|
||||
|
||||
`instalar.sh` compila si encuentra `go`. Si no, se compila en otra máquina y se
|
||||
copia el binario a `despliegue/enrecal` antes de lanzar el instalador:
|
||||
|
||||
cd gestor && CGO_ENABLED=0 GOOS=linux GOARCH=amd64 go build -trimpath -buildvcs=false -o ../despliegue/enrecal .
|
||||
scp ../despliegue/enrecal servidor:/ruta/de/la/web/despliegue/
|
||||
|
||||
## Día a día
|
||||
|
||||
- Otra clave para una cuenta: `sudo ./despliegue/cuenta.sh -usuario X clave`
|
||||
- Registro del servicio: `journalctl -u enrecal`
|
||||
- Copia de los datos: basta con copiar `/var/lib/enrecal/registro.jsonl`,
|
||||
también con el servicio en marcha, porque solo se escribe al final.
|
||||
- La configuración (cupo, ventana, qué finde es tranqui o con ruido) se cambia
|
||||
en `/etc/enrecal/config.json` y se aplica con `sudo systemctl restart enrecal`.
|
||||
19
despliegue/config.ejemplo.json
Normal file
19
despliegue/config.ejemplo.json
Normal file
|
|
@ -0,0 +1,19 @@
|
|||
{
|
||||
"escucha": "127.0.0.1:8090",
|
||||
"base_url": "https://www.laenre.net",
|
||||
"dir_datos": "/var/lib/enrecal",
|
||||
"dir_plantillas": "/opt/enrecal/plantillas",
|
||||
"log_auth": "/var/log/enrecal/auth.log",
|
||||
"cookie_segura": true,
|
||||
"local": false,
|
||||
"meses_vista": 4,
|
||||
"reglas": {
|
||||
"meses_ventana": 3,
|
||||
"cupo_dias": 3,
|
||||
"dias_minimo_confirmar": 7,
|
||||
"dias_maximo_pendiente": 30,
|
||||
"dias_reservables": [5, 6, 7],
|
||||
"ancla_finde": "2026-09-25",
|
||||
"turno_ancla": "ruido"
|
||||
}
|
||||
}
|
||||
23
despliegue/cuenta.sh
Executable file
23
despliegue/cuenta.sh
Executable file
|
|
@ -0,0 +1,23 @@
|
|||
#!/bin/sh
|
||||
# Da de alta una cuenta o le cambia la clave, con el servicio parado.
|
||||
#
|
||||
# El gestor lee el registro al arrancar, así que una cuenta creada con el
|
||||
# servicio en marcha no se vería hasta reiniciarlo. Este script lo para, hace
|
||||
# la operación como el usuario enrecal (para que el registro no cambie de dueño)
|
||||
# y lo vuelve a arrancar.
|
||||
#
|
||||
# sudo ./despliegue/cuenta.sh -usuario hacklab -nombre "Hacklab La Raíz" cuenta
|
||||
# sudo ./despliegue/cuenta.sh -usuario hacklab clave
|
||||
#
|
||||
# Opciones: -rol enre|interno|externas, -clave X (si no, se genera una al
|
||||
# azar), -definitiva (la clave no se pide cambiar al entrar).
|
||||
set -eu
|
||||
|
||||
if [ "$(id -u)" -ne 0 ]; then
|
||||
echo "Hay que lanzarlo con sudo." >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
systemctl stop enrecal
|
||||
trap 'systemctl start enrecal' EXIT
|
||||
runuser -u enrecal -- /opt/enrecal/enrecal -config /etc/enrecal/config.json "$@"
|
||||
44
despliegue/enrecal.service
Normal file
44
despliegue/enrecal.service
Normal file
|
|
@ -0,0 +1,44 @@
|
|||
[Unit]
|
||||
Description=Gestor de reservas de La Enredadera (/pedir/)
|
||||
After=network.target
|
||||
|
||||
[Service]
|
||||
Type=simple
|
||||
User=enrecal
|
||||
Group=enrecal
|
||||
ExecStart=/opt/enrecal/enrecal -config /etc/enrecal/config.json servir
|
||||
Restart=on-failure
|
||||
RestartSec=5
|
||||
|
||||
# Solo puede escribir en sus datos y en su registro de accesos.
|
||||
ProtectSystem=strict
|
||||
ReadWritePaths=/var/lib/enrecal /var/log/enrecal
|
||||
ProtectHome=true
|
||||
PrivateTmp=true
|
||||
PrivateDevices=true
|
||||
NoNewPrivileges=true
|
||||
CapabilityBoundingSet=
|
||||
AmbientCapabilities=
|
||||
ProtectKernelTunables=true
|
||||
ProtectKernelModules=true
|
||||
ProtectKernelLogs=true
|
||||
ProtectControlGroups=true
|
||||
ProtectClock=true
|
||||
ProtectHostname=true
|
||||
RestrictNamespaces=true
|
||||
RestrictRealtime=true
|
||||
RestrictSUIDSGID=true
|
||||
LockPersonality=true
|
||||
MemoryDenyWriteExecute=true
|
||||
RestrictAddressFamilies=AF_INET AF_INET6 AF_UNIX
|
||||
SystemCallArchitectures=native
|
||||
SystemCallFilter=@system-service
|
||||
SystemCallFilter=~@privileged
|
||||
UMask=0027
|
||||
|
||||
# Tope de memoria: el gestor limita argon2 a dos cálculos a la vez (unos
|
||||
# 130 MB), así que 512 MB sobran y protegen al resto de servicios de la máquina.
|
||||
MemoryMax=512M
|
||||
|
||||
[Install]
|
||||
WantedBy=multi-user.target
|
||||
77
despliegue/instalar.sh
Executable file
77
despliegue/instalar.sh
Executable file
|
|
@ -0,0 +1,77 @@
|
|||
#!/bin/sh
|
||||
# Instala o actualiza el gestor de /pedir/ en el servidor.
|
||||
#
|
||||
# sudo ./despliegue/instalar.sh
|
||||
#
|
||||
# Se lanza desde la raíz del repositorio. Se puede repetir: la segunda vez solo
|
||||
# actualiza el programa y las plantillas, y no toca ni la configuración ni los
|
||||
# datos.
|
||||
set -eu
|
||||
|
||||
RAIZ=$(cd "$(dirname "$0")/.." && pwd)
|
||||
PROG=/opt/enrecal
|
||||
DATOS=/var/lib/enrecal
|
||||
LOGS=/var/log/enrecal
|
||||
CONF=/etc/enrecal
|
||||
|
||||
if [ "$(id -u)" -ne 0 ]; then
|
||||
echo "Hay que lanzarlo con sudo." >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# 1. El programa: se compila aquí si hay Go, o se usa el que se haya copiado a
|
||||
# despliegue/enrecal (ver README.md).
|
||||
if command -v go >/dev/null 2>&1; then
|
||||
echo "Compilando..."
|
||||
(cd "$RAIZ/gestor" && CGO_ENABLED=0 go build -trimpath -buildvcs=false -o "$RAIZ/despliegue/enrecal" .)
|
||||
elif [ ! -x "$RAIZ/despliegue/enrecal" ]; then
|
||||
echo "No hay Go en esta máquina ni un despliegue/enrecal ya compilado." >&2
|
||||
echo "Compílalo en otra máquina y cópialo (ver despliegue/README.md)." >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# 2. Usuario propio, sin shell ni carpeta personal.
|
||||
if ! id enrecal >/dev/null 2>&1; then
|
||||
useradd --system --no-create-home --shell /usr/sbin/nologin enrecal
|
||||
fi
|
||||
|
||||
# 3. Carpetas. El programa y las plantillas fuera de la web pública.
|
||||
install -d -m 0755 "$PROG" "$PROG/plantillas"
|
||||
install -d -m 0750 -o enrecal -g enrecal "$DATOS" "$LOGS"
|
||||
install -d -m 0755 "$CONF"
|
||||
|
||||
install -m 0755 "$RAIZ/despliegue/enrecal" "$PROG/enrecal"
|
||||
rm -f "$PROG"/plantillas/*.tmpl.html
|
||||
install -m 0644 "$RAIZ"/gestor/plantillas/*.tmpl.html "$PROG/plantillas/"
|
||||
|
||||
if [ ! -f "$CONF/config.json" ]; then
|
||||
install -m 0644 "$RAIZ/despliegue/config.ejemplo.json" "$CONF/config.json"
|
||||
echo "Configuración nueva en $CONF/config.json"
|
||||
fi
|
||||
|
||||
# 4. nginx: el límite de intentos va en http{} (conf.d) y el resto en un
|
||||
# fragmento que se incluye con una línea dentro del server{} de la web.
|
||||
if [ -d /etc/nginx ]; then
|
||||
install -d -m 0755 /etc/nginx/conf.d /etc/nginx/snippets
|
||||
install -m 0644 "$RAIZ/despliegue/nginx-zona.conf" /etc/nginx/conf.d/enrecal-zona.conf
|
||||
install -m 0644 "$RAIZ/despliegue/nginx-laenre.conf" /etc/nginx/snippets/enrecal.conf
|
||||
fi
|
||||
|
||||
# 5. systemd.
|
||||
install -m 0644 "$RAIZ/despliegue/enrecal.service" /etc/systemd/system/enrecal.service
|
||||
systemctl daemon-reload
|
||||
systemctl enable enrecal >/dev/null 2>&1
|
||||
systemctl restart enrecal
|
||||
sleep 1
|
||||
systemctl --no-pager --lines=3 status enrecal || true
|
||||
|
||||
cat <<'FIN'
|
||||
|
||||
Listo. Si es la primera vez, faltan dos cosas:
|
||||
|
||||
1. En el server{} de www.laenre.net, añadir esta línea y recargar nginx:
|
||||
include /etc/nginx/snippets/enrecal.conf;
|
||||
sudo nginx -t && sudo systemctl reload nginx
|
||||
|
||||
2. Crear las cuentas con despliegue/cuenta.sh (ver despliegue/README.md).
|
||||
FIN
|
||||
28
despliegue/nginx-laenre.conf
Normal file
28
despliegue/nginx-laenre.conf
Normal file
|
|
@ -0,0 +1,28 @@
|
|||
# Se incluye dentro del server{} de www.laenre.net:
|
||||
# include /etc/nginx/snippets/enrecal.conf;
|
||||
|
||||
# La web se despliega con git, así que en la carpeta pública están también
|
||||
# .git, el código del gestor y las notas internas. Nada de eso se sirve.
|
||||
location ~ /\.(?!well-known) { deny all; }
|
||||
location ~ ^/(gestor|despliegue)/ { deny all; }
|
||||
location ~ ^/(README\.md|context\.txt|info\.txt)$ { deny all; }
|
||||
|
||||
location /pedir/ {
|
||||
proxy_pass http://127.0.0.1:8090;
|
||||
proxy_set_header Host $host;
|
||||
# Imprescindible pisar las dos: si no, cualquiera manda su propia
|
||||
# X-Real-IP y se salta el bloqueo por IP del gestor.
|
||||
proxy_set_header X-Real-IP $remote_addr;
|
||||
proxy_set_header X-Forwarded-For $remote_addr;
|
||||
client_max_body_size 16k;
|
||||
}
|
||||
|
||||
location = /pedir/entrar {
|
||||
limit_req zone=enrecal burst=5 nodelay;
|
||||
limit_req_status 429;
|
||||
proxy_pass http://127.0.0.1:8090;
|
||||
proxy_set_header Host $host;
|
||||
proxy_set_header X-Real-IP $remote_addr;
|
||||
proxy_set_header X-Forwarded-For $remote_addr;
|
||||
client_max_body_size 16k;
|
||||
}
|
||||
3
despliegue/nginx-zona.conf
Normal file
3
despliegue/nginx-zona.conf
Normal file
|
|
@ -0,0 +1,3 @@
|
|||
# Va dentro de http{}: en Debian, /etc/nginx/conf.d/ ya se incluye ahí.
|
||||
# Diez intentos de acceso por minuto y por IP en /pedir/entrar.
|
||||
limit_req_zone $binary_remote_addr zone=enrecal:1m rate=10r/m;
|
||||
Loading…
Add table
Add a link
Reference in a new issue