LibrePortal/scripts/docker/command/run_privileged.sh
librelad 0c719b5912 harden(desudo): add runInstallOp helper + convert adguard/traefik/crowdsec/dashy
- New runInstallOp helper for manager install-dir/template ops (rooted:
  sudo; rootless: run as the current manager user, which owns the tree).
- adguard.sh, traefik.sh: container-config sed -> runFileOp.
- crowdsec.sh: host crowdsec systemctl/apt-get -> runSystem.
- dashy_update_conf.sh: conf-file mkdir/chown/md5sum/tee -> runFileOp/
  runFileWrite; docker ps/restart -> dockerCommandRun.
Deferred (cross-owner copy / temp-file across /tmp<->/docker, need rootless
env to bridge correctly): owncloud_setup_config.sh, adguard_auth.sh.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Signed-off-by: librelad <librelad@digitalangels.vip>
2026-05-23 23:45:42 +01:00

68 lines
2.6 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 the manager install dir / shipped templates — the LibrePortal clone and
# its container templates, owned by the manager user that runs the runtime.
# rooted -> sudo <cmd> (install tree is root-owned; byte-identical)
# rootless -> <cmd> (the manager user already owns it — no privilege)
# For copies that read the install tree and write into /docker (two different
# owners in rootless), don't use this for the whole copy — 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
}