diff --git a/packages/secubox-profiles/debian/postinst b/packages/secubox-profiles/debian/postinst index b296a191..f896e9c1 100755 --- a/packages/secubox-profiles/debian/postinst +++ b/packages/secubox-profiles/debian/postinst @@ -25,16 +25,16 @@ case "$1" in fi done - # secubox-sleeper.service runs ProtectSystem=strict with an explicit - # ReadWritePaths= (see debian/secubox-sleeper.service) — every - # directory it lists MUST already exist before the unit's first - # start, or systemd's sandbox will not make it writable. Pre-create - # this package's own two leaves here (shared parents /var/lib/secubox - # and /var/log/secubox themselves come from secubox-core, 0755 - # secubox:secubox — reasserted here matching the repo-wide - # shared-parent convention, never narrowed to 0750). /run/secubox - # comes from RuntimeDirectory=secubox; /data/lxc and /etc/secubox/waf - # are provisioned by lxc/secubox-waf-ng respectively, not here. + # The actuator (api/actuate.py + snapshot.py + audit.py, driven both + # by secubox-profilectl apply/rollback and by secubox-sleeper's + # in-process STOPs) writes snapshot.SNAP_DIR and audit.AUDIT_LOG — + # pre-create both here so a fresh board has them before the first + # apply/sleep, regardless of unit sandboxing (secubox-sleeper.service + # is deliberately NOT ProtectSystem=strict, see its unit file, but + # these two leaves are needed either way). Shared parent + # /var/log/secubox comes from secubox-core (0755 secubox:secubox) — + # reasserted here matching the repo-wide shared-parent convention, + # never narrowed to 0750. install -d -o secubox -g secubox -m 0755 /var/log/secubox install -d -o root -g root -m 0750 /var/lib/secubox/profiles/rollback diff --git a/packages/secubox-profiles/debian/secubox-sleeper.service b/packages/secubox-profiles/debian/secubox-sleeper.service index 0c5c3c1c..852b074b 100644 --- a/packages/secubox-profiles/debian/secubox-sleeper.service +++ b/packages/secubox-profiles/debian/secubox-sleeper.service @@ -28,27 +28,24 @@ RuntimeDirectory=secubox RuntimeDirectoryPreserve=yes RuntimeDirectoryMode=0775 -# ProtectSystem=strict makes / read-only by default; the actuator's actual -# write set (traced through api/actuate.py, api/snapshot.py, api/audit.py — -# apply_plan's STOP path is the only one the sleeper ever drives) is listed -# explicitly below so this sandbox stays FUNCTIONAL, not just hardened: -# - /run/secubox — the socket dir + api.sleeper.WAKE_LOCK_FILE -# (read, but ReadWritePaths is directory-granular) and waker-active.json -# - /var/lib/secubox/profiles/rollback — snapshot.SNAP_DIR, the 4R chain -# shared with secubox-profilectl/secubox-wakectl (actuate_paths.py) -# - /var/log/secubox — audit.AUDIT_LOG (append-only audit.log) -# - /data/lxc — actuate.py::_lxc_autostart edits -# //config (lxc.start.auto) before lxc-stop -# - /etc/secubox/waf — actuate.py::ROUTES_FILE -# (haproxy-routes.json): a STOP on a routed module calls -# _portal_remove, which rewrites this file (temp+rename in the SAME -# directory) — omitting it here would reproduce, one layer up, the -# exact EROFS lesson that motivated wrapping the OTHER two ctls in -# systemd-run in the first place (secubox-profilectl 0.6.1). -ProtectSystem=strict +# Deliberately NOT ProtectSystem=strict (ref #896 T12 review). This daemon +# drives lxc-start/lxc-stop + systemctl IN-PROCESS as root — unlike the +# panel/waker, which escape their own sandbox via systemd-run into PID1's +# context before touching systemd/LXC. lxc-start/lxc-stop write LXC-internal +# runtime/lock paths (/run/lxc/, /run/lock/lxc/, cgroup + mount-namespace +# setup) that are no part of this codebase's stable contract to enumerate; +# under ProtectSystem=strict everything under /run outside an explicit +# ReadWritePaths entry is read-only, so those writes would EROFS — silently, +# since api/actuate.py::_issue only hard-fails on rc is None, meaning +# auto-sleep for every LXC-backed on-demand module would quietly stop +# working (the whole RAM-savings target of ref #896). A root daemon that +# drives LXC in-process without ProtectSystem is at this codebase's normal +# floor (many root daemons here have no sandboxing) — dropping strict here +# is a fix, not a regression. ProtectHome/PrivateTmp stay: the actuator +# needs neither /home nor a shared /tmp (its atomic writes are all +# temp-file-in-target-dir, not /tmp). ProtectHome=true PrivateTmp=true -ReadWritePaths=/run/secubox /var/lib/secubox/profiles/rollback /var/log/secubox /data/lxc /etc/secubox/waf [Install] WantedBy=multi-user.target