90+ services declare RuntimeDirectory=secubox, so systemd re-chowns the shared
socket parent to secubox:secubox 0755 on each start, locking out non-secubox
socket creators. Removing explicit chowns (#494) wasn't enough; the per-minute
dirs-guard now self-heals /run/secubox centrally instead of editing 90+ units.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
secubox-core.service ran After=network.target, so its ExecStart
'chown secubox:secubox /run/secubox + chmod 775' fired LAST — after
secubox-runtime.service had re-applied the canonical tmpfiles rule
'd /run/secubox 1777 root root'. Result: the socket dir ended up
secubox:secubox, non-secubox daemons lost parent +x, and their sockets 502'd.
- Remove the chown/chmod of /run/secubox from ExecStart; the dir is now owned
solely by tmpfiles.d (1777 root root) + secubox-runtime.service. This unit
keeps only the www-data group membership.
- postinst defensively removes a stale non-dpkg-owned /etc/tmpfiles.d/secubox.conf
declaring /run/secubox as 0775 secubox secubox (it overrode /usr/lib canonical).
- Ensure /var/log/suricata exists (0755) so ReadWritePaths services don't
NAMESPACE-fail.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
(cherry picked from commit 60f05992ee)
Review found two gaps the install-d sweep missed:
- chmod-form clobber: soc-gateway/soc-agent/ui-manager did 'chmod 750
/var/log/secubox' (same #511 traversal class) -> now 0755.
- secubox-core tmpfiles.d only declared /run/secubox; now declares all 5 shared
parents at 0755 (mode-only, owner-agnostic) for boot/install-time self-heal.
core 1.1.7 -> 1.1.8.
Non-secubox daemons can't traverse a 0750 secubox:secubox dir even when
the target files are world-readable. Caused secubox-eye-remote-dhcp
(dnsmasq --user=dnsmasq) to fail-loop 625× before manual chmod 0755.
Same constraint will hit hostapd/wpa_supplicant for the upcoming
secubox-mesh radio module (#449), netifyd for secubox-dpi, etc.
/etc/secubox/secrets stays 0700 secubox:secubox — sensitive content
remains private. Opening the parent only exposes file *names*, not
content (CSPN policy preserved).
Live drift already applied on gk2 (2026-06-03). This bumps the source
so the next secubox-core reinstall doesn't regress.
Co-authored-by: CyberMind-FR <gandalf@Gk2.net>
Co-authored-by: Claude Opus 4.7 <noreply@anthropic.com>
SecuBox stays source of truth. user_store gains set_password() (the single
password write path = capture point) + list_users(); a new host CLI
secubox-user-sync sets the canonical argon2 hash then pushes the same plaintext
(via SECUBOX_USER_PASSWORD env/stdin, never argv) into each app exposing a
`<app>ctl user-provision` verb. nextcloudctl + photoprismctl gain that verb,
each creating a per-user photo folder (/data/shared/photos/<user>) and a
user-scoped library; admin stays unrestricted (management), others scoped.
gk2 + admin are always provisioned (seed). Tests for set_password included.
Stock lxc.service has After=remote-fs.target but not After=data.mount.
/data is a local ext4 mount (UUID-based, not NFS). At boot lxc.service
ran ~2s in, lxc-autostart enumerated /data/lxc/ before the mount
landed, found nothing, exited 0. Every LXC with lxc.start.auto = 1
stayed STOPPED. Authelia being one of them broke every SSO-gated
vhost — auth_request returned 503, nginx replied HTTP 500.
Fix: systemd drop-in /etc/systemd/system/lxc.service.d/wait-for-data.conf
with RequiresMountsFor=/data. systemd resolves to the right mount unit
and orders lxc.service after it. No-op on appliances without a /data
partition.
Live-deployed on gk2 (1.1.4 → 1.1.5); After= now includes data.mount.
Co-authored-by: CyberMind-FR <gandalf@Gk2.net>
The old ExecStart sequence overwrote tmpfiles.d's 1777 root:root with
775 secubox:secubox, killing nginx's ability to traverse the directory
and reach the .sock files inside. Every secubox-*.sock upstream
returned 502 after each reboot. Observed AGAIN on 2026-05-21 after
the MOCHAbin freeze — ~90 services started up but only 8 had usable
sockets, the rest hidden behind broken perms.
New unit:
* Ordered After=systemd-tmpfiles-setup.service so tmpfiles.d wins.
* Re-applies the canonical rule (systemd-tmpfiles --create) as a
safety net for boards that hit the rule before /run is mounted.
* NO chown / chmod that override tmpfiles.
Co-authored-by: CyberMind-FR <gandalf@Gk2.net>
The MOCHAbin custom kernel builds nf_conntrack / nf_nat / nft_chain_nat
as =y not =m, so the stock nftables.service ExecStartPre 'modprobe
nf_nat' exits 1, systemd kills the unit before ExecStart, and the
DNAT/MASQUERADE rules in /etc/nftables.d/*.nft never get loaded —
every reboot lost lyrion slimproto :3483 DNAT, mqtt forwards, etc.
* packages/secubox-core/systemd/nftables.service.d/override.conf (new):
drop-in that swallows modprobe failures (|| true).
* packages/secubox-core/debian/rules: install the drop-in to
/etc/systemd/system/nftables.service.d/override.conf.
* Closes the nftables half of #150 (board loses NAT rules at boot).
Co-authored-by: CyberMind-FR <gandalf@Gk2.net>
The postinst unconditionally installed `nginx/secubox.conf` (which contains
three server blocks bound to 80/443) over any existing file. On HAProxy-
fronted boards where HAProxy already owns 80/443, this turned the file into
a config bomb: nginx -t still passed (syntax-only), but the next
systemctl restart nginx crashed with `bind() failed (98: Address already
in use)`. The bomb went off during the #156 cookie-audit deploy on the
gk2 prod board (4-min dashboard outage).
Fix:
- Only install /etc/nginx/sites-available/secubox on first install
(file absent). Subsequent installs/upgrades keep the operator-tuned
file intact (same idempotent pattern as the /etc/secubox.conf gate
a few lines above).
- Symlink creation already had the same gate (good).
- nginx-reload now wrapped in nginx -t — don't reload if the merged
config wouldn't survive a fresh start; print a warning instead.
Operators who customized the file pre-upgrade keep their version. New
installs get the standalone-nginx variant as before.
Changelog bumped to 1.1.2.
Co-authored-by: CyberMind-FR <gandalf@Gk2.net>
Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
- Define Component struct with requirements, tags, modes
- Implement Scanner to find all secubox-* packages
- Add SupportsArch() helper method
- Create secubox-core/debian/secubox.yaml example
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- extlinux.conf: secubox-led entry now uses initrd.img-6.12.85
(matches kernel 6.12.85, not the +deb12-arm64 variant)
- This fixes "Driver 'mv64xxx_i2c' is already registered" error
caused by kernel/initrd module mismatch
- Add secubox-led-k2000 script for rainbow LED effect
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Add /usr/sbin/secubox-led-heartbeat script
- Add secubox-led-heartbeat.service systemd unit
- Update debian/rules to install heartbeat components
- Add README.md with documentation
LED heartbeat uses IS31FL3199 via sysfs with I2C timing delays.
Configurable via LED_COLOR and LED_NUM environment variables.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Add CORS headers to nginx secubox-proxy.conf for cross-origin API requests
- Fix login.html endpoints: /auth/login -> /login
- Upgrade Python deps in build scripts: pydantic>=2.0, fastapi>=0.100, uvicorn>=0.25
- Add pip upgrade in secubox-core postinst for Debian bookworm compatibility
- Fix display/__init__.py to import existing modules only
Fixes authentication and API issues in VBox and ebin builds.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Add --nicbootprio1 0 and --nicbootprio2 0 to prevent VirtualBox
from attempting network boot when hard disk boot fails.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Provides common commands:
- secubox status - system and services overview
- secubox services - list all SecuBox services
- secubox logs [svc] - view service logs
- secubox restart/start/stop <svc> - manage services
- secubox info - system information
- secubox network - network configuration
- secubox version - version info
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Add tmpfiles.d/secubox.conf with mode 1777 (sticky + world-writable)
- Update postinst to create /run/secubox with correct permissions
- Run systemd-tmpfiles --create on package install
This fixes permission denied errors when services try to create
Unix sockets in /run/secubox directory.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This systemd service runs before all secubox services to create
the /run/secubox directory with correct ownership and permissions.
Fixes recurring issue where socket directory disappears causing
502 Bad Gateway errors and navbar showing only 2 categories.
- New oneshot service: secubox-runtime.service
- Runs before secubox-hub, secubox-portal, secubox-p2p
- Creates /run/secubox owned by secubox:secubox with mode 775
- Updated debian/rules to install the service
- Updated debian/postinst to enable the service
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Includes all package APIs with public dashboard endpoints:
- secubox-system: System Hub with /info, /resources, /security
- secubox-crowdsec: CrowdSec dashboard with /status, /hub, /metrics, actions
- secubox-wireguard: WireGuard VPN with /interfaces, /peers, start/stop
- secubox-netdata: Monitoring with /stats, /processes, /alerts
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>