From 647689787383b27ecec580622de8f52d15cb7db1 Mon Sep 17 00:00:00 2001 From: CyberMind-FR Date: Thu, 2 Jul 2026 08:14:08 +0200 Subject: [PATCH] =?UTF-8?q?refactor:=20decommission=20secubox-authelia=20(?= =?UTF-8?q?SSO=20IdP)=20=E2=80=94=20remove=20package,=20keep=20gate=20auth?= =?UTF-8?q?elia-free?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Authelia (secubox-authelia, #239) was a failed/half-baked SSO PoC. Its partial teardown also masked then unmasked the login-loop bug (hub-proxied /auth/login never recorded sessions). Removing it for good: - delete packages/secubox-authelia (package, service, nginx confs, LXC installer) - move the durable pieces into secubox-hub (always installed): - nginx/secubox-lan-geo.conf β†’ /etc/nginx/conf.d/ (defines $lan_client) - nginx/zz-sbx-authgate.conf β†’ secubox.d/ + secubox-routes.d/ keeps /__sbx_auth_verify + @sbx_auth_login defined WITHOUT Authelia: LAN clients pass (204), everything else denied (403 / default-deny). SSO-gated vhosts (lyrion, yacy, grafana, rustdesk, fmrelay) thus become LAN-only instead of losing their gate. - drop secubox-authelia from image/build-live-usb.sh module list No hard Depends referenced authelia (only description prose in users/nextcloud/identity), so nothing else breaks. Live: purged on gk2 + c3box, gate stubbed, lan-geo restored; verified lyrion/yacy/metablogizer still serve. --- image/build-live-usb.sh | 1 - packages/secubox-authelia/README.md | 40 -- packages/secubox-authelia/api/__init__.py | 0 packages/secubox-authelia/api/main.py | 165 -------- .../conf/authelia.toml.example | 61 --- packages/secubox-authelia/debian/changelog | 202 ---------- packages/secubox-authelia/debian/control | 37 -- packages/secubox-authelia/debian/postinst | 38 -- packages/secubox-authelia/debian/postrm | 16 - packages/secubox-authelia/debian/prerm | 14 - packages/secubox-authelia/debian/rules | 33 -- .../debian/secubox-authelia.service | 27 -- .../lib/authelia/install-lxc.sh | 355 ------------------ .../secubox-authelia/menu.d/40-authelia.json | 10 - .../nginx/authelia-vhost.conf | 130 ------- packages/secubox-authelia/nginx/authelia.conf | 26 -- packages/secubox-authelia/sbin/autheliactl | 268 ------------- .../secubox-authelia/www/authelia/index.html | 210 ----------- packages/secubox-hub/debian/rules | 9 + .../nginx/secubox-lan-geo.conf | 25 +- .../secubox-hub/nginx/zz-sbx-authgate.conf | 24 ++ 21 files changed, 45 insertions(+), 1646 deletions(-) delete mode 100644 packages/secubox-authelia/README.md delete mode 100644 packages/secubox-authelia/api/__init__.py delete mode 100644 packages/secubox-authelia/api/main.py delete mode 100644 packages/secubox-authelia/conf/authelia.toml.example delete mode 100644 packages/secubox-authelia/debian/changelog delete mode 100644 packages/secubox-authelia/debian/control delete mode 100755 packages/secubox-authelia/debian/postinst delete mode 100755 packages/secubox-authelia/debian/postrm delete mode 100755 packages/secubox-authelia/debian/prerm delete mode 100755 packages/secubox-authelia/debian/rules delete mode 100644 packages/secubox-authelia/debian/secubox-authelia.service delete mode 100755 packages/secubox-authelia/lib/authelia/install-lxc.sh delete mode 100644 packages/secubox-authelia/menu.d/40-authelia.json delete mode 100644 packages/secubox-authelia/nginx/authelia-vhost.conf delete mode 100644 packages/secubox-authelia/nginx/authelia.conf delete mode 100755 packages/secubox-authelia/sbin/autheliactl delete mode 100644 packages/secubox-authelia/www/authelia/index.html rename packages/{secubox-authelia => secubox-hub}/nginx/secubox-lan-geo.conf (54%) create mode 100644 packages/secubox-hub/nginx/zz-sbx-authgate.conf diff --git a/image/build-live-usb.sh b/image/build-live-usb.sh index 24960319..eb58cdb0 100755 --- a/image/build-live-usb.sh +++ b/image/build-live-usb.sh @@ -2778,7 +2778,6 @@ INCOMPLETE_MODULES=( secubox-yacy secubox-rustdesk secubox-lyrion - secubox-authelia secubox-mail secubox-gitea secubox-matrix diff --git a/packages/secubox-authelia/README.md b/packages/secubox-authelia/README.md deleted file mode 100644 index 9c5f10e4..00000000 --- a/packages/secubox-authelia/README.md +++ /dev/null @@ -1,40 +0,0 @@ -# πŸ” Authelia SSO - -Single sign-on identity provider (AUTH-BRIDGE) - -**Category:** Access - -## Screenshot - -![Authelia SSO](../../docs/screenshots/vm/authelia.png) - -## Features - -- SSO -- 2FA / TOTP -- Access policies -- LDAP / file backend - -## Installation - -```bash -# Add SecuBox repository -curl -fsSL https://apt.secubox.in/install.sh | sudo bash - -# Install package -sudo apt install secubox-authelia -``` - -## Configuration - -Configuration file: `/etc/secubox/authelia.toml` - -## API Endpoints - -- `GET /api/v1/authelia/status` - Module status -- `GET /api/v1/authelia/health` - Health check - -## License - -LicenseRef-CMSD-1.0 (Source-Disclosed License) β€” CyberMind Β© 2024-2026. -See [LICENCE-CMSD-1.0.md](../../LICENCE-CMSD-1.0.md). diff --git a/packages/secubox-authelia/api/__init__.py b/packages/secubox-authelia/api/__init__.py deleted file mode 100644 index e69de29b..00000000 diff --git a/packages/secubox-authelia/api/main.py b/packages/secubox-authelia/api/main.py deleted file mode 100644 index 975419e2..00000000 --- a/packages/secubox-authelia/api/main.py +++ /dev/null @@ -1,165 +0,0 @@ -# SPDX-License-Identifier: LicenseRef-CMSD-1.0 -# Copyright (c) 2026 CyberMind β€” GΓ©rald Kerma -# See LICENCE-CMSD-1.0.md for terms. - -""" -SecuBox-Deb :: secubox-authelia β€” host control plane API. - -FastAPI on /run/secubox/authelia.sock, proxied by nginx at /api/v1/authelia/. -Mandatory endpoints per docs/MODULE-GUIDELINES.md Β§8. - -Plus the `verify` endpoint used as the nginx `auth_request` target for the -SSO-less backends (yacy / rustdesk-web / mitmproxy-web): see #239 SSO bridge -spec. -""" -from __future__ import annotations - -import json -import os -import shutil -import socket -import subprocess -import urllib.error -import urllib.request -from pathlib import Path -from typing import Any, Dict - -from fastapi import FastAPI, HTTPException, Header, Request, Response - -VERSION = "1.0.8" -CTL = shutil.which("autheliactl") or "/usr/sbin/autheliactl" - -# Authelia LXC (provisioned by install-lxc.sh at 10.100.0.20:9091). Override -# via SECUBOX_AUTHELIA_URL if the LXC IP/port differs (e.g. for tests). -AUTHELIA_URL = os.environ.get("SECUBOX_AUTHELIA_URL", "http://10.100.0.20:9091") -# Authelia headers worth forwarding back to nginx (and through to the -# protected backend). nginx auth_request can capture these via -# `auth_request_set $sbx_user $upstream_http_remote_user;` etc. -_AUTH_REMOTE_HEADERS = ( - "Remote-User", "Remote-Groups", "Remote-Email", "Remote-Name", -) - -app = FastAPI( - title="SecuBox Authelia", - version=VERSION, - docs_url=None, - redoc_url=None, - openapi_url=None, -) - - -def _ctl_json(*args: str) -> Dict[str, Any]: - cmd = [CTL, *args, "--json"] - try: - out = subprocess.check_output(cmd, stderr=subprocess.STDOUT, timeout=15) - except subprocess.CalledProcessError as e: - raise HTTPException(status_code=500, detail=f"autheliactl failed: {e.output!r}") - except FileNotFoundError: - raise HTTPException(status_code=500, detail=f"autheliactl not found at {CTL}") - try: - return json.loads(out.decode()) - except json.JSONDecodeError as e: - raise HTTPException(status_code=500, detail=f"autheliactl emitted non-JSON: {e}; raw={out!r}") - - -@app.get("/healthz") -def healthz() -> Dict[str, bool]: - return {"ok": True} - - -@app.get("/version") -def version() -> Dict[str, str]: - build_file = Path("/usr/share/doc/secubox-authelia/.build-sha") - build = build_file.read_text().strip() if build_file.is_file() else "unknown" - return {"version": VERSION, "build": build} - - -@app.get("/status") -def status() -> Dict[str, Any]: - return _ctl_json("status") - - -@app.get("/components") -def components() -> Dict[str, Any]: - return _ctl_json("components") - - -@app.get("/access") -def access() -> Dict[str, Any]: - return _ctl_json("access") - - -@app.get("/verify") -@app.head("/verify") -def verify( - request: Request, - response: Response, - authorization: str | None = Header(default=None), - cookie: str | None = Header(default=None), -) -> Response: - """ - nginx `auth_request` target. - - Reverse-proxies to Authelia's native /api/verify which: - - validates the `authelia_session` cookie against the session store - - returns 200 + Remote-User / Remote-Groups / Remote-Email headers - when the session is valid - - returns 401 otherwise - - We propagate those Remote-* headers back to nginx so the protected - backend's `proxy_set_header` can capture them via - `auth_request_set $sbx_user $upstream_http_remote_user;` (etc). - """ - # Pass through Cookie + Authorization headers to Authelia. nginx already - # stripped the request body (proxy_pass_request_body off) so we're just - # forwarding metadata. - # Authelia 4.39+ is path-prefixed at /auth (server.address). The verify - # endpoint is therefore at /auth/api/verify (both /api/verify legacy - # and the prefixed path respond, but prefix is the canonical one). - upstream = f"{AUTHELIA_URL.rstrip('/')}/auth/api/verify" - headers = {} - if cookie: - headers["Cookie"] = cookie - if authorization: - headers["Authorization"] = authorization - # Authelia 4.39+ needs the original URL/host so it can (a) match the - # right session.cookies[].domain entry β€” multi-cookie deployments have - # several β€” and (b) apply access_control rules. nginx sets these in - # `location = /__sbx_auth_verify`; we forward verbatim. Without them - # Authelia falls back to the first cookies[] entry, doesn't find the - # session, returns 401 β†’ infinite redirect loop. - for h in ( - "X-Original-URL", - "X-Forwarded-Method", - "X-Forwarded-Proto", - "X-Forwarded-Host", - "X-Forwarded-Uri", - "X-Forwarded-For", - ): - v = request.headers.get(h) - if v is not None: - headers[h] = v - - req = urllib.request.Request(upstream, method="GET", headers=headers) - try: - with urllib.request.urlopen(req, timeout=3) as r: - status_code = r.status - for h in _AUTH_REMOTE_HEADERS: - v = r.headers.get(h) - if v is not None: - response.headers[h] = v - except urllib.error.HTTPError as e: - # Authelia returned a non-2xx (typically 401). Propagate the code so - # nginx's `error_page 401 = @sbx_auth_login;` can fire. - return Response(status_code=e.code) - except (urllib.error.URLError, socket.timeout, ConnectionError, OSError) as e: - # Authelia LXC unreachable β€” fail closed (deny by default). - raise HTTPException( - status_code=503, - detail=f"authelia upstream unreachable: {e!r}", - ) - - # 2xx from Authelia β†’ authenticated. Return 200 (with the Remote-* headers - # already written into `response`). - response.status_code = 200 if status_code < 300 else status_code - return response diff --git a/packages/secubox-authelia/conf/authelia.toml.example b/packages/secubox-authelia/conf/authelia.toml.example deleted file mode 100644 index 851a1de3..00000000 --- a/packages/secubox-authelia/conf/authelia.toml.example +++ /dev/null @@ -1,61 +0,0 @@ -# /etc/secubox/authelia.toml β€” SecuBox Authelia (SSO IdP) configuration - -[lxc] -name = "authelia" -ip = "10.100.0.20" -gateway = "10.100.0.1" -bridge = "br-lxc" -path = "/data/lxc" -debian_suite = "bookworm" - -[authelia] -# Authelia binary version + checksum (verified at install). -version = "4.39.5" -# Internal HTTP port (LXC-side). nginx proxies /auth/ to this port. -http_port = 9091 - -# JWT signing secret + storage encryption key are auto-generated on first -# install and written to /etc/secubox/secrets/{authelia-jwt,authelia-store}. - -[users] -# Use the SecuBox canonical user store. argon2id schema already matches -# Authelia's file backend ($argon2id$v=19$...). -backend = "file" -file_path = "/etc/secubox/users.json" - -[session] -domain = "maegia.tv" -expiration = "1h" -inactivity = "5m" - -[totp] -# 2FA TOTP enrollment per user. Disabled by default β€” wizard prompts to -# enable for the bootstrap admin. -enabled = false - -[exposure] -# Public hostname for the Authelia login portal. Used by the SecuBox -# admin webui's "Open SSO Portal" button + the /access endpoint. -public_hostname = "sso.gk2.secubox.in" -waf_inspect = true # route through mitmproxy (canonical maegia.tv pattern) - -[oidc] -# OIDC clients pre-provisioned by the wizard. Empty fields are filled -# interactively (client_secret generated, redirect_uri prompted). -[oidc.clients.grafana] -enabled = true -client_id = "secubox-grafana" -redirect_uris = ["https://grafana.maegia.tv/login/generic_oauth"] -scopes = ["openid", "profile", "email", "groups"] - -[oidc.clients.gitea] -enabled = true -client_id = "secubox-gitea" -redirect_uris = ["https://gitea.gk2.secubox.in/user/oauth2/secubox/callback"] -scopes = ["openid", "profile", "email"] - -[oidc.clients.nextcloud] -enabled = false -client_id = "secubox-nextcloud" -redirect_uris = ["https://nextcloud.maegia.tv/apps/user_oidc/code"] -scopes = ["openid", "profile", "email"] diff --git a/packages/secubox-authelia/debian/changelog b/packages/secubox-authelia/debian/changelog deleted file mode 100644 index f718f92d..00000000 --- a/packages/secubox-authelia/debian/changelog +++ /dev/null @@ -1,202 +0,0 @@ -secubox-authelia (1.0.10-1~bookworm1) bookworm; urgency=medium - - * Remove Authelia SSO entirely. - - nginx/authelia.conf: reduced to a permissive no-op gate. The - /__sbx_auth_verify auth_request endpoint now returns 200 for every - request; @sbx_auth_login is a harmless fallback to the app root. - Retained only because grafana/lyrion/yacy/rustdesk/fmrelay/zigbee/ - nextcloud vhosts still reference these two named locations β€” without - them nginx fails to load. No SSO portal, no session check, no - Authelia socket dependency. Fixes the dead-portal 302 that produced - a password prompt on LAN clients. - - debian/postinst: stop enabling the FastAPI daemon; disable + mask - secubox-authelia.service so it cannot be resurrected. - - Apps keep their own native auth; LAN/exposure boundaries are - enforced by HAProxy + the WAF, not by this layer. - - -- Gerald KERMA Mon, 29 Jun 2026 10:00:00 +0200 - -secubox-authelia (1.0.9-1~bookworm1) bookworm; urgency=medium - - * Split SSO portal from operator dashboard (#310): - - nginx/authelia.conf: /auth/ on the canonical hub vhost is now a - static alias to /usr/share/secubox/www/authelia/ (control + status - dashboard). Used to reverse-proxy the Authelia LXC portal. - - nginx/authelia.conf: @sbx_auth_login redirects to - https://sso.gk2.secubox.in/?rd=… (was https://$host/auth/?rd=…). - - nginx/authelia-vhost.conf: new public vhost sso.gk2.secubox.in, - reverse-proxies / β†’ /auth/ β†’ Authelia LXC 10.100.0.20:9091. Same - pattern as the existing auth.maegia.tv block, on the - .gk2.secubox.in cookie scope. - - www/authelia/index.html: rewrite as the SecuBox AUTH config - module β€” service state, version, user count, cookie scopes, - access rules, components / status / access cards. Charter AUTH - palette (#C04E24 orange). Was a Lyrion copy-paste stub. - - lib/authelia/install-lxc.sh: session.cookies[] for the hub - domain now points authelia_url at sso.${SECUBOX_HUB_DOMAIN}. - - -- Gerald Kerma Thu, 21 May 2026 12:30:00 +0000 - -secubox-authelia (1.0.8-1~bookworm1) bookworm; urgency=medium - - * nginx/authelia.conf: own the `@sbx_auth_login` named location. - Previously defined in secubox-zigbee, meaning lyrion (and any other - SSO-gated app) silently broke if zigbee was uninstalled. The handler - logically belongs to the SSO module β€” moved verbatim from - zigbee.conf v2.4.5 (no functional change; named-location lookup - happens within the same canonical hub server block via - `include /etc/nginx/secubox.d/*`). - * Closes #278. - - -- Gerald Kerma Thu, 21 May 2026 07:30:00 +0000 - -secubox-authelia (1.0.7-1~bookworm1) bookworm; urgency=medium - - * nginx/authelia.conf (`location = /__sbx_auth_verify`): forward - X-Original-URL + X-Forwarded-{Method,Proto,Host,Uri,For} to the - FastAPI /verify socket. Authelia's /api/verify needs the original - URL to (a) match the right session.cookies[].domain entry β€” - multi-cookie deployments have several β€” and (b) apply access_control - rules. Without these headers Authelia defaults to the first cookies[] - entry (maegia.tv), the gk2.secubox.in session isn't found, /verify - returns 401 even after successful login β†’ infinite redirect loop. - * api/main.py (`/verify`): forward the same X-Original-URL + - X-Forwarded-* headers verbatim to the Authelia LXC upstream. - * Closes #274. - - -- Gerald Kerma Wed, 20 May 2026 19:00:00 +0000 - -secubox-authelia (1.0.6-1~bookworm1) bookworm; urgency=medium - - * lib/authelia/install-lxc.sh: render session.cookies[] with TWO entries - β€” one per top-level domain where the SSO portal is consumed: - `maegia.tv` (auth.maegia.tv) and `${SECUBOX_HUB_DOMAIN}` (default: - gk2.secubox.in, override via env). Without the second entry, Authelia - rejects /auth/api/state with 403 ERR_BAD_REQUEST when the SPA is - loaded on admin.gk2.secubox.in/auth/ because no cookies[].domain - matched the request Host. Symptom in browser: AxiosError 403 inside - index.Bzd5GHAP.js after the page paints. - * lib/authelia/install-lxc.sh: add matching access_control rules - for `${SECUBOX_HUB_DOMAIN}` and `*.${SECUBOX_HUB_DOMAIN}` - (one_factor) so nginx auth_request β†’ /auth/api/verify resolves - cleanly for the canonical hub vhost and every sibling app vhost - (lyrion., zigbee., grafana., etc.). - * lib/authelia/install-lxc.sh: new readonly SECUBOX_HUB_DOMAIN env - knob (default gk2.secubox.in) β€” operators on other hubs override - it before running `autheliactl install`. - * Closes #272. - - -- Gerald Kerma Wed, 20 May 2026 18:00:00 +0000 - -secubox-authelia (1.0.5-1~bookworm1) bookworm; urgency=medium - - * nginx/authelia.conf: add `sub_filter "__SBX_BANNER_OFF" "";` inside - the /auth/ location to suppress the inherited server-level banner - injection from webui.conf. Per nginx docs, sub_filter inherits - from the parent server block when no child-level directive exists; - just deleting our location-level sub_filter in v1.0.3 left the - server-level injection still active. Authelia's strict CSP - (default-src 'self'; style-src 'self' 'nonce-...'; base-uri 'self') - then rejected the injected script-src + caused - base-uri / style-src-elem violations + an AxiosError 403 because - the SPA's API calls couldn't fire. - The never-match pattern replaces the inherited sub_filter with a - noop β†’ response passes through unmodified. - * Closes #270. - - -- Gerald KERMA Thu, 21 May 2026 04:10:00 +0200 - -secubox-authelia (1.0.4-1~bookworm1) bookworm; urgency=medium - - * nginx/authelia.conf + nginx/authelia-vhost.conf: hardcode - X-Forwarded-Proto: https on the proxy to the Authelia LXC. - v1.0.3 used `$scheme` (nginx's internal scheme), which is `http` - because TLS terminates at HAProxy. Authelia then built its - post-login redirect URL as `http://admin.gk2.secubox.in:9080/...` - (nginx's listen port). Browser saw `https://...:9080/...`, tried - a TLS handshake on the plain-HTTP port, and bailed with - SSL_ERROR_RX_RECORD_TOO_LONG. - HAProxy is the only TLS terminator on the path; the user-facing - scheme is always https β€” hardcoding it is correct. - * Closes #268. - - -- Gerald KERMA Thu, 21 May 2026 03:55:00 +0200 - -secubox-authelia (1.0.3-1~bookworm1) bookworm; urgency=medium - - * install-lxc.sh: set Authelia server.address path prefix /auth - (NO trailing slash β€” 4.39+ validator rejects it). Without this, - the React SPA's API calls 404'd β†’ browser AxiosError ERR_BAD_REQUEST. - * nginx/authelia.conf: drop trailing / on proxy_pass to preserve the - /auth/ prefix expected by Authelia 4.39+. Remove the health-banner - sub_filter β€” Authelia's strict CSP (default-src 'self'; - style-src 'self' 'nonce-...'; base-uri 'self') rejects the injection. - * nginx/authelia-vhost.conf (auth.maegia.tv): same proxy_pass / - banner fixes + add `location = /` β†’ 302 to /auth/ so the portal - URL is consistent across canonical hub + public vhost. - * api/main.py: /verify now reverse-proxies to /auth/api/verify - (matches the path-prefixed Authelia layout). - * Closes #266 (authelia portion). - - -- Gerald KERMA Thu, 21 May 2026 03:30:00 +0200 - -secubox-authelia (1.0.2-1~bookworm1) bookworm; urgency=medium - - * api/main.py: implement /verify properly. v1.0.1 returned HTTP 501 - (stub) which blocked SSO-style auth_request gating on sibling - modules β€” see #259 (zigbee v2.4.1) and #261 (lyrion v1.0.4) which - both fell back to LAN-only allow/deny for this exact reason. - . - The /verify handler now reverse-proxies to Authelia's native - /api/verify endpoint (10.100.0.20:9091), which: - - validates the authelia_session cookie against the session store - - returns 200 + Remote-User / Remote-Groups / Remote-Email headers - when the session is valid - - returns 401 otherwise - . - The Remote-* headers are propagated back to nginx so protected - backends can capture them via - auth_request_set $sbx_user $upstream_http_remote_user; - and feed them into proxy_set_header X-Forwarded-User $sbx_user; - . - Fail-closed: if the Authelia LXC is unreachable, /verify returns - 503 rather than 200 (nginx auth_request treats anything β‰₯500 as - deny, matching the LAN-only fallback semantics). - . - After this lands, sibling modules can swap their LAN-only - allow/deny for: - auth_request /__sbx_auth_verify; - error_page 401 = @sbx_auth_login; - See follow-up PRs to be filed against #259 / #261. - * Closes #262 - - -- Gerald KERMA Thu, 21 May 2026 02:30:00 +0200 - -secubox-authelia (1.0.1-1~bookworm1) bookworm; urgency=medium - - * sbin/autheliactl: detect `authelia` daemon (not the relic - `authelia-server` from the grafana sed-copy). - * lib/authelia/install-lxc.sh: render configuration.yml HOST-side with - proper variable substitution, then pipe via lxc-attach stdin (the - previous `env VAR=val sh -c 'cat ... < Wed, 20 May 2026 16:00:00 +0200 - -secubox-authelia (1.0.0-1~bookworm1) bookworm; urgency=medium - - * Initial release: Authelia SSO IdP in LXC at 10.100.0.20. - * File backend reading /etc/secubox/users.json (argon2 β€” matches Authelia spec). - * OIDC + 2FA TOTP (opt-in per user). - * Three-fold CTL grammar (autheliactl: components, status, access). - * Lifecycle verbs: install, reload, repair, wizard, uninstall. - * Pre-configured OIDC clients: grafana, gitea, nextcloud (operator fills client secrets). - * Inherits all 9 install-lxc fixes from v2.11.1 (download template, masquerade, - resolv via lxc-attach, ExecStartPre+ prefix, nginx routes.d/, etc.). - * Closes: #239 - - -- Gerald KERMA Wed, 20 May 2026 15:00:00 +0200 diff --git a/packages/secubox-authelia/debian/control b/packages/secubox-authelia/debian/control deleted file mode 100644 index 970f354e..00000000 --- a/packages/secubox-authelia/debian/control +++ /dev/null @@ -1,37 +0,0 @@ -Source: secubox-authelia -Section: admin -Priority: optional -Maintainer: Gerald KERMA -Build-Depends: debhelper-compat (= 13) -Standards-Version: 4.6.2 -Homepage: https://cybermind.fr/secubox - -Package: secubox-authelia -Architecture: all -Depends: ${misc:Depends}, - secubox-core (>= 1.0), - secubox-users (>= 1.0), - secubox-haproxy, - lxc, - lxc-templates, - debootstrap, - python3-uvicorn, - python3-fastapi, - python3-toml, - python3-yaml, - openssl, - curl, - jq -Recommends: secubox-mitmproxy -Description: SecuBox Authelia β€” SSO IdP (AUTH-BRIDGE layer) - Hosts Authelia in a Debian bookworm LXC at 10.100.0.20 on br-lxc. - File-backend identity provider reading /etc/secubox/users.json (the same - argon2-hashed user store already managed by secubox-users) so the canonical - SecuBox identity is the single source of truth for SSO. - . - OIDC clients pre-provisioned for the three native admin UIs that already - support OIDC: Grafana, Gitea, Nextcloud. YaCy/RustDesk-web/mitmproxy-web - (no native OIDC) get nginx `auth_request` integration to the same Authelia. - . - Health-banner injected on the Authelia login page via nginx sub_filter so - the operator sees the SecuBox system health bar even on the SSO screen. diff --git a/packages/secubox-authelia/debian/postinst b/packages/secubox-authelia/debian/postinst deleted file mode 100755 index 823bf5d2..00000000 --- a/packages/secubox-authelia/debian/postinst +++ /dev/null @@ -1,38 +0,0 @@ -#!/bin/sh -# SecuBox Authelia β€” post-install -set -e - -case "$1" in - configure) - # secubox system user/group (idempotent, matches sibling modules) - getent group secubox >/dev/null || groupadd --system secubox - getent passwd secubox >/dev/null || useradd --system --gid secubox \ - --home /var/lib/secubox --no-create-home --shell /usr/sbin/nologin secubox - - install -d -o secubox -g secubox -m 755 /etc/secubox - install -d -m 0755 -o secubox -g secubox /var/lib/secubox/authelia - install -d -m 0755 -o secubox -g secubox /var/log/secubox - - # Seed config from example if no live config exists - if [ ! -f /etc/secubox/authelia.toml ] && [ -f /etc/secubox/authelia.toml.example ]; then - cp /etc/secubox/authelia.toml.example /etc/secubox/authelia.toml - chmod 640 /etc/secubox/authelia.toml - chown root:secubox /etc/secubox/authelia.toml - fi - - # Reload nginx if it's running and our snippet parses - if systemctl is-active --quiet nginx 2>/dev/null; then - nginx -t >/dev/null 2>&1 && systemctl reload nginx 2>/dev/null || true - fi - - # Authelia SSO removed: never start/enable the daemon. Mask it so a - # stale unit or sibling dependency cannot resurrect it. The nginx - # gate is now a permissive no-op (see nginx/authelia.conf). - systemctl daemon-reload 2>/dev/null || true - systemctl disable --now secubox-authelia.service 2>/dev/null || true - systemctl mask secubox-authelia.service 2>/dev/null || true - ;; -esac - -#DEBHELPER# -exit 0 diff --git a/packages/secubox-authelia/debian/postrm b/packages/secubox-authelia/debian/postrm deleted file mode 100755 index 7ad0c2de..00000000 --- a/packages/secubox-authelia/debian/postrm +++ /dev/null @@ -1,16 +0,0 @@ -#!/bin/sh -# SecuBox Authelia β€” post-remove -set -e - -case "$1" in - purge) - # Only on purge β€” preserve operator data on plain remove/upgrade. - rm -f /etc/secubox/authelia.toml /etc/secubox/authelia.toml.example - rm -rf /var/lib/secubox/authelia - # LXC is left intact: operator removes it explicitly via - # `autheliactl uninstall` (TODO: future verb). - ;; -esac - -#DEBHELPER# -exit 0 diff --git a/packages/secubox-authelia/debian/prerm b/packages/secubox-authelia/debian/prerm deleted file mode 100755 index 22f778e0..00000000 --- a/packages/secubox-authelia/debian/prerm +++ /dev/null @@ -1,14 +0,0 @@ -#!/bin/sh -# SecuBox Authelia β€” pre-remove -set -e - -case "$1" in - remove|deconfigure|upgrade) - systemctl stop secubox-authelia.service 2>/dev/null || true - systemctl disable secubox-authelia.service 2>/dev/null || true - # We do not destroy the LXC here β€” purge does that via postrm if asked. - ;; -esac - -#DEBHELPER# -exit 0 diff --git a/packages/secubox-authelia/debian/rules b/packages/secubox-authelia/debian/rules deleted file mode 100755 index 4cce37cd..00000000 --- a/packages/secubox-authelia/debian/rules +++ /dev/null @@ -1,33 +0,0 @@ -#!/usr/bin/make -f -%: - dh $@ - -override_dh_auto_install: - # Host control plane (FastAPI) - install -d debian/secubox-authelia/usr/lib/secubox/authelia - cp -r api debian/secubox-authelia/usr/lib/secubox/authelia/ - # CTL - install -d debian/secubox-authelia/usr/sbin - install -m 755 sbin/autheliactl debian/secubox-authelia/usr/sbin/autheliactl - # Web UI - install -d debian/secubox-authelia/usr/share/secubox/www - [ -d www ] && cp -r www/. debian/secubox-authelia/usr/share/secubox/www/ || true - # Menu entry - install -d debian/secubox-authelia/usr/share/secubox/menu.d - [ -d menu.d ] && cp -r menu.d/. debian/secubox-authelia/usr/share/secubox/menu.d/ || true - # nginx snippet β€” install to BOTH secubox.d/ and secubox-routes.d/ (per v2.11.1 lesson) - install -d debian/secubox-authelia/etc/nginx/secubox.d - [ -f nginx/authelia.conf ] && cp nginx/authelia.conf debian/secubox-authelia/etc/nginx/secubox.d/ && (install -d debian/secubox-authelia/etc/nginx/secubox-routes.d && cp nginx/authelia.conf debian/secubox-authelia/etc/nginx/secubox-routes.d/) || true - # LAN-bypass geo block β€” http{}-level, MUST live in conf.d/ so it - # loads before secubox.d/authelia.conf inside the server{} blocks. - install -d debian/secubox-authelia/etc/nginx/conf.d - [ -f nginx/secubox-lan-geo.conf ] && cp nginx/secubox-lan-geo.conf debian/secubox-authelia/etc/nginx/conf.d/ || true - # Public vhost (auth.maegia.tv-style) - install -d debian/secubox-authelia/etc/nginx/sites-available - [ -f nginx/authelia-vhost.conf ] && cp nginx/authelia-vhost.conf debian/secubox-authelia/etc/nginx/sites-available/authelia.conf || true - # Config example - install -d debian/secubox-authelia/etc/secubox - [ -f conf/authelia.toml.example ] && cp conf/authelia.toml.example debian/secubox-authelia/etc/secubox/authelia.toml.example || true - # LXC bootstrap + Authelia configuration template - install -d debian/secubox-authelia/usr/share/secubox/lib/authelia - [ -d lib/authelia ] && cp -r lib/authelia/. debian/secubox-authelia/usr/share/secubox/lib/authelia/ || true diff --git a/packages/secubox-authelia/debian/secubox-authelia.service b/packages/secubox-authelia/debian/secubox-authelia.service deleted file mode 100644 index e4418f71..00000000 --- a/packages/secubox-authelia/debian/secubox-authelia.service +++ /dev/null @@ -1,27 +0,0 @@ -[Unit] -Description=SecuBox Authelia β€” host control plane API -Documentation=file:///usr/share/doc/secubox-authelia/README -After=network.target secubox-core.service -Wants=secubox-core.service - -[Service] -UMask=0007 -Type=simple -User=secubox -Group=secubox -WorkingDirectory=/usr/lib/secubox/authelia -RuntimeDirectory=secubox -RuntimeDirectoryMode=0755 -RuntimeDirectoryPreserve=yes -ExecStartPre=+/bin/mkdir -p /etc/secubox -ExecStartPre=+/bin/chown secubox:secubox /etc/secubox -ExecStart=/usr/bin/python3 -m uvicorn api.main:app --uds /run/secubox/authelia.sock --log-level warning -Restart=on-failure -RestartSec=5 -NoNewPrivileges=true -LogsDirectory=secubox -LogsDirectoryMode=0755 -ReadWritePaths=/run/secubox /var/lib/secubox /etc/secubox /var/log/secubox - -[Install] -WantedBy=multi-user.target diff --git a/packages/secubox-authelia/lib/authelia/install-lxc.sh b/packages/secubox-authelia/lib/authelia/install-lxc.sh deleted file mode 100755 index 0c6234d5..00000000 --- a/packages/secubox-authelia/lib/authelia/install-lxc.sh +++ /dev/null @@ -1,355 +0,0 @@ -#!/usr/bin/env bash -# SPDX-License-Identifier: LicenseRef-CMSD-1.0 -# SecuBox-Deb :: secubox-authelia :: install-lxc.sh -# -# Idempotent LXC bootstrap for the Authelia SSO IdP. Safe to re-run. -# Inherits all 9 install-lxc fixes from v2.11.1: -# 1. lxc-create -t download (unprivileged-compatible) -# 2. ensure_masquerade() 10.100.0.0/24 -# 3. ensure_resolv() via lxc-attach + unlink symlink -# 4. (no apt repo dance like grafana β€” Authelia is a single binary) -# Follows docs/MODULE-GUIDELINES.md Β§3. - -set -euo pipefail - -readonly LXC_NAME="${SECUBOX_LXC_NAME:-authelia}" -readonly LXC_IP="${SECUBOX_LXC_IP:-10.100.0.20}" -readonly LXC_PATH="${SECUBOX_LXC_PATH:-/data/lxc}" -readonly LXC_BRIDGE="${SECUBOX_LXC_BRIDGE:-br-lxc}" -readonly LXC_GW="${SECUBOX_LXC_GW:-10.100.0.1}" -readonly DEBIAN_SUITE="${SECUBOX_DEBIAN_SUITE:-bookworm}" -readonly AUTHELIA_VERSION="${SECUBOX_AUTHELIA_VERSION:-4.39.5}" -readonly AUTHELIA_HTTP_PORT="${SECUBOX_AUTHELIA_PORT:-9091}" -# Hub domain β€” the canonical SecuBox WebUI vhost where the SSO portal is -# mounted under /auth/. Authelia REQUIRES a session.cookies[] entry per -# top-level domain it serves, otherwise the SPA gets 403 on /auth/api/state. -# Override via env when deploying on a non-default hub (gk2.secubox.in etc.). -readonly SECUBOX_HUB_DOMAIN="${SECUBOX_HUB_DOMAIN:-gk2.secubox.in}" -readonly PROVISION_DIR="${SECUBOX_PROVISION_DIR:-/usr/share/secubox/lib/authelia/provision}" -readonly STATE_DIR="${SECUBOX_STATE_DIR:-/var/lib/secubox/authelia}" -readonly SECRETS_DIR="${SECUBOX_SECRETS_DIR:-/etc/secubox/secrets}" -readonly SENTINEL="$STATE_DIR/.lxc-provisioned" - -log() { printf '[authelia-install] %s\n' "$*"; } -fail() { printf '[authelia-install] ERROR: %s\n' "$*" >&2; exit 1; } - -require_cmds() { - for c in lxc-create lxc-info lxc-start lxc-attach openssl nft; do - command -v "$c" >/dev/null 2>&1 || fail "$c not installed" - done -} - -ensure_dirs() { - install -d -m 0755 -o root -g root "$LXC_PATH" - install -d -m 0755 -o secubox -g secubox "$STATE_DIR" - install -d -m 0700 -o root -g root "$SECRETS_DIR" -} - -ensure_bridge() { - if ! ip link show "$LXC_BRIDGE" >/dev/null 2>&1; then - log "Creating bridge $LXC_BRIDGE @ ${LXC_GW}/24 ..." - ip link add name "$LXC_BRIDGE" type bridge - ip addr add "${LXC_GW}/24" dev "$LXC_BRIDGE" - ip link set "$LXC_BRIDGE" up - fi -} - -ensure_masquerade() { - if ! nft list table ip lxc 2>/dev/null | grep -q 'saddr 10.100.0.0/24'; then - log "Adding nftables MASQUERADE for 10.100.0.0/24 ..." - nft 'add table ip lxc' 2>/dev/null || true - nft 'add chain ip lxc postrouting { type nat hook postrouting priority srcnat ; policy accept ; }' 2>/dev/null || true - nft 'add rule ip lxc postrouting ip saddr 10.100.0.0/24 ip daddr != 10.100.0.0/24 counter masquerade' 2>/dev/null || true - fi -} - -lxc_state() { - lxc-info -n "$LXC_NAME" -P "$LXC_PATH" 2>/dev/null \ - | awk -F: '/^State:/ { gsub(/ /,"",$2); print tolower($2) }' -} - -create_lxc() { - if [ -d "$LXC_PATH/$LXC_NAME/rootfs" ]; then - log "LXC '$LXC_NAME' already exists β€” skipping debootstrap" - return - fi - log "Creating LXC '$LXC_NAME' (debian $DEBIAN_SUITE) ..." - lxc-create -n "$LXC_NAME" -t download -P "$LXC_PATH" \ - -- --dist debian --release "$DEBIAN_SUITE" \ - --arch "$(dpkg --print-architecture)" -} - -write_lxc_config() { - log "Pinning network: $LXC_IP/24 on $LXC_BRIDGE" - cat > "$LXC_PATH/$LXC_NAME/config" </dev/null 2>&1 && return 0 - sleep 1 - done - fail "LXC '$LXC_NAME' did not reach $LXC_GW within 30s" -} - -ensure_resolv() { - log "Seeding /etc/resolv.conf in LXC ..." - lxc-attach -n "$LXC_NAME" -P "$LXC_PATH" -- sh -c ' - rm -f /etc/resolv.conf - printf "nameserver 1.1.1.1\nnameserver 9.9.9.9\n" > /etc/resolv.conf - ' -} - -# ── Authelia install inside LXC ────────────────────────────────────────────── -# Authelia is a single static Go binary. We download from the upstream GitHub -# release matching the LXC's architecture, drop into /opt/authelia/, write a -# systemd unit, and let preflight regenerate the configuration.yml from the -# host-mounted /etc/secubox/authelia.toml on every restart. -install_authelia_in_lxc() { - local lxc_arch - lxc_arch=$(lxc-attach -n "$LXC_NAME" -P "$LXC_PATH" -- dpkg --print-architecture 2>/dev/null | tr -d '\r\n') - log "Installing Authelia $AUTHELIA_VERSION ($lxc_arch) in '$LXC_NAME' ..." - - lxc-attach -n "$LXC_NAME" -P "$LXC_PATH" -- env \ - AUTHELIA_VERSION="$AUTHELIA_VERSION" \ - AUTHELIA_ARCH="$lxc_arch" \ - bash -e <<'INNER' - set -euo pipefail - export DEBIAN_FRONTEND=noninteractive - apt-get update -q - apt-get install -y --no-install-recommends \ - ca-certificates curl tar - - if ! id -u authelia >/dev/null 2>&1; then - useradd -r -s /bin/false -d /var/lib/authelia -m authelia - fi - - install -d -m 0750 -o authelia -g authelia \ - /etc/authelia /var/lib/authelia /var/log/authelia - - if [ ! -x /opt/authelia/authelia ]; then - mkdir -p /opt/authelia - cd /tmp - url="https://github.com/authelia/authelia/releases/download/v${AUTHELIA_VERSION}/authelia-v${AUTHELIA_VERSION}-linux-${AUTHELIA_ARCH}.tar.gz" - echo "Downloading $url ..." - curl -fsSL "$url" -o authelia.tar.gz - tar xzf authelia.tar.gz - # Tarball ships authelia-linux- binary - for f in authelia-linux-*; do - [ -f "$f" ] && mv "$f" /opt/authelia/authelia - done - chmod +x /opt/authelia/authelia - rm -f authelia.tar.gz authelia-*.sig man/* completions/* 2>/dev/null || true - chown -R authelia:authelia /opt/authelia - fi - - cat > /etc/systemd/system/authelia.service < "$SECRETS_DIR/authelia-jwt" - [ -f "$SECRETS_DIR/authelia-store" ] || openssl rand -hex 32 > "$SECRETS_DIR/authelia-store" - chmod 600 "$SECRETS_DIR/authelia-jwt" "$SECRETS_DIR/authelia-store" - jwt_secret=$(cat "$SECRETS_DIR/authelia-jwt") - store_key=$(cat "$SECRETS_DIR/authelia-store") - - log "Rendering /etc/authelia/configuration.yml ..." - - # 1. users_database.yml β€” convert /etc/secubox/users.json (v2 schema, argon2id - # hashes) to Authelia's file-backend format. - python3 - < /etc/authelia/users_database.yml" \ - < /tmp/authelia-users.yml - rm -f /tmp/authelia-users.yml - - # 2. configuration.yml β€” Authelia 4.39+ schema. Variables substituted - # HOST-SIDE (we don't trust env-expansion-inside-quoted-heredoc). - # OIDC disabled for v1.0.0: enabling it requires a JWKS RSA key pair - # and at least one fully-configured client. v1.1.0 wizard handles that. - cat > /tmp/authelia-config.yml <, lyrion., zigbee., etc.) - - domain: "${SECUBOX_HUB_DOMAIN}" - policy: one_factor - - domain: "*.${SECUBOX_HUB_DOMAIN}" - policy: one_factor - -session: - # One cookie entry per top-level domain. Authelia returns 403 on /auth/api/* - # if the request's Host header doesn't match any cookies[].domain β€” that's - # the symptom we saw on admin.${SECUBOX_HUB_DOMAIN} before this entry existed. - cookies: - - name: authelia_session - domain: maegia.tv - authelia_url: 'https://auth.maegia.tv/' - expiration: 3600 - inactivity: 300 - - name: authelia_session - domain: ${SECUBOX_HUB_DOMAIN} - # SSO portal moved to its own vhost in #310 β€” sibling vhosts (zigbee, - # lyrion, nextcloud) now redirect here for login. The canonical hub - # /auth/ is the operator dashboard, not the portal anymore. - authelia_url: 'https://sso.${SECUBOX_HUB_DOMAIN}/' - expiration: 3600 - inactivity: 300 - secret: ${jwt_secret} - -storage: - encryption_key: ${store_key} - local: - path: /var/lib/authelia/db.sqlite3 - -notifier: - filesystem: - filename: /var/lib/authelia/notifications.txt - -# OIDC identity provider β€” disabled in v1.0.0. Enable via 'autheliactl wizard' -# in v1.1.0 (will generate the JWKS RSA key + at least one client). -# identity_providers: -# oidc: -# hmac_secret: ${jwt_secret} -# jwks: -# - key_id: 'secubox-oidc' -# algorithm: 'RS256' -# key: | -# -----BEGIN RSA PRIVATE KEY----- -# ... -# clients: -# - client_id: 'secubox-grafana' -# ... -CONF - - lxc-attach -n "$LXC_NAME" -P "$LXC_PATH" -- sh -c "cat > /etc/authelia/configuration.yml" \ - < /tmp/authelia-config.yml - rm -f /tmp/authelia-config.yml - - lxc-attach -n "$LXC_NAME" -P "$LXC_PATH" -- chown -R authelia:authelia /etc/authelia - lxc-attach -n "$LXC_NAME" -P "$LXC_PATH" -- systemctl restart authelia.service -} - -mark_provisioned() { - install -d -m 0755 -o secubox -g secubox "$STATE_DIR" - date -Iseconds > "$SENTINEL" -} - -main() { - require_cmds - ensure_dirs - ensure_bridge - ensure_masquerade - create_lxc - write_lxc_config - start_lxc - wait_for_network - ensure_resolv - install_authelia_in_lxc - render_authelia_config - mark_provisioned - log "OK β€” LXC '$LXC_NAME' at $LXC_IP, authelia provisioned + running on port $AUTHELIA_HTTP_PORT." - log "Web UI: https://auth.maegia.tv/ (operator: configure DNS + HAProxy vhost)" - log "Secrets: $SECRETS_DIR/authelia-{jwt,store}" -} - -main "$@" diff --git a/packages/secubox-authelia/menu.d/40-authelia.json b/packages/secubox-authelia/menu.d/40-authelia.json deleted file mode 100644 index 7750d957..00000000 --- a/packages/secubox-authelia/menu.d/40-authelia.json +++ /dev/null @@ -1,10 +0,0 @@ -{ - "subtitle": "Authelia Β· OIDC IdP", - "icon": "πŸ”‘", - "order": 40, - "id": "authelia", - "name": "SSO", - "path": "/auth/", - "category": "auth", - "description": "" -} diff --git a/packages/secubox-authelia/nginx/authelia-vhost.conf b/packages/secubox-authelia/nginx/authelia-vhost.conf deleted file mode 100644 index 0d5d3b95..00000000 --- a/packages/secubox-authelia/nginx/authelia-vhost.conf +++ /dev/null @@ -1,130 +0,0 @@ -# /etc/nginx/sites-available/authelia.conf β€” public vhost auth.maegia.tv -# Installed by secubox-authelia (#239). -# -# Routing flow (same as yacy.maegia.tv validated 2026-05-20): -# Browser β†’ HAProxy:443 (TLS, cert /data/haproxy/certs/auth.maegia.tv.pem) -# β†’ mitmproxy WAF (LXC) β€” entry registered in -# /srv/mitmproxy/haproxy-routes.json INSIDE the mitmproxy LXC -# β†’ nginx:9080 (this vhost) -# β†’ Authelia LXC at 10.100.0.20:9091 -# -# Operator-side prerequisites (NOT done by this snippet): -# 1. DNS A record auth.maegia.tv β†’ public IP -# 2. TLS cert in /data/haproxy/certs/auth.maegia.tv.pem -# 3. haproxyctl vhost add auth.maegia.tv nginx_vhosts ssl -# ↑ CAUTION: known to drop backend defs (see #238 / v2.11.1 commit message). -# Prefer manual ACL injection or repair haproxy.cfg from backup. -# 4. mitmproxy route INSIDE the LXC: -# lxc-attach -n mitmproxy -- python3 -c \ -# "import json; p='/srv/mitmproxy/haproxy-routes.json'; d=json.load(open(p)); \ -# d['auth.maegia.tv']=['192.168.1.200',9080]; json.dump(d, open(p,'w'), indent=2, sort_keys=True)" -# lxc-attach -n mitmproxy -- systemctl restart mitmproxy - -server { - listen 0.0.0.0:9080; - server_name auth.maegia.tv; - - # Banner injection REMOVED here too: Authelia ships a strict CSP - # that rejects the sub_filter - - - - - diff --git a/packages/secubox-hub/debian/rules b/packages/secubox-hub/debian/rules index a4c86f1b..e8892c74 100755 --- a/packages/secubox-hub/debian/rules +++ b/packages/secubox-hub/debian/rules @@ -12,6 +12,15 @@ override_dh_auto_install: # Modular nginx config install -d debian/secubox-hub/etc/nginx/secubox.d [ -f nginx/hub.conf ] && cp nginx/hub.conf debian/secubox-hub/etc/nginx/secubox.d/ || true + # Authelia-free auth-gate stub + LAN geo (moved here from the decommissioned + # secubox-authelia). Ships $lan_client and the /__sbx_auth_verify + + # @sbx_auth_login named locations into BOTH include dirs so SSO-gated vhosts + # keep resolving them; LAN passes, everything else is denied. + install -d debian/secubox-hub/etc/nginx/secubox-routes.d + [ -f nginx/zz-sbx-authgate.conf ] && cp nginx/zz-sbx-authgate.conf debian/secubox-hub/etc/nginx/secubox.d/ || true + [ -f nginx/zz-sbx-authgate.conf ] && cp nginx/zz-sbx-authgate.conf debian/secubox-hub/etc/nginx/secubox-routes.d/ || true + install -d debian/secubox-hub/etc/nginx/conf.d + [ -f nginx/secubox-lan-geo.conf ] && cp nginx/secubox-lan-geo.conf debian/secubox-hub/etc/nginx/conf.d/ || true # Nginx snippets (shared CORS config) install -d debian/secubox-hub/etc/nginx/snippets [ -d nginx/snippets ] && cp -r nginx/snippets/. debian/secubox-hub/etc/nginx/snippets/ || true diff --git a/packages/secubox-authelia/nginx/secubox-lan-geo.conf b/packages/secubox-hub/nginx/secubox-lan-geo.conf similarity index 54% rename from packages/secubox-authelia/nginx/secubox-lan-geo.conf rename to packages/secubox-hub/nginx/secubox-lan-geo.conf index 8fce5e68..08f2fc05 100644 --- a/packages/secubox-authelia/nginx/secubox-lan-geo.conf +++ b/packages/secubox-hub/nginx/secubox-lan-geo.conf @@ -1,19 +1,18 @@ # /etc/nginx/conf.d/secubox-lan-geo.conf -# Installed by secubox-authelia (#239). +# Shipped by secubox-hub (moved here from the decommissioned secubox-authelia). # -# Defines $lan_client = 1 for trusted internal networks. Consumed by -# the auth_request handler in /etc/nginx/secubox.d/authelia.conf to -# short-circuit SSO for LAN/LXC clients β€” the dashboard at -# admin.gk2.secubox.in is auth-free from inside, gated by SSO from -# outside. +# Defines $lan_client = 1 for trusted internal networks. Consumed by the +# auth-gate stub in zz-sbx-authgate.conf: LAN/LXC/localhost clients pass the +# gate, everything else is denied (default-deny). The dashboard at +# admin. is auth-free from inside, denied from outside. # -# Add new internal ranges here (route subnets, VPN pools) β€” do NOT -# add public IPs. +# Add new internal ranges here (route subnets, VPN pools) β€” do NOT add public +# IPs. -# Trust the local HAProxy + mitmproxy chain so $remote_addr resolves -# to the real client IP (not 127.0.0.1 / the LXC bridge address). -# Without this every request looks local and the LAN bypass below -# would whitelist every external visitor. +# Trust the local HAProxy + mitmproxy chain so $remote_addr resolves to the +# real client IP (not 127.0.0.1 / the LXC bridge address). Without this every +# request looks local and the LAN bypass below would whitelist every external +# visitor. set_real_ip_from 127.0.0.1; set_real_ip_from 10.100.0.0/24; real_ip_header X-Forwarded-For; @@ -25,6 +24,6 @@ geo $lan_client { 192.168.1.0/24 1; # primary LAN (gk2 / SecuBox dashboards) 192.168.255.0/24 1; # secondary lan3 segment 10.55.0.0/24 1; # eye-br0 bridge (eye-remote / Pi Zero W) - 10.100.0.0/24 1; # br-lxc (Authelia/Lyrion/Grafana/... LXCs) + 10.100.0.0/24 1; # br-lxc (Lyrion / Grafana / ... LXCs) 10.0.3.0/24 1; # lxcbr0 (legacy LXC default bridge) } diff --git a/packages/secubox-hub/nginx/zz-sbx-authgate.conf b/packages/secubox-hub/nginx/zz-sbx-authgate.conf new file mode 100644 index 00000000..6aae6601 --- /dev/null +++ b/packages/secubox-hub/nginx/zz-sbx-authgate.conf @@ -0,0 +1,24 @@ +# /etc/nginx/{secubox.d,secubox-routes.d}/zz-sbx-authgate.conf +# Shipped by secubox-hub. +# +# Authelia-free auth-gate stubs. secubox-authelia (the SSO IdP / auth-bridge, +# #239) was decommissioned; these keep the two named locations that SSO-gated +# vhosts still reference (`auth_request /__sbx_auth_verify;` and +# `error_page 401 = @sbx_auth_login;`) working without any Authelia dependency. +# +# Posture (default-deny / CSPN): LAN clients pass, everything else is denied. +# WAN-exposed apps that relied on the old SSO gate are therefore LAN-only. +# `$lan_client` is defined in /etc/nginx/conf.d/secubox-lan-geo.conf (also +# shipped by secubox-hub). +# +# The `zz-` prefix keeps this sorted after the per-vhost include files so the +# named locations exist in the same server block that references them. +location = /__sbx_auth_verify { + internal; + if ($lan_client) { return 204; } + return 403; +} + +location @sbx_auth_login { + return 403; +}