fix(install): broad sudo during install, tighten to scoped only after
The install hands the heavy setup to the manager (completeInitMessage: sudo -u libreportal 'libreportal run install') — creating the docker-install user, rootless setup, apt, sysctl — which needs broad root. initUsers was installing the SCOPED sudoers up front, so that handoff died with 'sudo: a password is required' on useradd. Fix: initUsers installs a temporary NOPASSWD: ALL for the install phase; completeInitMessage calls the new initScopedSudoers to tighten to the runtime allowlist only after the install succeeds (on failure, broad sudo is left so the manual 'libreportal run install' retry works). This restores the documented 'kill NOPASSWD:ALL AFTER the runtime is set up' ordering. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com> Signed-off-by: librelad <librelad@digitalangels.vip>
This commit is contained in:
parent
d7aae3f47e
commit
c63cb4a2a7
58
init.sh
58
init.sh
@ -698,16 +698,42 @@ initUsers()
|
||||
sudo systemctl restart docker
|
||||
isSuccessful "User $sudo_user_name created successfully."
|
||||
fi
|
||||
# Manager-user sudo: a SCOPED, validated /etc/sudoers.d drop-in (NOT
|
||||
# NOPASSWD: ALL, and never appended to /etc/sudoers — a malformed main file
|
||||
# locks out sudo entirely). Under Model A the runtime runs AS this user and
|
||||
# reaches root ONLY via: the unprivileged docker-install user (data plane,
|
||||
# confined by rootless), the root-owned /usr/local/lib/libreportal/ helpers
|
||||
# (each a fixed, self-validated op the manager can't modify), and a fixed set
|
||||
# of system binaries. Deliberately excluded: bash/su and tee/cp/chmod/chown/
|
||||
# sed/mv/rm/install (each root-equivalent). See scripts/system/libreportal-*.
|
||||
# Install-phase sudo: the heavy install runs AS this user (see the handoff in
|
||||
# completeInitMessage) and needs BROAD root — useradd for the docker-install
|
||||
# user, rootless setup, apt, sysctl, etc. So grant a temporary validated
|
||||
# NOPASSWD: ALL drop-in now (never appended to /etc/sudoers — a malformed main
|
||||
# file locks out sudo entirely); completeInitMessage calls initScopedSudoers
|
||||
# to tighten it to the scoped RUNTIME allowlist once the install succeeds.
|
||||
local sudoers_dropin="/etc/sudoers.d/${sudo_user_name}"
|
||||
local install_user="${CFG_DOCKER_INSTALL_USER:-dockerinstall}"
|
||||
local sudoers_tmp
|
||||
sudoers_tmp=$(mktemp)
|
||||
printf '%s ALL=(ALL) NOPASSWD: ALL\n' "$sudo_user_name" > "$sudoers_tmp"
|
||||
if sudo visudo -cf "$sudoers_tmp" >/dev/null 2>&1; then
|
||||
sudo install -m 0440 -o root -g root "$sudoers_tmp" "$sudoers_dropin"
|
||||
isSuccessful "Configured install-phase sudo for $sudo_user_name (tightened after install)."
|
||||
else
|
||||
isError "Refusing to install an invalid sudoers drop-in for $sudo_user_name."
|
||||
fi
|
||||
rm -f "$sudoers_tmp"
|
||||
|
||||
initRootHelpers
|
||||
}
|
||||
|
||||
# Tighten the manager's sudo from the install-phase NOPASSWD: ALL down to the
|
||||
# scoped RUNTIME allowlist. Called AFTER the (manager-run) install phase, which
|
||||
# needs the broad root this deliberately withholds. The runtime then reaches root
|
||||
# ONLY via: the unprivileged docker-install user (data plane, rootless-confined),
|
||||
# the root-owned /usr/local/lib/libreportal/ helpers (each a fixed, self-validated
|
||||
# op the manager can't modify), and a fixed system-binary set. Excluded:
|
||||
# bash/su + tee/cp/chmod/chown/sed/mv/rm/install (each root-equivalent). Also
|
||||
# clears legacy broad grants (a NOPASSWD: ALL in the main /etc/sudoers, sudo-group
|
||||
# membership). See FOOTPRINT.md.
|
||||
initScopedSudoers()
|
||||
{
|
||||
local sudoers_dropin="/etc/sudoers.d/${sudo_user_name}"
|
||||
local install_user
|
||||
install_user=$(grep -h '^CFG_DOCKER_INSTALL_USER=' "$configs_dir/general/general_docker_install" 2>/dev/null | head -1 | cut -d= -f2 | awk '{print $1}')
|
||||
install_user="${install_user:-${CFG_DOCKER_INSTALL_USER:-dockerinstall}}"
|
||||
local sudoers_tmp
|
||||
sudoers_tmp=$(mktemp)
|
||||
cat > "$sudoers_tmp" <<EOF
|
||||
@ -727,9 +753,7 @@ ${sudo_user_name} ALL=(root) NOPASSWD: LP_HELPERS, LP_SYSTEM
|
||||
EOF
|
||||
if sudo visudo -cf "$sudoers_tmp" >/dev/null 2>&1; then
|
||||
sudo install -m 0440 -o root -g root "$sudoers_tmp" "$sudoers_dropin"
|
||||
# Defensive cleanup of legacy broad grants from older installs: a
|
||||
# NOPASSWD: ALL line appended to the main /etc/sudoers, plus sudo-group
|
||||
# membership (the scoped drop-in is user-specific; the group isn't needed).
|
||||
# Clear legacy broad grants from older installs.
|
||||
if sudo grep -qE "^${sudo_user_name}[[:space:]]+ALL=\(ALL\)[[:space:]]+NOPASSWD:[[:space:]]+ALL" /etc/sudoers 2>/dev/null; then
|
||||
local main_tmp; main_tmp=$(mktemp)
|
||||
sudo grep -vE "^${sudo_user_name}[[:space:]]+ALL=\(ALL\)[[:space:]]+NOPASSWD:[[:space:]]+ALL$" /etc/sudoers > "$main_tmp"
|
||||
@ -737,13 +761,11 @@ EOF
|
||||
rm -f "$main_tmp"
|
||||
fi
|
||||
sudo gpasswd -d "$sudo_user_name" sudo >/dev/null 2>&1 || true
|
||||
isSuccessful "Configured scoped passwordless sudo for $sudo_user_name (/etc/sudoers.d/${sudo_user_name})."
|
||||
isSuccessful "Tightened $sudo_user_name sudo to the scoped runtime allowlist."
|
||||
else
|
||||
isError "Refusing to install an invalid sudoers drop-in for $sudo_user_name."
|
||||
isError "Invalid scoped sudoers — left install-phase sudo in place for $sudo_user_name."
|
||||
fi
|
||||
rm -f "$sudoers_tmp"
|
||||
|
||||
initRootHelpers
|
||||
}
|
||||
|
||||
# Install the root-owned privilege helpers. Under Model A the runtime runs AS the
|
||||
@ -1260,7 +1282,9 @@ completeInitMessage()
|
||||
|
||||
# Switch to libreportal user and run the install command
|
||||
if sudo -u "$sudo_user_name" LIBREPORTAL_SKIP_LOGO=1 bash -c "libreportal run install"; then
|
||||
:
|
||||
# Install done — tighten the manager's broad install-phase sudo down to
|
||||
# the scoped runtime allowlist.
|
||||
initScopedSudoers
|
||||
else
|
||||
echo ""
|
||||
echo "⚠️ LibrePortal installation encountered issues."
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user