Files
felhom.eu/documentation/audits/debian13-restic-2026-10-16/tools/rx.sh
T

28 lines
1.8 KiB
Bash

#!/bin/bash
# R-1105 — run ONE read-only restic command against THIS box's off-site store, with the restic of a chosen controller
# image (0.322.0 = restic 0.14.0, 0.323.0-rc.N = 0.18.1). Runs INSIDE the guest (pushed by pct). It builds the same
# `rclone:` repo + `rclone.program` the controller builds (offboxBaseArgs, pinned transport) from settings.json, mounts
# the controller's own volumes READ-ONLY (--volumes-from …:ro) and shares its network. It prints no host, user, path,
# key or password. ALLOWED verbs: snapshots, restore, ls, cat config — each with --no-lock, so nothing is written to the
# store. Usage: rx.sh <image> <restic args…>
set -euo pipefail
IMG="$1"; shift
case "$1" in snapshots|restore|ls|cat) ;; *) echo "rx.sh: refusing verb '$1' (read-only verbs only)" >&2; exit 2 ;; esac
S=/var/lib/docker/volumes/felhom-controller-data/_data/data/settings.json
eval "$(python3 - "$S" <<'EOF'
import json, shlex, sys
o = json.load(open(sys.argv[1]))["offbox"]
assert o.get("transport") == "rclone-pinned", "rx.sh handles the pinned transport only"
d = "/opt/docker/felhom-controller/data/offbox"
prog = (f"ssh -p {o.get('port') or 23} -oBatchMode=yes -oConnectTimeout=10 -oStrictHostKeyChecking=yes "
f"-oUserKnownHostsFile={d}/known_hosts -oIdentitiesOnly=yes -i {d}/ssh_key {o['user']}@{o['host']} rclone")
print("REPO=" + shlex.quote("rclone:" + o["repo_path"]))
print("PROG=" + shlex.quote("rclone.program=" + prog))
EOF
)"
mkdir -p /tmp/r1105
exec docker run --rm --network container:felhom-controller --volumes-from felhom-controller:ro \
-v /tmp/r1105:/tmp/r1105 -e RESTIC_PASSWORD_FILE=/opt/docker/felhom-controller/data/offbox/repo_password \
-e RESTIC_CACHE_DIR=/tmp/r1105/cache-$(echo "$IMG" | tr -c 'a-z0-9.\n' '_') \
--entrypoint restic "$IMG" -r "$REPO" -o "$PROG" --no-lock "$@"