Give dockerCommandRunInstallUser an --argv mode that execs arguments verbatim (sudo -u <user> env ... "$@") instead of bash -c "$*", and point runFileOp at it. The old $*+bash -c re-parse silently mangled backslashes/quotes in args — e.g. sed scripts (\1, \( become 1, ( ) and the sqlite3 .backup arg — so rootless data-plane ops with regex were broken. Verified: the WG_DEFAULT_DNS sed now applies correctly as the install user. All existing runFileOp callers pass plain commands, so the switch is safe (and fixes the latent sqlite3 case). Convert scripts/network/dns/setup_dns.sh: /etc/resolv.conf edits and ping -> runSystem; the WG_DEFAULT_DNS compose-file sed -> runFileOp. Byte-identical in rooted; correct in rootless. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com> Signed-off-by: librelad <librelad@digitalangels.vip>
61 lines
2.4 KiB
Bash
Executable File
61 lines
2.4 KiB
Bash
Executable File
#!/bin/bash
|
|
|
|
# Run a command as the unprivileged rootless Docker install user.
|
|
#
|
|
# This used to ssh to <user>@localhost to get a fully-initialised user session
|
|
# (so `systemctl --user` and the rootless dockerd would work). That needs an SSH
|
|
# server, a generated key and authorized_keys — none of which the install set
|
|
# up, so the whole rootless path silently no-op'd. Instead run via `sudo -u`
|
|
# with the session env set explicitly: `loginctl enable-linger` (done during
|
|
# rootless setup) keeps the user's `systemd --user` and /run/user/<uid> alive,
|
|
# so `systemctl --user` works, and DOCKER_HOST points at the rootless socket.
|
|
# `sudo -u` to an unprivileged user is not a root escalation, and there's no SSH
|
|
# attack surface.
|
|
dockerCommandRunInstallUser()
|
|
{
|
|
local silent_flag=""
|
|
local argv_mode=""
|
|
while true; do
|
|
case "$1" in
|
|
--silent) silent_flag="1"; shift ;;
|
|
--argv) argv_mode="1"; shift ;;
|
|
*) break ;;
|
|
esac
|
|
done
|
|
|
|
local uid
|
|
uid=$(id -u "$CFG_DOCKER_INSTALL_USER" 2>/dev/null)
|
|
if [ -z "$uid" ]; then
|
|
isError "Cannot run as '$CFG_DOCKER_INSTALL_USER' — user does not exist."
|
|
return 1
|
|
fi
|
|
|
|
# rootless docker installs its binaries to the user's ~/bin, so include it.
|
|
local run_env=(
|
|
"HOME=/home/$CFG_DOCKER_INSTALL_USER"
|
|
"XDG_RUNTIME_DIR=/run/user/$uid"
|
|
"DBUS_SESSION_BUS_ADDRESS=unix:path=/run/user/$uid/bus"
|
|
"DOCKER_HOST=unix:///run/user/$uid/docker.sock"
|
|
"PATH=/home/$CFG_DOCKER_INSTALL_USER/bin:/usr/bin:/bin:/usr/local/bin"
|
|
)
|
|
|
|
# --argv: exec the remaining args verbatim (no shell re-parse) so regex/
|
|
# quotes/backslashes in arguments (e.g. sed scripts) survive intact. Default:
|
|
# treat $1 as a shell snippet via bash -c (needed for pipes/redirects/
|
|
# systemctl --user/etc.).
|
|
if [ -n "$argv_mode" ]; then
|
|
if [ -n "$silent_flag" ]; then
|
|
sudo -u "$CFG_DOCKER_INSTALL_USER" env "${run_env[@]}" "$@" >/dev/null 2>&1
|
|
else
|
|
sudo -u "$CFG_DOCKER_INSTALL_USER" env "${run_env[@]}" "$@"
|
|
fi
|
|
else
|
|
local remote_command="$1"
|
|
if [ -n "$silent_flag" ]; then
|
|
sudo -u "$CFG_DOCKER_INSTALL_USER" env "${run_env[@]}" bash -c "$remote_command" >/dev/null 2>&1
|
|
else
|
|
sudo -u "$CFG_DOCKER_INSTALL_USER" env "${run_env[@]}" bash -c "$remote_command"
|
|
fi
|
|
fi
|
|
}
|