diff --git a/init.sh b/init.sh index 677b5fd..3995ef7 100755 --- a/init.sh +++ b/init.sh @@ -21,6 +21,8 @@ # (Also: LP_CONTAINERS_DIR.) Put on its own disk if wanted. # --backups-dir=PATH Root for backup repos. Default /libreportal-backups. # (Also: LP_BACKUPS_DIR.) Point at a separate disk/mount. +# --manager-user=NAME Control-plane manager user (owns the install, runs the +# runtime). Default libreportal. (Also: LP_MANAGER_USER.) # --allow-home Permit a containers/backups root inside /home/ # (needs rootless o+x traversal of that home — a privacy # trade-off; refused without this flag). @@ -109,7 +111,11 @@ init_skip_docker_images=false init_allow_home=false install_param="init" -sudo_user_name=libreportal +# Control-plane manager user — configurable via --manager-user= / LP_MANAGER_USER +# (default libreportal). Resolved early here (sudo_bashrc needs it); re-resolved +# after flag parsing in libreportalDerivePaths, and baked into the helpers/unit/ +# wrapper at install (the __MANAGER__ placeholder). +sudo_user_name="${LP_MANAGER_USER:-libreportal}" sshd_config="/etc/ssh/sshd_config" sudo_bashrc="/home/$sudo_user_name/.bashrc" hosts_file="/etc/hosts" @@ -159,6 +165,10 @@ libreportalDerivePaths() { install_scripts_dir="$script_dir/scripts/" containers_dir="$LP_CONTAINERS_DIR/" backup_dir="$LP_BACKUPS_DIR" + + # Control-plane manager user (configurable; default libreportal). + sudo_user_name="${LP_MANAGER_USER:-${sudo_user_name:-libreportal}}" + sudo_bashrc="/home/$sudo_user_name/.bashrc" } libreportalDerivePaths @@ -167,6 +177,12 @@ libreportalDerivePaths # an unsafe choice; the root helpers also re-check at runtime (defence in depth). libreportalValidatePaths() { local pair name d + # Manager username: must be a valid Linux username (it becomes a real account, + # a sudoers drop-in name, and the baked __MANAGER__ in the root helpers). + if [[ ! "$sudo_user_name" =~ ^[a-z_][a-z0-9_-]*$ ]]; then + isError "Invalid manager user '$sudo_user_name' — use lowercase letters, digits, '_' or '-' (must start with a letter or '_')." + exit 1 + fi for pair in "system:$LP_SYSTEM_DIR" "containers:$LP_CONTAINERS_DIR" "backups:$LP_BACKUPS_DIR"; do name="${pair%%:*}"; d="${pair#*:}" case "$d" in @@ -239,6 +255,7 @@ for ((i=1; i<=$#; i++)); do --system-dir=*) LP_SYSTEM_DIR="${!i#*=}"; ((init_shift_count++)) ;; --containers-dir=*) LP_CONTAINERS_DIR="${!i#*=}"; ((init_shift_count++)) ;; --backups-dir=*) LP_BACKUPS_DIR="${!i#*=}"; ((init_shift_count++)) ;; + --manager-user=*) LP_MANAGER_USER="${!i#*=}"; ((init_shift_count++)) ;; --allow-home) init_allow_home=true; ((init_shift_count++)) ;; esac done @@ -1108,7 +1125,9 @@ sudo tee -a "$command_script" >/dev/null <<'EOF' # LibrePortal Command Start # LibrePortal Command Version 1.4 -CHECK_USER="libreportal" +# Manager user baked at install (the __MANAGER__ placeholder); unbaked keeps "__". +CHECK_USER="__MANAGER__"; [[ "$CHECK_USER" == *"__"* ]] && CHECK_USER="libreportal" +LP_MANAGER_USER="$CHECK_USER"; export LP_MANAGER_USER CURRENT_USER=$(whoami) # Check if the script is run by the specified user @@ -1401,8 +1420,10 @@ else fi # LibrePortal Command End EOF - # Bake the three roots into the (root-owned) wrapper, same as the helpers. + # Bake the manager name + three roots into the (root-owned) wrapper, same as + # the helpers. sudo sed -i \ + -e "s/__MANAGER__/${sudo_user_name}/g" \ -e "s#__SYSTEM_DIR__#${LP_SYSTEM_DIR}#g" \ -e "s#__CONTAINERS_DIR__#${LP_CONTAINERS_DIR}#g" \ -e "s#__BACKUPS_DIR__#${LP_BACKUPS_DIR}#g" \ diff --git a/scripts/checks/requirements/check_install_type.sh b/scripts/checks/requirements/check_install_type.sh index ae5d8b5..5b5b89b 100755 --- a/scripts/checks/requirements/check_install_type.sh +++ b/scripts/checks/requirements/check_install_type.sh @@ -13,8 +13,7 @@ resolveDockerInstallUser() else docker_install_user="$sudo_user_name" fi - [[ -z "$docker_install_user" ]] && docker_install_user="$sudo_user_name" - [[ -z "$docker_install_user" ]] && docker_install_user="libreportal" + [[ -z "$docker_install_user" ]] && docker_install_user="${sudo_user_name:-libreportal}" } checkInstallTypeRequirement() diff --git a/scripts/install/install_crowdsec.sh b/scripts/install/install_crowdsec.sh index fff6124..c65c9dd 100644 --- a/scripts/install/install_crowdsec.sh +++ b/scripts/install/install_crowdsec.sh @@ -222,7 +222,7 @@ installCrowdsecHost() bouncer_key=$(runSystem cscli bouncers add traefik-bouncer -o raw 2>&1 | tail -1) if [[ -n "$bouncer_key" && "$bouncer_key" != *"error"* ]]; then echo "$bouncer_key" | sudo tee "$key_file" >/dev/null - sudo chown libreportal:libreportal "$key_file" + sudo chown "$sudo_user_name:$sudo_user_name" "$key_file" sudo chmod 0600 "$key_file" checkSuccess "Traefik bouncer API key generated" diff --git a/scripts/source/paths.sh b/scripts/source/paths.sh index ae6b2d3..7babcb1 100644 --- a/scripts/source/paths.sh +++ b/scripts/source/paths.sh @@ -60,3 +60,7 @@ containers_dir="$LP_CONTAINERS_DIR/" # --- Derived: backups tree (container-user-owned; own mount-able) ----------- backup_dir="$LP_BACKUPS_DIR" + +# --- Control-plane manager user (configurable; baked into helpers at install) - +# The systemd unit + CLI wrapper export LP_MANAGER_USER; else default libreportal. +sudo_user_name="${LP_MANAGER_USER:-libreportal}" diff --git a/scripts/system/libreportal-svc b/scripts/system/libreportal-svc index 9f76427..c06c663 100644 --- a/scripts/system/libreportal-svc +++ b/scripts/system/libreportal-svc @@ -58,11 +58,12 @@ Type=simple User=$MANAGER Group=$MANAGER WorkingDirectory=$INSTALL_SCRIPTS_DIR -# Relocatable path roots — baked here by root so the processor resolves them -# authoritatively (not via the legacy compat default in paths.sh). +# Relocatable path roots + manager user — baked here by root so the processor +# resolves them authoritatively (not via the legacy compat default in paths.sh). Environment=LP_SYSTEM_DIR=$SYSTEM_DIR Environment=LP_CONTAINERS_DIR=$CONTAINERS_DIR Environment=LP_BACKUPS_DIR=$BACKUPS_DIR +Environment=LP_MANAGER_USER=$MANAGER ExecStart=$TASK_PROCESSOR start_script Restart=always RestartSec=5