# drogheda.helgen.online — 27-oct-2026: página de entrada propia (backend/acceso.py) en lugar de la ventana de # HTTP Basic. nginx pregunta a /api/_auth en cada petición; sin sesión manda a /entrar.html (las API reciben 401 JSON). # Lo instala backend/nginx/cambiar-entrada.sh (respaldo, nginx -t, recarga, pruebas y regreso automático si algo falla). # Lo de Certbot (443, certificados) es igual que antes. # Límites por IP (la oficina de Querétaro sale por una sola IP: holgados). Además, acceso.py frena por usuario. limit_req_zone $binary_remote_addr zone=hbox_entrar:1m rate=30r/m; limit_req_zone $binary_remote_addr zone=hbox_reporte:1m rate=6r/m; server { server_name drogheda.helgen.online; root /srv/projects/drogheda/hbox-docs/site; index index.html; # ---- sesión: todo pide sesión salvo lo marcado «auth_request off» abajo auth_request /_auth; auth_request_set $hbox_user $upstream_http_x_hbox_user; error_page 401 = @entrar; error_page 500 502 503 504 /publico/caido.html; location = /_auth { internal; proxy_pass http://127.0.0.1:8081/api/_auth; proxy_pass_request_body off; proxy_set_header Content-Length ""; proxy_set_header X-Remote-User ""; proxy_set_header X-Original-URI $request_uri; proxy_set_header X-Real-IP $remote_addr; } location @entrar { # sin sesión: a la página de entrada; después regresa a donde ibas (la página lo lee después del #) return 302 /entrar.html#$request_uri; } location @api401 { default_type application/json; return 401 '{"ok":false,"sesion":false,"error":"Tu sesión terminó. Vuelve a entrar en /entrar.html"}'; } location @lento { default_type application/json; return 429 '{"ok":false,"codigo":"bloqueado","error":"Demasiados intentos seguidos desde esta conexión. Espera un minuto y vuelve a intentar."}'; } # ---- públicas (sin sesión): la página de entrada y lo que necesita para verse location = /entrar.html { auth_request off; add_header Cache-Control "no-store"; } location ^~ /publico/ { auth_request off; } location ^~ /fonts/ { auth_request off; } location = /stylesheets/helgen.css { auth_request off; } location = /js/tema.js { auth_request off; } location ~ ^/img/(helgen-mascara\.svg|favicon\.png|helgen-icono-180\.png)$ { auth_request off; } location = /favicon.ico { auth_request off; try_files /img/favicon.png =404; } # ---- API sin sesión: entrar, salir, saber si hay sesión, salud, avisos y reporte desde la entrada location = /api/_auth { return 404; } location ~ ^/api/(salir|sesion|salud|incidencias/publicas)$ { auth_request off; client_max_body_size 16k; proxy_pass http://127.0.0.1:8081; proxy_set_header Host $host; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header X-Forwarded-Proto $scheme; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Remote-User ""; } location = /api/entrar { auth_request off; limit_req zone=hbox_entrar burst=20 nodelay; limit_req_status 429; error_page 429 = @lento; client_max_body_size 16k; proxy_pass http://127.0.0.1:8081; proxy_set_header Host $host; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header X-Forwarded-Proto $scheme; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Remote-User ""; } location = /api/incidencias/publica { auth_request off; limit_req zone=hbox_reporte burst=4 nodelay; limit_req_status 429; error_page 429 = @lento; client_max_body_size 16k; proxy_pass http://127.0.0.1:8081; proxy_set_header Host $host; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header X-Forwarded-Proto $scheme; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Remote-User ""; } # ---- API con sesión: el usuario lo pone nginx (de la sesión), nunca el navegador location /api/ { error_page 401 = @api401; client_max_body_size 25m; proxy_read_timeout 120s; proxy_pass http://127.0.0.1:8081; proxy_set_header Host $host; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header X-Forwarded-Proto $scheme; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Remote-User $hbox_user; } location / { try_files $uri $uri/ =404; } listen [::]:443 ssl; # managed by Certbot listen 443 ssl; # managed by Certbot ssl_certificate /etc/letsencrypt/live/drogheda.helgen.online/fullchain.pem; # managed by Certbot ssl_certificate_key /etc/letsencrypt/live/drogheda.helgen.online/privkey.pem; # managed by Certbot include /etc/letsencrypt/options-ssl-nginx.conf; # managed by Certbot ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem; # managed by Certbot } server { if ($host = drogheda.helgen.online) { return 301 https://$host$request_uri; } # managed by Certbot listen 80; listen [::]:80; server_name drogheda.helgen.online; return 404; # managed by Certbot }