fix(mail): live-deploy fixes — _rspamd uid via lxc-attach + smoke gate 7/12 (ref #153)

Two issues surfaced during Phase 2 live deploy on admin.gk2.secubox.in:

1. configure_rspamd_controller hardcoded chown to host uid 100110, assuming
   _rspamd is uid 110 inside the LXC. On this Debian 12 image _rspamd is
   uid 107 — rspamd crash-looped with "Permission denied" on secrets.inc.
   Fix: chown via `lxc-attach -- chown _rspamd:_rspamd` so the kernel's
   idmap maps the right uid regardless of image package set. Mode 0640
   instead of 0600 so the worker (uid _rspamd) can read it even if launched
   from a slightly different group context.

2. Smoke gate 7 grepped for the literal string "rspamd" in the first 5
   lines of `rspamc stat`, but rspamc only prints "Results for command:
   stat" + counters. Fix: grep for an always-present stat marker
   ("Messages scanned" or "Pools allocated") with a wider head -10 window.

3. Smoke gate 12 ran `dpkg -l opendkim spamassassin` under `set -e` and
   silently aborted the smoke when the named packages were unknown (the
   success case after purge). Fix: append `|| true` so the grep below is
   the actual gate.

All 13 gates green on admin.gk2.secubox.in after these fixes + the manual
deploy steps (DKIM keygen via lxc-attach, bind-mount entries, HAProxy +
mitmproxy route map for rspamd.gk2.secubox.in).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
CyberMind-FR 2026-05-16 13:34:28 +02:00
parent bd8e7d396d
commit 637b2221c0
2 changed files with 12 additions and 5 deletions

View File

@ -109,8 +109,11 @@ configure_rspamd_controller() {
password = "$pw";
enable_password = "$pw";
EOF_INC
chmod 0600 "$local_d/secrets.inc"
chown 100110:100110 "$local_d/secrets.inc" 2>/dev/null || true
# Resolve _rspamd uid/gid via the LXC itself — the host's 100110 ≠ _rspamd
# on all Debian images (varies with packages installed). Run chown from
# inside the container so the kernel applies idmap automatically.
lxc-attach -n "$container" -- chown _rspamd:_rspamd /etc/rspamd/local.d/secrets.inc 2>/dev/null || true
lxc-attach -n "$container" -- chmod 0640 /etc/rspamd/local.d/secrets.inc 2>/dev/null || true
echo "[rspamd] controller secret provisioned"
}

View File

@ -72,8 +72,9 @@ pass "DKIM key + DNS TXT present"
# ─── 7) Outbound mail carries DKIM-Signature header ──────────────────────
step "7) DKIM-Signature on outbound mail (best-effort; needs swaks)"
# We just spot-check via rspamc; full DKIM-on-Maildir test is Phase 2.5
out=$(ssh "$HOST" 'lxc-attach -n mail -- rspamc stat 2>&1 | head -5' || true)
echo "$out" | grep -qi "rspamd" || fail "rspamc stat did not return rspamd output"
out=$(ssh "$HOST" 'lxc-attach -n mail -- rspamc stat 2>&1 | head -10' || true)
echo "$out" | grep -qE "Messages scanned|Pools allocated" \
|| fail "rspamc stat did not return rspamd stat output"
pass "rspamc stat reachable"
# ─── 8) SPF rule loaded ───────────────────────────────────────────────────
@ -106,7 +107,10 @@ pass "rspamd.gk2.secubox.in routes via HAProxy → mitmproxy → 10.100.0.10:113
# ─── 12) OpenDKIM + SpamAssassin purged ──────────────────────────────────
step "12) OpenDKIM + SpamAssassin absent from mail LXC"
ssh "$HOST" 'lxc-attach -n mail -- dpkg -l opendkim spamassassin 2>&1' > /tmp/phase2-dpkg
# dpkg -l returns non-zero when the named package is unknown — that's the
# success case here, so swallow it with `|| true`. The grep below still
# detects an actually-installed (^ii ) row.
ssh "$HOST" 'lxc-attach -n mail -- dpkg -l opendkim spamassassin 2>&1 || true' > /tmp/phase2-dpkg
if grep -qE '^ii (opendkim|spamassassin)' /tmp/phase2-dpkg; then
fail "OpenDKIM or SpamAssassin still installed"
fi