Third batch after lyrion/zigbee/authelia (commit 54da8a7c). Same anti-
pattern across all three: nginx `/<module>/` was proxy_pass'ing to the
LXC, which silently broke any absolute asset URL the upstream app
served. Each module gets the same surgical fix:
- nginx/<module>.conf — /<module>/ is now `alias /usr/share/secubox/
www/<module>/` (SecuBox admin static page) instead of `proxy_pass`.
Both /api/v1/<module>/ and /<module>/ gated by `auth_request
/__sbx_auth_verify` so SSO covers admin access.
- <module>ctl — config_get strips TOML inline comments;
emit_access_json now returns the REAL upstream URLs (no /<module>/
admin suffix); PUBLIC_HOSTNAME defaults to <module>.gk2.secubox.in.
grafanactl also gets the `""|""` -> `""|list` case fix.
- www/<module>/index.html — "native UI" button reads its href from
/api/v1/<module>/access at runtime (single source of truth) and
opens in a new tab.
NEW dedicated vhost files for grafana and rustdesk (yacy already had
one): packages/{grafana,rustdesk}/nginx/<module>-vhost.conf. Both
listen 0.0.0.0:9080 server_name <module>.gk2.secubox.in, Authelia-
gated, serving the upstream app at root. Operator prerequisites (DNS
+ TLS cert + HAProxy ACL + mitmproxy route inside its LXC) documented
in each vhost header.
Side note: grafana's LMS-style absolute-path problem requires
`serve_from_sub_path = false` + `root_url = https://grafana.gk2.
secubox.in/` in /etc/grafana/grafana.ini inside the LXC. This is
flagged in the changelog as a follow-up for install-lxc.sh; for now
the live LXC config is unchanged.
Live verified on gk2 — all six modules (lyrion + zigbee + authelia +
yacy + grafana + rustdesk) now return the same /access shape:
lan http://<lxc_ip>:<port>/ (lan-only)
public https://<module>.gk2.secubox.in/ (Authelia SSO)