LibrePortal/FOOTPRINT.md
librelad 15fc42c858 refactor(layout): consolidate out-of-/docker files + fix sysctl dir
Organise the system footprint outside /docker:
- All LibrePortal executables now live together in /usr/local/lib/libreportal/
  (root:root): the 7 root helpers AND the CLI wrapper. /usr/local/bin/libreportal
  becomes a symlink onto $PATH. run_privileged._runRootHelper, init.sh
  (initRootHelpers + scoped-sudoers Cmnd_Alias + command setup) all point there.
  The wrapper is now root-owned too (manager can't tamper with its entrypoint).
- Fix a real bug: rootless sysctl settings were written to /etc/sysctl/99-custom.conf,
  a dir  does NOT read, so net.ipv4.ip_unprivileged_port_start /
  kernel.unprivileged_userns_clone never persisted across reboot. Moved to
  /etc/sysctl.d/99-libreportal-rootless.conf (the existing
  reload now actually applies them). Consistent libreportal* naming.
- Drop dead fqdn_file=/root/libreportal-fqdn.txt global (never used).
- Add FOOTPRINT.md: a manifest of every file LibrePortal places outside /docker
  (doubles as an uninstall checklist).

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Signed-off-by: librelad <librelad@digitalangels.vip>
2026-05-24 19:40:35 +01:00

3.0 KiB

LibrePortal system footprint (outside /docker)

Everything LibrePortal is lives under /docker (app data, configs, the install tree, the database). This file catalogues the few things it must place outside /docker to integrate with the host. The OS dictates where most of these live — sudoers, systemd units, sysctl, and $PATH entries can only be read from their fixed locations, so they can't all sit in one folder. What we control, we keep together in /usr/local/lib/libreportal/; everything else is named libreportal* so the whole footprint is greppable and removable.

Executables — /usr/local/lib/libreportal/ (root:root, our own dir)

File Owner Purpose
libreportal root the CLI wrapper (symlinked onto $PATH, see below)
libreportal-ownership root reconcile the /docker ownership model
libreportal-dns root edit /etc/resolv.conf (nameservers)
libreportal-ssh-access root manage admin authorized_keys + sshd PasswordAuthentication
libreportal-socket root docker-socket read perms (type switcher)
libreportal-svc root generate/install the task-processor systemd unit
libreportal-bininstall root install the restic/kopia backup-engine binaries
libreportal-appcfg root rewrite AdGuard/CrowdSec/ownCloud config files

These are the scoped-sudoers trust boundary: root-owned in a root-owned dir, so the manager can sudo them but can't modify them. Source of truth: scripts/system/ in the repo; installed by init.shinitRootHelpers (re-installed only on a reinstall, not by the quick-deploy).

OS-mandated locations (must live where the OS reads them)

Path Owner Purpose
/usr/local/bin/libreportal root symlink/usr/local/lib/libreportal/libreportal (puts the CLI on $PATH)
/etc/sudoers.d/libreportal root scoped least-privilege grant for the manager
/etc/systemd/system/libreportal.service root the task-processor service (User=libreportal)
/etc/sysctl.d/99-libreportal-hardening.conf root kernel LPE-surface hardening
/etc/sysctl.d/99-libreportal-rootless.conf root rootless sysctl settings + "rootless configured" marker

Third-party tools we install (not ours, conventional home)

/usr/local/bin/{restic,kopia,ufw-docker,docker-compose} — installed on demand (restic/kopia via the libreportal-bininstall helper). /usr/local/bin is the correct home for these; left under their own names.

System users

libreportal (the manager) and dockerinstall (the rootless docker user), each with a home under /home/. The rootless daemon config lives at ~dockerinstall/.config/docker/daemon.json.

Uninstall sketch

sudo systemctl disable --now libreportal.service
sudo rm -f /etc/systemd/system/libreportal.service /etc/sudoers.d/libreportal
sudo rm -f /etc/sysctl.d/99-libreportal-*.conf
sudo rm -rf /usr/local/lib/libreportal /usr/local/bin/libreportal
# optional: the backup-engine binaries, the users, and /docker itself