scripts: felhom-peersync v1.0.1 — strip out of process substitution (exit-swallow fix)

<(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 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01PSK5g6qYLknKj8u3QAFEr6
This commit is contained in:
2026-07-04 00:49:25 +02:00
parent 13203c2452
commit 30d762d520
+11 -4
View File
@@ -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"