From 30d762d520d978bfb116ab0c63dfd99c827b9dc7 Mon Sep 17 00:00:00 2001 From: kisfenyo Date: Sat, 4 Jul 2026 00:49:25 +0200 Subject: [PATCH] =?UTF-8?q?scripts:=20felhom-peersync=20v1.0.1=20=E2=80=94?= =?UTF-8?q?=20strip=20out=20of=20process=20substitution=20(exit-swallow=20?= =?UTF-8?q?fix)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit <(wg-quick strip ...) hid the strip exit code: a corrupt head file could feed syncconf partial input that wipes the live peer set with exit 0 (S1 REPORT finding). Strip now writes a temp file; its failure aborts before wg runs. Sandbox red-proof: pre-fix shape invoked wg with rc=0 despite strip exit 1; fixed shape never reaches wg. Co-Authored-By: Claude Fable 5 Claude-Session: https://claude.ai/code/session_01PSK5g6qYLknKj8u3QAFEr6 --- scripts/felhom-peersync.sh | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) diff --git a/scripts/felhom-peersync.sh b/scripts/felhom-peersync.sh index b961021..891a0c5 100644 --- a/scripts/felhom-peersync.sh +++ b/scripts/felhom-peersync.sh @@ -1,5 +1,10 @@ #!/usr/bin/env bash -# felhom-peersync v1.0.0 — the offsite endpoint's WG peer-list reconcile script (S1, doc 06 §5). +# felhom-peersync v1.0.1 — the offsite endpoint's WG peer-list reconcile script (S1, doc 06 §5). +# +# v1.0.1 (S2): `wg-quick strip` moved OUT of process substitution — `<(...)` hides the inner +# exit code, so a strip failure (e.g. corrupt head file) could feed syncconf empty/partial input +# that WIPES the live peer set while the script exits 0. Strip now writes a temp file and its +# failure aborts before wg is ever invoked. # # Runs as the SSH forced command for the hub's `felhom-peersync` user (via sudo — see # documentation/runbooks/offsite-endpoint.md step 5). Reads the hub's declarative payload on @@ -58,9 +63,11 @@ jq -r '.peers[] | "\n[Peer]\nPublicKey = \(.pubkey)\nAllowedIPs = \(.allowed_ip) <<<"$payload" >> "$tmp" chmod 600 "$tmp" -# 4. Apply from the TMP file first. On failure we exit here (set -e): the previous good -# LIVE_CONF is still in place — runtime and boot config never diverge in the bad direction. -wg syncconf "$IFACE" <(wg-quick strip "$tmp") || err "wg syncconf failed; live conf untouched" +# 4. Apply from the TMP file first. On failure we exit here: the previous good LIVE_CONF is +# still in place — runtime and boot config never diverge in the bad direction. Strip runs as +# its own step (NOT process substitution, which would swallow its exit code — v1.0.1). +wg-quick strip "$tmp" > "$tmpdir/stripped" || err "wg-quick strip failed; live state untouched" +wg syncconf "$IFACE" "$tmpdir/stripped" || err "wg syncconf failed; live conf untouched" # 5. Persist only after a successful apply (same-fs mv = atomic). mv "$tmp" "$LIVE_CONF"