#!/bin/bash # Unified mirror sync + verification script # Doc’s β€œNot my circus, not my monkeys” edition πŸ’ + runtime tracking + before/after trust set -euo pipefail umask 022 LOGBASE="/var/log/mirror-verify" GPGDIR="/etc/mirror-gpg" MIRRORS=( # name|rsync_source|local_dir|logfile|manifest_url|sig_url|gpg_keyring "archlinux|rsync://arch.mirror.constant.com/archlinux/|/brimstone2/mirror/archlinux|$LOGBASE/arch-mirror-sync.log|https://geo.mirror.pkgbuild.com/iso/latest/archlinux-x86_64.iso|https://geo.mirror.pkgbuild.com/iso/latest/archlinux-x86_64.iso.sig|$GPGDIR/archlinux.gpg" "gentoo|rsync://masterdistfiles.gentoo.org/gentoo/|/brimstone2/mirror/gentoo|$LOGBASE/gentoo-mirror-sync.log|https://distfiles.gentoo.org/releases/amd64/autobuilds/current-stage3-amd64/sha256sum.txt|https://distfiles.gentoo.org/releases/amd64/autobuilds/current-stage3-amd64/sha256sum.txt.sig|$GPGDIR/gentoo.gpg" "hardenedbsd|rsync://rsync.hardenedbsd.org/all/|/mnt/brimstone/mirror/hardenedbsd|$LOGBASE/hbsd-sync.log|https://hardenedbsd.org/releases/CHECKSUMS.SHA256|https://hardenedbsd.org/releases/CHECKSUMS.SHA256.sig|$GPGDIR/hbsd.gpg" "void|rsync://repo-sync.voidlinux.org/voidlinux/|/mnt/brimstone/mirror/void|$LOGBASE/void-sync.log|https://repo.voidlinux.org/live/current/sha256sum.txt|https://repo.voidlinux.org/live/current/sha256sum.txt.sig|$GPGDIR/void.gpg" "slackware|rsync://mirrors.kernel.org/slackware/|/mnt/brimstone/mirror/slackware|$LOGBASE/slackware-sync.log|https://mirrors.slackware.com/slackware/slackware64-current/CHECKSUMS.md5|https://mirrors.slackware.com/slackware/slackware64-current/CHECKSUMS.md5.asc|$GPGDIR/slackware.gpg" ) for entry in "${MIRRORS[@]}"; do IFS="|" read -r NAME SOURCE DEST LOG MANIFEST SIG KEYRING <<< "$entry" { echo "========== [$(date)] Starting $NAME ==========" START=$(date +%s) # Banner title case "$NAME" in archlinux) TITLE="Arch Linux Mirror Verifier" ;; gentoo) TITLE="Gentoo Mirror Verifier" ;; hardenedbsd) TITLE="HardenedBSD Mirror Verifier" ;; void) TITLE="Void Linux Mirror Verifier" ;; slackware) TITLE="Slackware Mirror Verifier" ;; *) TITLE="Mirror Verifier" ;; esac cat << EOF __ __ _ | \/ (_) ___ _ __ ___ ___ _ __ ___ | |\/| | |/ __| '_ \` _ \ / _ \| '__/ _ \\ | | | | | (__| | | | | | (_) | | | __/ |_| |_|_|\___|_| |_| |_|\___/|_| \___| v1.0 πŸ’ $TITLE – Not my circus EOF echo "========== BEFORE Keyring Trust (fingerprints) for $NAME ==========" if [ -f "$KEYRING" ]; then gpg --no-default-keyring --keyring "$KEYRING" --fingerprint || true else echo "[$NAME] No keyring available – cannot verify signatures." fi echo "========== Syncing $NAME ==========" rsync -avhr --delete "$SOURCE" "$DEST" echo "========== Dry-run verification for $NAME ==========" DRYRUN=$(rsync -nrv --delete "$SOURCE" "$DEST") if [[ -z "$DRYRUN" ]]; then echo "[$NAME] In sync: no differences found" else echo "[$NAME] OUT OF SYNC – differences detected!" echo "$DRYRUN" fi echo "========== Signature verification for $NAME ==========" TMPDIR=$(mktemp -d) curl -s -L -o "$TMPDIR/manifest" "$MANIFEST" curl -s -L -o "$TMPDIR/sig" "$SIG" if [ ! -s "$TMPDIR/sig" ]; then echo "[$NAME] No valid signature upstream – Not my circus, not my monkeys πŸ’" else if gpg --no-default-keyring --keyring "$KEYRING" \ --verify "$TMPDIR/sig" "$TMPDIR/manifest" 2>&1; then echo "[$NAME] Signature verified successfully βœ…" else echo "[$NAME] Signature verification FAILED ❌ (Upstream problem?)" fi fi rm -rf "$TMPDIR" echo "========== AFTER Keyring Trust (fingerprints) for $NAME ==========" if [ -f "$KEYRING" ]; then gpg --no-default-keyring --keyring "$KEYRING" --fingerprint || true fi END=$(date +%s) RUNTIME=$(( (END - START) / 60 )) echo "[$NAME] Completed in $RUNTIME minutes" echo "========== [$(date)] Done with $NAME ==========" } >> "$LOG" 2>&1 done