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>
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.sh → initRootHelpers (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