fix: ACME ownership self-heal + daily timer, apply-all force, firewall baseline re-stamp
acme:
- acme.sh chmods its tree to owner-only (700/600) every run, which
broke the two-user model: a tree left owner-only by one user made
every acme.sh call of the other exit 2
- normalize_acme_home() reopens group access (sudo chmod g+rwX,
files only — setgid dirs trip RestrictSUIDSGID); _run_acme_preflight
is the choke point before every daemon acme.sh call + startup
- acme service now runs as the daemon user; --log persists the raw CA
transcript; SYS_LOG=6 journals manual issue/renew runs
- timer daily-only: two runs/day landed inside ZeroSSL's 24h
validation backoff (Retry-After: 86400) — a permanent renewal lockout
- _collect_acme no longer raises on cert-list failure; reports
status.error (AcmeState.status) so the certs page can surface it
firewall: re-stamp the applied baseline on live zone mutations
(interfaces/services/rich-rules/masquerade/forward-ports) so cancel-all
reverts to post-mutation state, not a stale install-era snapshot;
set_masquerade syncs the declarative config for existing zones;
add_forward_port records toaddr only with toport
status: apply-all accepts {"force": true} (forwarded to the firewall
apply only); ApplyConfirm force checkbox; applyResultToasts() — the
errors map wins over the 200; ActionButton checks errors before the
success toast; dashboard uses ApplyConfirm
system_import: drift re-imports carry the existing apply-meta; first
import stamps the adopted content as applied (it is the running state)
— no phantom pending changes
nginx: get_config only re-saves when migration actually changed the
config (no more owner/mtime churn on every read)
install: repair mis-owned top-level system dirs (tmpfiles
unsafe-path-transition), warn with a full-repair command for deeper
mis-ownership
daemon/server: loop.get_exception_handler() (aiohttp API fix)
tests: 888 pytest + 24 node passing; ruff clean
This commit is contained in:
@@ -144,6 +144,32 @@ fi
|
||||
# Shared group: use the WebUI user's primary group
|
||||
USER_GROUP=$(id -gn "$USER_NAME")
|
||||
|
||||
# Some appliance images ship with top-level system directories (and sometimes
|
||||
# everything under them) owned by a regular user. This trips systemd-tmpfiles'
|
||||
# "unsafe path transition" check and lets that user modify system paths.
|
||||
# Repair the top level here; warn with a full-repair command if deeper
|
||||
# mis-ownership is detected (depth-1 entries of /etc /usr /var /boot are
|
||||
# always root-owned on Debian, so this check cannot false-positive).
|
||||
_sys_dirs=(/ /bin /boot /etc /home /media /mnt /opt /root /sbin /srv /usr /var /var/lib /var/log)
|
||||
_misowned=()
|
||||
for _d in "${_sys_dirs[@]}"; do
|
||||
[[ -e "$_d" ]] || continue
|
||||
[[ "$(stat -c '%U' "$_d" 2>/dev/null)" == "root" ]] || _misowned+=("$_d")
|
||||
done
|
||||
if [[ ${#_misowned[@]} -gt 0 ]]; then
|
||||
warn "System directories not owned by root: ${_misowned[*]}"
|
||||
warn "Chowning to root:root (image shipped with mis-owned system paths)."
|
||||
chown root:root "${_misowned[@]}"
|
||||
_deep_count=$(find /etc /usr /var /boot -maxdepth 1 ! -user root 2>/dev/null | wc -l)
|
||||
if [[ "$_deep_count" -gt 0 ]]; then
|
||||
warn "Deeper mis-ownership detected ($_deep_count entries at depth 1)."
|
||||
warn "Run a full repair, then re-run this installer:"
|
||||
warn " sudo find / -xdev -path /proc -prune -o -path /sys -prune -o -path /dev -prune -o -path /run -prune -o -path /tmp -prune -o -path /home/$USER_NAME -prune -o -user $USER_NAME -print0 | xargs -0 -r chown root:root"
|
||||
else
|
||||
log "Repaired top-level system directory ownership."
|
||||
fi
|
||||
fi
|
||||
|
||||
echo "============================================"
|
||||
echo " Vacuum Wall Appliance Installer"
|
||||
echo " Install dir: $PROJECT_DIR"
|
||||
|
||||
Reference in New Issue
Block a user