Compare commits

..
3 Commits
4 changed files with 32 additions and 16 deletions
+1
View File
@@ -15,6 +15,7 @@ Recovery steps are in `RUNBOOK.md`. Repo overview and workflows are in `README.m
- **Cockpit (argento.timothykim.net)**: Runs directly on the host (not Docker) on port 9090 with self-signed TLS. The nginx conf inlines security headers instead of including security-headers.inc because Cockpit's internal iframes break with X-Frame-Options: DENY. Cockpit has a known bug where font files return 404 — this is not a proxy issue.
- **Minecraft HTTP-only**: HTTPS causes WebSocket/CORS errors with the MCSManager daemon. No cert issued for this domain.
- **SSL cert issuance chicken-and-egg**: On fresh recovery, certs don't exist so SSL confs can't load. The `.hold` pattern moves SSL confs aside, starts nginx with HTTP-only confs, issues certs, then restores SSL confs.
- **ZFS NFSv4 ACLs on threeteras/media**: `acltype=nfsv4`, `aclmode=restricted`, `aclinherit=passthrough`. `chmod` on anything under `/opt/argento/smb/media` fails with `Operation not permitted` (EPERM) even as root — that is the ACL refusing to be overwritten, not a bug. New dirs inherit the parent's ACL automatically, so setgid bits and `chmod` are unnecessary; don't put `force create mode` / `force directory mode` in smb.conf shares over this dataset either, since those make Samba call chmod.
- **SELinux is enforcing**: Caused issues with samba (symlinks blocked, parent directory traversal blocked). Don't use symlinks for config files — use the sync-system.sh copy approach instead.
- **Secrets in .env files**: All secrets (DB passwords, API keys, tokens) live in `.env` files under each app's `docker/<app>/` directory on the server. These are gitignored (`**/.env` in root `.gitignore`). The `.env` files are included in the USB backup. If the backup is lost, all secrets can be recreated from Bitwarden. The `system/msmtprc` in the repo has its password REDACTED -- the real one is only on the server.
- **ZFS parent dataset mountpoints**: Pools have parent datasets (e.g., `nextcloud`, `threeteras`) that create mountpoints like `/mnt/nextcloud`. These are empty and expected — do not delete them.
+19 -14
View File
@@ -120,19 +120,10 @@ zfs create -o mountpoint=/opt/argento/docker/immich/library threeteras/immich
zpool status # verify pools are ONLINE
# Per-user SMB share dirs need ownership + setgid (rsync in step 7c will
# preserve these if a USB backup exists, but freshly-created datasets are
# root-owned and need this fixup).
for u in yireh isaac; do
chown "$u":sambagroup "/opt/argento/smb/$u"
chmod 2770 "/opt/argento/smb/$u"
done
# Shared music dir. Lives inside the media dataset (so it rides the media
# snapshot policy) but is exported as its own writable [music] share.
# setgid so files dropped in over SMB inherit sambagroup and stay readable
# by the Navidrome container.
install -d -o timothykim -g sambagroup -m 2775 /opt/argento/smb/media/Music
# Ownership is set in step 7b — sambagroup doesn't exist yet.
mkdir -p /opt/argento/smb/media/Music
# SELinux contexts for samba — fresh ZFS datasets get unlabeled_t and samba
# refuses to serve them. Persistent rules (semanage) survive full relabels;
@@ -151,9 +142,23 @@ so file ownership lands on the correct UIDs.
```bash
/opt/argento/scripts/restore-users.sh
# Share dirs are root-owned on freshly created datasets. These must run AFTER
# restore-users.sh — the users and sambagroup don't exist before it. Skip if
# the datasets were imported intact; step 7c's rsync preserves ownership.
for u in yireh isaac; do
chown "$u":sambagroup "/opt/argento/smb/$u"
chmod 2770 "/opt/argento/smb/$u"
done
# No chmod on Music: threeteras/media is acltype=nfsv4 aclmode=restricted, so
# chmod fails with EPERM. aclinherit=passthrough already copied the parent's
# ACL onto the dir, which is what grants sambagroup write. The other datasets
# are acltype=posix aclmode=discard, so chmod works normally there.
chown timothykim:sambagroup /opt/argento/smb/media/Music
```
This recreates timothykim, yireh, isaac, and the sambagroup group with
This recreates timothykim, yireh, isaac, hannah, and the sambagroup group with
their original UIDs/GIDs, then restores the samba password hashes from
`/mnt/backup/argento/system/samba-private/` if present (mirrored there
by sync-system.sh, gitignored so the hashes aren't in version control).
@@ -161,7 +166,7 @@ by sync-system.sh, gitignored so the hashes aren't in version control).
If the samba passdb backup is missing, set passwords manually:
```bash
for u in timothykim yireh isaac; do
for u in timothykim yireh isaac hannah; do
smbpasswd -a "$u"
smbpasswd -e "$u"
done
@@ -265,7 +270,7 @@ Deploy each app (nginx is already running and will return 502 until they start):
```bash
# Add any new apps that have been added since this was written
for app in nextcloud gitea jellyfin navidrome garage minecraft immich beszel-agent; do
for app in nextcloud gitea jellyfin navidrome garage minecraft immich beszel-agent diun; do
cd /opt/argento/docker/$app
docker compose pull
docker compose build
+3 -2
View File
@@ -25,6 +25,7 @@ USERS=(
"timothykim:1000:1000:/bin/bash:home:wheel,video,docker,sambagroup"
"yireh:1100:1100:/sbin/nologin:nohome:sambagroup"
"isaac:1101:1101:/sbin/nologin:nohome:sambagroup"
"hannah:1102:1102:/sbin/nologin:nohome:sambagroup"
)
# Abort if an existing entity's numeric ID doesn't match what we expect
@@ -122,7 +123,7 @@ 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"
echo " for u in timothykim yireh isaac hannah; do smbpasswd -a \"\$u\"; done"
elif [ -f "$PASSDB_SRC/passdb.tdb" ]; then
install -d -m 700 /var/lib/samba/private
cp "$PASSDB_SRC"/*.tdb /var/lib/samba/private/
@@ -130,7 +131,7 @@ elif [ -f "$PASSDB_SRC/passdb.tdb" ]; then
echo "[+] restored samba passdb from $PASSDB_SRC/"
else
echo "[!] no samba passdb backup found at $PASSDB_SRC/"
echo " run: for u in timothykim yireh isaac; do smbpasswd -a \"\$u\"; done"
echo " run: for u in timothykim yireh isaac hannah; do smbpasswd -a \"\$u\"; done"
fi
echo ""
+9
View File
@@ -45,6 +45,15 @@
browseable = yes
guest ok = no
[music]
path = /opt/argento/smb/media/Music
valid users = @sambagroup
write list = @sambagroup
force group = sambagroup
read only = no
browseable = yes
guest ok = no
#[homes]
# comment = Home Directories