fix(firewall): pick backend by docker mode, use container name

The firewall rebuild chose ufw-docker vs ufw from $EUID -eq 0 (am I root?)
rather than the docker mode. During a rootless install everything runs as
root, so it wrongly picked ufw-docker — which manages the rooted daemon's
DOCKER-USER chain that rootless never creates — and failed with 'Docker
instance libreportal doesn't exist'. (It was also inconsistent at runtime: the
non-root cron refresh always fell through to plain ufw.) Select by
CFG_DOCKER_INSTALL_TYPE so rootless always uses plain ufw (ports are published
on the host) and rooted always uses ufw-docker.

Also: ufw-docker needs the container name, not the app name — pass
service_name (e.g. libreportal-service) with an app_name fallback; route the
traefik-detect docker ps through runFileOp (was raw docker -> /var/run in
rootless); and move the ufw/ufw-docker sudo calls to runSystem.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Signed-off-by: librelad <librelad@digitalangels.vip>
This commit is contained in:
librelad 2026-05-24 13:47:40 +01:00
parent 84ed9b2272
commit 85f8130a49

View File

@ -9,7 +9,7 @@ firewallRebuildFromDatabase()
# Determine firewall type # Determine firewall type
local firewall_type="" local firewall_type=""
if [[ $EUID -eq 0 ]] && command -v ufw-docker &> /dev/null; then if [[ "$CFG_DOCKER_INSTALL_TYPE" == "rooted" ]] && command -v ufw-docker &> /dev/null; then
firewall_type="ufw-docker" firewall_type="ufw-docker"
isSuccessful "Using UFW-Docker for Rooted install" isSuccessful "Using UFW-Docker for Rooted install"
elif command -v ufw &> /dev/null; then elif command -v ufw &> /dev/null; then
@ -21,7 +21,7 @@ firewallRebuildFromDatabase()
# Check if Traefik is installed and running # Check if Traefik is installed and running
local traefik_available=false local traefik_available=false
if [[ -d "$containers_dir/traefik" ]] && docker ps --format "table {{.Names}}" | grep -q "traefik"; then if [[ -d "$containers_dir/traefik" ]] && runFileOp docker ps --format "table {{.Names}}" | grep -q "traefik"; then
traefik_available=true traefik_available=true
isSuccessful "Traefik detected - respecting traefik_managed flags" isSuccessful "Traefik detected - respecting traefik_managed flags"
else else
@ -95,11 +95,11 @@ firewallRebuildFromDatabase()
# the published port", so no route rule is created and # the published port", so no route rule is created and
# the container is unreachable from other hosts — host # the container is unreachable from other hosts — host
# access still works via docker-proxy, which masks it. # access still works via docker-proxy, which masks it.
result=$(sudo ufw-docker allow "$app_name" "${port_internal:-$port_value}/tcp" 2>&1) result=$(runSystem ufw-docker allow "${service_name:-$app_name}" "${port_internal:-$port_value}/tcp" 2>&1)
else else
# Rootless: container ports are published on the host, # Rootless: container ports are published on the host,
# so the external port is the one to open. # so the external port is the one to open.
result=$(sudo ufw allow "$port_spec" comment "LibrePortal" 2>&1) result=$(runSystem ufw allow "$port_spec" comment "LibrePortal" 2>&1)
fi fi
# Capture rc separately: `local x=$(...)` would clobber $? # Capture rc separately: `local x=$(...)` would clobber $?
# with the exit of `local`, hiding the command's real status. # with the exit of `local`, hiding the command's real status.