Compare commits

..

No commits in common. "b985db14ff426f461ca519b68131837570718101" and "b2891ff4d225bc0a9a89dc9c4a52dffa95da8b48" have entirely different histories.

21 changed files with 22 additions and 201 deletions

View File

@ -20,17 +20,8 @@
#494 secubox-core ExecStart · #498 Phase 7 WAF enforcement · #485 SOC scoring.
### 🔎 Reco T0 — recon live gk2 2026-06-24 (avant fix)
- ✅ **#494** : **FIX SYSTÉMIQUE poussé** (`fix/494-…`). Pas que core : 7 units re-chownaient
le parent partagé `/run/secubox` (core+hub services, eye-remote/eye-square/metablogizer/
metrics/p2p postinsts ; eye-square chownait aussi /var/log/secubox = pire). Tous nettoyés
(mkdir fallback only ; logs modules en sous-dossier propre ; orphan /etc/tmpfiles.d nettoyé).
**Vérifié live** : /run/secubox 1777 **root:root** stable après restart core ET hub ; webui 200.
Bumps core 1.1.7/hub 1.4.4/eye-remote 1.0.1/eye-square 1.0.4/metablog 1.2.2/metrics 1.0.4/p2p 1.7.1.
- ✅ **#471** (mesh /run/secubox) : déjà résolu (changelog mesh "drop install -d /run/secubox") → verify-close.
- ⬜ **#421** : sockets cachés en mount-ns privé (RuntimeDirectory) — mécanisme distinct, non traité.
- 🆕 Suivi (classe #511) : mesh/toolbox/admin font `install -d -o <module> /var/log/secubox`
(propriétaire du parent partagé = user module) → autres daemons ne peuvent créer leurs logs.
Séparé de #494, à traiter (sous-dossiers propres comme fait pour eye-square/p2p).
- **#494/#471/#421** : la vraie régression live = `/run/secubox` = 1777 **secubox:secubox**
(règle dure = 1777 **root:root**). Possédé par le worktree `fix/494-…` → ne pas collisionner.
- **#447** : pas une fuite — `password_hash=null` → lockout kiosk + user CI parasite ;
**CI-image-gated** (rpi400, pas gk2).
- **#91** : `haproxy.cfg` active valide ; backup `*.broken-by-haproxyctl-*` prouve le bug

View File

@ -55,13 +55,4 @@ server {
proxy_pass http://unix:/run/secubox/system.sock:/;
include /etc/nginx/snippets/secubox-proxy.conf;
}
# #65: per-module routes self-register here. Every module package drops a
# /etc/nginx/secubox-routes.d/<module>.conf (location-only snippet) at
# install time, so a newly added module's /<module>/ + /api/v1/<module>/
# routes are picked up automatically — no more hand-editing this file per
# module. This is the ACTIVE include (matches the deployed webui.conf).
# The crowdsec/waf/system blocks above stay hardcoded: those core packages
# only ship the legacy secubox.d/ snippet, so they would NOT duplicate here.
include /etc/nginx/secubox-routes.d/*.conf;
}

View File

@ -1,38 +1,3 @@
secubox-core (1.1.10-1~bookworm1) bookworm; urgency=medium
* #421/#494: secubox-dirs-guard now also re-asserts /run/secubox to
1777 root:root every minute. 90+ services declare RuntimeDirectory=secubox,
so systemd re-chowns the shared socket parent to secubox:secubox 0755 on
each (re)start — which locks out services that create their socket as a
non-secubox user (e.g. secubox-blacklist-attrib "Permission denied").
Removing the explicit chowns (#494) was necessary but not sufficient against
the RuntimeDirectory churn; the guard now self-heals it centrally instead of
patching 90+ unit files.
-- Gerald KERMA <devel@cybermind.fr> Wed, 24 Jun 2026 11:15:00 +0000
secubox-core (1.1.9-1~bookworm1) bookworm; urgency=medium
* #494 fix: secubox-core.service no longer chowns /run/secubox to
secubox:secubox + chmod 775 in ExecStart. Running After=network.target,
it fired LAST and clobbered the canonical tmpfiles rule
(`d /run/secubox 1777 root root`) that secubox-runtime.service had just
re-applied — leaving the dir secubox:secubox so non-secubox daemons lost
parent +x and their sockets 502'd. /run/secubox lifecycle is now owned
solely by tmpfiles.d (1777 root root) + secubox-runtime.service; this unit
only manages the www-data group membership. Complements the #623 sweep
(which covered /var/lib,/var/log,/var/cache,/etc,/usr/share — not /run).
* Defensive: postinst removes a stale, non-dpkg-owned
/etc/tmpfiles.d/secubox.conf if it declares /run/secubox as
0775 secubox secubox (leftover from an old manual fix; /etc overrides
/usr/lib so it contradicted the canonical rule). The shipped canonical
file is /usr/lib/tmpfiles.d/secubox.conf.
* Also ensure /var/log/suricata exists (0755) so services with
ReadWritePaths=/var/log/suricata (secubox-threats/suricata) don't
NAMESPACE-fail at start.
-- Gerald KERMA <devel@cybermind.fr> Wed, 24 Jun 2026 10:30:00 +0000
secubox-core (1.1.8-1~bookworm1) bookworm; urgency=medium
* fix(#623): tmpfiles.d now declares all shared secubox parents

View File

@ -26,16 +26,6 @@ case "$1" in
install -d -o secubox -g secubox -m 755 /usr/share/secubox/www
# ── tmpfiles.d for persistent /run/secubox ──
# #494: drop a stale, non-dpkg-owned /etc/tmpfiles.d/secubox.conf left over
# from an old manual fix — it declares /run/secubox as 0775 secubox secubox
# and, because /etc overrides /usr/lib, it contradicts the canonical rule
# (/usr/lib/tmpfiles.d/secubox.conf: 1777 root root). Only remove it if it
# is NOT owned by any package and carries that bad declaration.
if [ -f /etc/tmpfiles.d/secubox.conf ] \
&& ! dpkg -S /etc/tmpfiles.d/secubox.conf >/dev/null 2>&1 \
&& grep -qE '/run/secubox[[:space:]]+0?775[[:space:]]+secubox' /etc/tmpfiles.d/secubox.conf; then
rm -f /etc/tmpfiles.d/secubox.conf
fi
systemd-tmpfiles --create 2>/dev/null || true
# ── Config initiale si absente ──

View File

@ -5,26 +5,10 @@ After=network.target
[Service]
Type=oneshot
RemainAfterExit=yes
# Phase 3 (#494) : /run/secubox is owned by tmpfiles.d at 1777 root:root.
# The previous ExecStart sequence (mkdir + chown secubox:secubox + chmod 775)
# ran AFTER tmpfiles.d and silently regressed the dir to 775, breaking cross-
# user traversal for daemons running as users other than secubox (e.g.
# secubox-threats which 226/NAMESPACE-failed because ReadWritePaths bind
# couldn't cross 775 secubox:secubox + missing /var/log/suricata). See
# secubox-core/debian/changelog 1.1.7 for the failure post-mortem.
#
# /run/secubox lifecycle is now :
# 1. tmpfiles.d/secubox.conf creates 1777 root:root
# 2. this service is a no-op for /run/secubox (NOT touched)
# 3. each module's postinst chmods its own socket via UMask if needed
# /var/log/suricata must exist for any service whose ReadWritePaths references
# it (secubox-threats, secubox-suricata). Create idempotently.
ExecStart=/bin/mkdir -p /var/log/suricata
ExecStart=/bin/sh -c "chown secubox:secubox /var/log/suricata 2>/dev/null || true"
ExecStart=/bin/chmod 0755 /var/log/suricata
# Add www-data to secubox group (for nginx static-file access).
ExecStart=/bin/mkdir -p /run/secubox
ExecStart=/bin/chown secubox:secubox /run/secubox
ExecStart=/bin/chmod 775 /run/secubox
# Add www-data to secubox group if not already (for nginx access)
ExecStart=/bin/sh -c "id -nG www-data | grep -q secubox || usermod -aG secubox www-data"
[Install]

View File

@ -10,17 +10,4 @@ for d in /var/lib/secubox /var/log/secubox /var/cache/secubox /etc/secubox /usr/
[ -d "$d" ] || continue
[ "$(stat -c %a "$d" 2>/dev/null)" = "755" ] || chmod 0755 "$d" 2>/dev/null || true
done
# /run/secubox is the world-writable socket dir and MUST stay 1777 root:root so
# a service running as ANY user can create its own socket. 90+ services declare
# `RuntimeDirectory=secubox`, which makes systemd re-chown the parent to
# secubox:secubox 0755 on every (re)start — locking out non-secubox socket
# creators (e.g. blacklist-attrib: "Permission denied") (#421/#494). Re-assert
# the canonical perms here so that flapping self-heals each minute.
if [ -d /run/secubox ]; then
[ "$(stat -c '%a %U %G' /run/secubox 2>/dev/null)" = "1777 root root" ] || {
chown root:root /run/secubox 2>/dev/null || true
chmod 1777 /run/secubox 2>/dev/null || true
}
fi
exit 0

View File

@ -1,10 +1,3 @@
secubox-eye-remote (1.0.1-1~bookworm1) bookworm; urgency=medium
* #494: postinst no longer chowns the shared /run/secubox parent to
secubox:secubox (tmpfiles.d owns it 1777 root root).
-- Gerald KERMA <devel@cybermind.fr> Wed, 24 Jun 2026 10:45:00 +0000
secubox-eye-remote (1.0.0-1) bookworm; urgency=medium
* Initial release

View File

@ -8,10 +8,9 @@ case "$1" in
# Reload udev rules
udevadm control --reload-rules || true
# Create runtime directory (fallback). #494: never chown the shared
# parent — it is owned by tmpfiles.d (1777 root root); chowning it to
# secubox:secubox breaks cross-user socket traversal.
# Create runtime directory
mkdir -p /run/secubox
chown secubox:secubox /run/secubox 2>/dev/null || true
# Ensure config dirs exist with correct ownership.
# 0755 on eye-remote/ so the dnsmasq daemon (running as dnsmasq:nogroup

View File

@ -1,11 +1,3 @@
secubox-eye-square (1.0.4-1~bookworm1) bookworm; urgency=medium
* #494/#511: postinst no longer chowns the shared parents /run/secubox and
/var/log/secubox to secubox-eye-square (it stripped every other daemon's
traversal/log access). Logs go to an own subdir /var/log/secubox/eye-square.
-- Gerald KERMA <devel@cybermind.fr> Wed, 24 Jun 2026 10:45:00 +0000
secubox-eye-square (1.0.3-1~bookworm1) bookworm; urgency=medium
* Relocate firstboot.sh from /usr/local/sbin/ to /usr/lib/secubox/

View File

@ -8,15 +8,9 @@ case "$1" in
useradd --system --no-create-home --shell /usr/sbin/nologin secubox-eye-square
fi
# Ensure runtime + audit dirs.
# #494/#511: NEVER chown the shared parents (/run/secubox,
# /var/log/secubox) to a module user — that strips other daemons of
# traversal and 502s the whole board. The parents are owned by
# tmpfiles.d/secubox-core (1777 root root / 0755). This module creates
# its socket inside the 1777 sticky dir and logs into its OWN subdir.
# Ensure runtime + audit dirs
mkdir -p /run/secubox /var/log/secubox
install -d -o secubox-eye-square -g secubox-eye-square -m 0750 \
/var/log/secubox/eye-square
chown secubox-eye-square:secubox-eye-square /run/secubox /var/log/secubox
# Activate AppArmor profile
if command -v apparmor_parser >/dev/null 2>&1; then

View File

@ -1,12 +1,3 @@
secubox-hub (1.4.7-1~bookworm1) bookworm; urgency=medium
* #494: drop the ExecStartPre chown/chmod of the shared /run/secubox parent.
It ran on every hub start and clobbered the canonical tmpfiles rule
(1777 root root) back to 775 secubox:secubox, 502'ing cross-user socket
traversal. The 1777 sticky parent already lets the hub create its socket.
-- Gerald KERMA <devel@cybermind.fr> Wed, 24 Jun 2026 10:45:00 +0000
secubox-hub (1.4.6-1~bookworm1) bookworm; urgency=medium
* perf(#644): dashboard/status/modules/alerts + public/health-batch now served

View File

@ -10,13 +10,10 @@ User=secubox
Group=secubox
WorkingDirectory=/usr/lib/secubox/hub
# Ensure /run/secubox exists before starting (fallback if secubox-core didn't run)
# + prefix runs as root regardless of User= setting.
# #494: do NOT chown/chmod the parent here — it is owned by tmpfiles.d
# (1777 root root) + secubox-runtime.service. This ExecStartPre ran on every
# hub (re)start and clobbered it back to 775 secubox:secubox, breaking
# cross-user socket traversal (nginx/www-data 502). The sticky 1777 parent
# already lets the hub create its own socket; only mkdir as a fallback.
# + prefix runs as root regardless of User= setting
ExecStartPre=+/bin/mkdir -p /run/secubox
ExecStartPre=+/bin/chown secubox:secubox /run/secubox
ExecStartPre=+/bin/chmod 775 /run/secubox
# TCP binding for VM compatibility (Unix socket has issues in some VMs)
ExecStart=/usr/bin/python3 -m uvicorn api.main:app \
--host 127.0.0.1 --port 8001 \

View File

@ -1,10 +1,3 @@
secubox-metablogizer (1.2.2-1~bookworm1) bookworm; urgency=medium
* #494: postinst no longer chowns the shared /run/secubox parent; only the
module's own /srv/metablogizer/sites is owned (see also #121).
-- Gerald KERMA <devel@cybermind.fr> Wed, 24 Jun 2026 10:45:00 +0000
secubox-metablogizer (1.2.1-1~bookworm1) bookworm; urgency=medium
* debian/secubox-metablogizer.service: lower uvicorn --log-level from

View File

@ -1,9 +1,7 @@
#!/bin/bash
set -e
mkdir -p /run/secubox /srv/metablogizer/sites
# #494: do NOT chown the shared parent /run/secubox (owned by tmpfiles.d at
# 1777 root root). Only own this module's own data dir.
chown secubox:secubox /srv/metablogizer/sites 2>/dev/null || true
chown secubox:secubox /run/secubox /srv/metablogizer/sites 2>/dev/null || true
systemctl daemon-reload
systemctl enable secubox-metablogizer 2>/dev/null || true
systemctl start secubox-metablogizer 2>/dev/null || true

View File

@ -1,10 +1,3 @@
secubox-metrics (1.0.4-1~bookworm1) bookworm; urgency=medium
* #494: postinst no longer chowns the shared /run/secubox parent
(tmpfiles.d owns it 1777 root root).
-- Gerald KERMA <devel@cybermind.fr> Wed, 24 Jun 2026 10:45:00 +0000
secubox-metrics (1.0.3-1~bookworm1) bookworm; urgency=medium
* VisitorOrigin: add AmbientCapabilities=CAP_NET_ADMIN to the systemd

View File

@ -8,9 +8,9 @@ case "$1" in
useradd -r -s /usr/sbin/nologin -d /var/lib/secubox secubox
fi
# Create runtime directory (fallback). #494: never chown the shared
# parent /run/secubox — it is owned by tmpfiles.d (1777 root root).
# Create runtime directory
mkdir -p /run/secubox
chown secubox:secubox /run/secubox
# Cache directory — was /tmp/secubox until #149. Now /var/cache/secubox,
# auto-managed by systemd's CacheDirectory=secubox at unit start.

View File

@ -1,10 +1,3 @@
secubox-p2p (1.7.1-1~bookworm1) bookworm; urgency=medium
* #494/#511: postinst no longer chowns the shared parents /run/secubox and
/var/log/secubox; logs go to an own subdir /var/log/secubox/p2p.
-- Gerald KERMA <devel@cybermind.fr> Wed, 24 Jun 2026 10:45:00 +0000
secubox-p2p (1.7.0-1~bookworm1) bookworm; urgency=medium
* Absorb the master-link role from secubox-master-link (closes #384)

View File

@ -8,15 +8,15 @@ case "$1" in
adduser --system --group --home /var/lib/secubox --no-create-home secubox
fi
# Create runtime directory (fallback). #494: never chown/chmod the
# shared parent /run/secubox — tmpfiles.d owns it (1777 root root);
# overriding it breaks cross-user socket traversal.
# Create runtime directory
mkdir -p /run/secubox
chown secubox:secubox /run/secubox
chmod 755 /run/secubox
# Log dir: own a subdir, do NOT chown the shared /var/log/secubox
# parent (#494/#511 — that strips other modules' log access).
# Create log directory
mkdir -p /var/log/secubox
install -d -o secubox -g secubox -m 0750 /var/log/secubox/p2p
chown secubox:secubox /var/log/secubox
chmod 755 /var/log/secubox
# Enable and start the service
systemctl daemon-reload

View File

@ -1,15 +1,3 @@
secubox-wazuh (1.0.1-1~bookworm1) bookworm; urgency=medium
* #53 fix: stop the 100% CPU spin on boards without Wazuh. The uvicorn worker
was started unconditionally even though SecuBox's IDS/IPS stack is
Suricata + CrowdSec and /var/ossec is absent, so it busy-looped for nothing.
Gate the unit with ConditionPathExists=/var/ossec/etc/ossec.conf — systemd
now reports "inactive (condition failed)" and never starts it unless a local
Wazuh agent/manager is installed. Add RestartSec=5 as a hot-respawn guard.
Module kept (opt-in SIEM integration), not removed.
-- Gerald KERMA <devel@cybermind.fr> Wed, 24 Jun 2026 10:00:00 +0000
secubox-wazuh (1.0.0-1) stable; urgency=low
* Initial release

View File

@ -1,13 +1,6 @@
[Unit]
Description=SecuBox Wazuh API
After=network.target secubox-core.service
# #53: this API only does anything when a local Wazuh agent/manager is present
# (/var/ossec, port 55000). SecuBox's documented IDS/IPS stack is Suricata +
# CrowdSec, so on every normal board Wazuh is absent and the uvicorn worker just
# burned 100% CPU for nothing. Gate the unit on Wazuh actually being installed:
# systemd reports "inactive (condition failed)" and never starts it otherwise.
# Remote-API-only integrations (no local ossec) should drop this condition.
ConditionPathExists=/var/ossec/etc/ossec.conf
[Service]
Type=simple
@ -16,8 +9,6 @@ WorkingDirectory=/usr/lib/secubox/wazuh
ExecStart=/usr/bin/python3 -m uvicorn api.main:app --uds /run/secubox/wazuh.sock --log-level warning
UMask=0117
Restart=on-failure
# Defensive: never hot-respawn (the default ~100ms churns CPU on its own).
RestartSec=5
[Install]
WantedBy=multi-user.target

View File

@ -50,12 +50,6 @@ fi
cd "\$SITE"
# #121: every git op below runs as root (ssh root@host), so a freshly created
# .git ends up root:root — but metablogizer runs as 'secubox' and must be able
# to write the repo (webhook deploys, sub-E #113). Re-own the site dir after any
# ingest that touches .git. Matches the chown pattern in module postinsts.
fix_perms() { chown -R secubox:secubox "\$SITE" 2>/dev/null || true; }
# Determine remote HEAD (might fail if repo doesn't exist yet — that's OK)
remote_head=\$(git ls-remote "\$REPO_URL" main 2>/dev/null | awk '{print \$1}' || true)
@ -82,7 +76,6 @@ if [[ -d .git ]]; then
fi
git tag -f v1.0.0
git push --quiet --force origin v1.0.0
fix_perms
echo "ingested-with-history"
exit 0
fi
@ -102,7 +95,6 @@ if [[ -d .git ]]; then
git push --quiet origin main
git tag v1.0.0
git push --quiet origin v1.0.0
fix_perms
echo "ingested-fresh"
exit 0
else
@ -121,7 +113,6 @@ else
git push --quiet origin main
git tag v1.0.0
git push --quiet origin v1.0.0
fix_perms
echo "ingested-fresh"
exit 0
fi