Reinstall test on Debian 12 surfaced three rootless-only breakages (rooted was byte-identical/fine): 1. pasta blocked by Debian's passt AppArmor profile (DENIED ptrace read -> can't open container netns -> rootless dockerd never starts). Default CFG_ROOTLESS_NET back to slirp4netns (reliable); pasta stays selectable for hosts that relax the profile. 2. de-sudo mis-assigned helpers by owner. /docker management layer (apps DB chowned to libreportal by install_sqlite, /docker/logs) is MANAGER-owned, not dockerinstall. Add runInstallWrite; move apps-DB sqlite3 -> runInstallOp and /docker/logs appends -> runInstallWrite. Revert ownership-SETUP scripts (libreportal_folders, app_folder) to runSystem — they must run as root to establish ownership during install. Container files (/docker/containers/<app>) stay runFileOp. 3. kernel hardening sysctls written to /etc/sysctl/99-custom.conf, which 'sysctl --system' does not read -> never applied. Write them to /etc/sysctl.d/99-libreportal-hardening.conf instead. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com> Signed-off-by: librelad <librelad@digitalangels.vip>
89 lines
3.4 KiB
Bash
89 lines
3.4 KiB
Bash
#!/bin/bash
|
|
|
|
# Mode-aware privileged operations.
|
|
#
|
|
# The privilege a file operation needs depends on the Docker mode:
|
|
# rooted — app/container files under /docker are root-owned, so ops run via
|
|
# sudo. This is byte-for-byte the historical behaviour.
|
|
# rootless — those files are owned by the unprivileged Docker install user, so
|
|
# ops run AS that user (via `sudo -u`, no root over the data plane).
|
|
# Centralising the branch here means each call site is written once and is
|
|
# correct in both modes, and rooted installs (incl. live boxes) are unchanged.
|
|
|
|
# Run a /docker data-plane command — mkdir/chown/rm/cp/mv/find/sqlite3/etc. on
|
|
# app or container files.
|
|
# rooted -> sudo <cmd>
|
|
# rootless -> run <cmd> as the Docker install user (no sudo)
|
|
# Note: for stdin-fed writes (e.g. `… | sudo tee file`) use runFileWrite below;
|
|
# this helper is for self-contained commands.
|
|
runFileOp() {
|
|
if [[ "$CFG_DOCKER_INSTALL_TYPE" == "rootless" ]]; then
|
|
dockerCommandRunInstallUser --argv "$@"
|
|
else
|
|
sudo "$@"
|
|
fi
|
|
}
|
|
|
|
# Write stdin to a path with the right privilege (replaces `… | sudo tee path`).
|
|
# rooted -> sudo tee
|
|
# rootless -> tee as the Docker install user
|
|
# Pass -a/--append as the first arg to append instead of truncate (replaces
|
|
# `… | sudo tee -a path`, e.g. the /docker/logs log-append idiom).
|
|
# Usage: some_command | runFileWrite [-a] /path/to/file
|
|
runFileWrite() {
|
|
local append=""
|
|
if [[ "$1" == "-a" || "$1" == "--append" ]]; then
|
|
append=" -a"
|
|
shift
|
|
fi
|
|
local dest="$1"
|
|
if [[ "$CFG_DOCKER_INSTALL_TYPE" == "rootless" ]]; then
|
|
dockerCommandRunInstallUser "tee$append '$dest' >/dev/null"
|
|
else
|
|
sudo tee$append "$dest" >/dev/null
|
|
fi
|
|
}
|
|
|
|
# Genuine system-administration command (ufw/systemctl/apt/sysctl/useradd, /etc
|
|
# edits). Needs real root in both modes; kept as sudo and funnelled through one
|
|
# place so it can later be confined to a scoped sudoers allowlist.
|
|
runSystem() {
|
|
sudo "$@"
|
|
}
|
|
|
|
# Op on a MANAGER-owned path — the LibrePortal clone + shipped templates AND the
|
|
# /docker management layer the runtime owns (apps DB, configs/, logs/, scripts).
|
|
# In rootless these are owned by the manager user; ops on them need no privilege.
|
|
# rooted -> sudo <cmd> (root-owned; byte-identical)
|
|
# rootless -> <cmd> (runs as the current user: root at install-time,
|
|
# the manager user at runtime — both can access)
|
|
# Container-owned data under /docker/containers/<app>/ is NOT this — use runFileOp.
|
|
# For copies that read manager files and write container-owned ones, read here
|
|
# and pipe into runFileWrite so each side runs as the correct owner.
|
|
runInstallOp() {
|
|
if [[ "$CFG_DOCKER_INSTALL_TYPE" == "rootless" ]]; then
|
|
"$@"
|
|
else
|
|
sudo "$@"
|
|
fi
|
|
}
|
|
|
|
# Write stdin to a MANAGER-owned path (apps DB sidecars, configs/, logs/ — e.g.
|
|
# the /docker/logs log-append idiom). Mirror of runFileWrite for the manager
|
|
# owner. Pass -a/--append as the first arg to append.
|
|
# rooted -> sudo tee
|
|
# rootless -> tee as the current (manager) user
|
|
runInstallWrite() {
|
|
local append=""
|
|
if [[ "$1" == "-a" || "$1" == "--append" ]]; then
|
|
append=" -a"
|
|
shift
|
|
fi
|
|
local dest="$1"
|
|
if [[ "$CFG_DOCKER_INSTALL_TYPE" == "rootless" ]]; then
|
|
tee$append "$dest" >/dev/null
|
|
else
|
|
sudo tee$append "$dest" >/dev/null
|
|
fi
|
|
}
|