diff --git a/.gitignore b/.gitignore index da136ce..101a559 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,4 @@ smb/ **/.env +system/samba-private/ diff --git a/RUNBOOK.md b/RUNBOOK.md index a12ac94..840d805 100644 --- a/RUNBOOK.md +++ b/RUNBOOK.md @@ -127,6 +127,14 @@ for u in yireh isaac; do chown "$u":sambagroup "/opt/argento/smb/$u" chmod 2770 "/opt/argento/smb/$u" done + +# SELinux contexts for samba — fresh ZFS datasets get unlabeled_t and samba +# refuses to serve them. Persistent rules (semanage) survive full relabels; +# restorecon applies them now. +semanage fcontext -a -t samba_share_t "/opt/argento/smb/media(/.*)?" +semanage fcontext -a -t samba_share_t "/opt/argento/smb/yireh(/.*)?" +semanage fcontext -a -t samba_share_t "/opt/argento/smb/isaac(/.*)?" +restorecon -Rv /opt/argento/smb/ ``` ## 7b. Restore users @@ -141,7 +149,8 @@ so file ownership lands on the correct UIDs. This recreates timothykim, yireh, isaac, and the sambagroup group with their original UIDs/GIDs, then restores the samba password hashes from -`/mnt/backup/samba-private/` if present. +`/mnt/backup/argento/system/samba-private/` if present (mirrored there +by sync-system.sh, gitignored so the hashes aren't in version control). If the samba passdb backup is missing, set passwords manually: diff --git a/scripts/backup.sh b/scripts/backup.sh index a1d073d..dbb50ab 100755 --- a/scripts/backup.sh +++ b/scripts/backup.sh @@ -40,17 +40,14 @@ for db in jellyfin library; do || FAILURES+=("jellyfin ${db} sqlite backup") done -# Single rsync covers everything: configs, app data, media, DB dumps +# Single rsync covers everything: configs, app data, media, DB dumps, +# and the samba passdb (mirrored into /opt/argento/system/samba-private/ +# by sync-system.sh, gitignored) RSYNC_OPTS="-a --delete" [ -t 1 ] && RSYNC_OPTS="$RSYNC_OPTS --info=progress2" rsync $RSYNC_OPTS /opt/argento/ /mnt/backup/argento/ \ || FAILURES+=("rsync argento") -# Back up samba passdb (binary — holds SMB password hashes, not in /opt/argento) -mkdir -p /mnt/backup/samba-private -rsync -a --delete /var/lib/samba/private/ /mnt/backup/samba-private/ \ - || FAILURES+=("rsync samba passdb") - if [ ${#FAILURES[@]} -gt 0 ]; then echo "BACKUP FAILED: ${FAILURES[*]}" >&2 exit 1 diff --git a/scripts/restore-users.sh b/scripts/restore-users.sh index 9b1d3be..1e719f4 100755 --- a/scripts/restore-users.sh +++ b/scripts/restore-users.sh @@ -117,18 +117,19 @@ done echo "" echo "=== samba passdb ===" +PASSDB_SRC=/mnt/backup/argento/system/samba-private if ! mountpoint -q /mnt/backup; then echo "[!] /mnt/backup is not mounted — skipping samba passdb restore" echo " mount the USB backup drive (RUNBOOK step 5) and re-run if you want" echo " to restore preserved SMB passwords; otherwise set them manually:" echo " for u in timothykim yireh isaac; do smbpasswd -a \"\$u\"; done" -elif [ -f /mnt/backup/samba-private/passdb.tdb ]; then +elif [ -f "$PASSDB_SRC/passdb.tdb" ]; then install -d -m 700 /var/lib/samba/private - cp /mnt/backup/samba-private/*.tdb /var/lib/samba/private/ + cp "$PASSDB_SRC"/*.tdb /var/lib/samba/private/ chmod 600 /var/lib/samba/private/*.tdb - echo "[+] restored samba passdb from /mnt/backup/samba-private/" + echo "[+] restored samba passdb from $PASSDB_SRC/" else - echo "[!] no samba passdb backup found at /mnt/backup/samba-private/" + echo "[!] no samba passdb backup found at $PASSDB_SRC/" echo " run: for u in timothykim yireh isaac; do smbpasswd -a \"\$u\"; done" fi diff --git a/scripts/sync-system.sh b/scripts/sync-system.sh index 69ebbb2..27bde99 100755 --- a/scripts/sync-system.sh +++ b/scripts/sync-system.sh @@ -17,6 +17,12 @@ done < "$REPO/system/tracked-configs" sed -i 's/^password .*/password REDACTED/' "$REPO/system/msmtprc" +# Mirror samba's binary passdb files into the repo so backup.sh's standard +# rsync of /opt/argento/ picks them up. Gitignored — credential hashes don't +# belong in version control, but they DO need to ride along on the USB backup. +install -d -m 700 "$REPO/system/samba-private" +rsync -a --delete /var/lib/samba/private/ "$REPO/system/samba-private/" + # Sync root crontab crontab -l > "$REPO/system/root-crontab" 2>/dev/null || true