From cfdad70cb0304fff1edba873d707f3cd40571e7e Mon Sep 17 00:00:00 2001 From: Garrett Allen <98648590+Gerrrt@users.noreply.github.com> Date: Sun, 20 Sep 2026 06:09:50 +0000 Subject: [PATCH] docs(nas): the snapshot task and the backup pull are done, and port 22 stops being inert in every document that said so (#484) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit §4.1 was created 2026-09-19 23:00 PDT and run once by hand; the pull read its snapshot minutes later. The Done blocks record what the checklist asked for: the ACL lines step 2 read off erebor/apps, frodo's inherited read entry, the step 5 cross-check (zfs creation and the script's parse of the name both 1789884000, so the zone is right), the first set 20260920T060234Z with jellyfin.db present and hashed on oracle, the timer installed, and the igc0.40 tripwire at 0 packets afterwards. §4's status block stops saying the backed-up row is not yet true. Step 9 of §6.2, in the same commit as it said: the five sentences that called port 22 inert — security.md, network.md, roadmap.md, §0.5 and §2 — become past tense with the date, and security.md now states the accepted residual where the pull is described rather than deferring it to the runbook. Refs #484. Co-Authored-By: Claude Fable 5.1 --- docs/network.md | 12 +++---- docs/roadmap.md | 7 ++-- docs/runbooks/build-the-nas.md | 65 ++++++++++++++++++++++------------ docs/security.md | 12 ++++--- 4 files changed, 59 insertions(+), 37 deletions(-) diff --git a/docs/network.md b/docs/network.md index 45b039d8..e3c3bfc7 100644 --- a/docs/network.md +++ b/docs/network.md @@ -332,12 +332,12 @@ Televisions and consoles. Internet only. [ADR-0016](adr/0016-open-casabonita-inward-and-keep-it-terminal-outward.md)). It has answered since 2026-09-19, and the target in `prometheus/targets/node.yaml` has been live since the same morning - ([#522](https://github.com/Gerrrt/HomeLab/pull/522)). Port `22` is inert - for a different reason — TrueNAS ships SSH disabled — until - [`build-the-nas.md`](runbooks/build-the-nas.md) §6.2 switches it on for the - backup pull [ADR-0045](adr/0045-pull-jellyfins-state-from-a-snapshot-over-ssh.md) - decided: key-only, one read-only user, and the rule already scopes it to - `10.0.99.20`. §6.2 rewrites this sentence on the day. + ([#522](https://github.com/Gerrrt/HomeLab/pull/522)). Port `22` was inert + for a different reason — TrueNAS ships SSH disabled — until 2026-09-19, + when [`build-the-nas.md`](runbooks/build-the-nas.md) §6.2 switched it on + for the backup pull [ADR-0045](adr/0045-pull-jellyfins-state-from-a-snapshot-over-ssh.md) + decided: key-only, one read-only user, `frodo`, and the rule already scopes + it to `10.0.99.20`. The first pull landed on 2026-09-20. [^OLEDTV]: [LG OLED TV](https://www.lg.com/us/tvs/oled) [^PS5]: [PlayStation 5](https://www.playstation.com/en-us/ps5/) diff --git a/docs/roadmap.md b/docs/roadmap.md index 82fc7238..218813f8 100644 --- a/docs/roadmap.md +++ b/docs/roadmap.md @@ -882,12 +882,13 @@ what left this one unfireable for months. the `22` that ADR-0016's table names — that port assumed a box administered over SSH, which was an operating-system decision inside a firewall table, and ADR-0040 carries the correction against its own text. Port 22 survives on the - Winterfell rule and is **inert** until - [`build-the-nas.md`](runbooks/build-the-nas.md) §6.2 switches SSH on for + Winterfell rule and was **inert** until 2026-09-19, when + [`build-the-nas.md`](runbooks/build-the-nas.md) §6.2 switched SSH on for the backup pull — decided by [ADR-0045](adr/0045-pull-jellyfins-state-from-a-snapshot-over-ssh.md), built under [#484](https://github.com/Gerrrt/HomeLab/issues/484), and - deployed by hand on `smaug`, where nothing pulls from `main`. The scrape target is + deployed by hand on `smaug`, where nothing pulls from `main`; the first set + landed on 2026-09-20. The scrape target is **`node_exporter` on `9100`**, settled by [#256](https://github.com/Gerrrt/HomeLab/issues/256) on 2026-09-17 — the pass that exists and a dashboard built entirely on `node_*` series, against an diff --git a/docs/runbooks/build-the-nas.md b/docs/runbooks/build-the-nas.md index be6c1506..475186d0 100644 --- a/docs/runbooks/build-the-nas.md +++ b/docs/runbooks/build-the-nas.md @@ -245,8 +245,8 @@ records the correction; it had originally claimed the rules were untouched by the operating-system change, and the ports were the part of them that was not. Port 22 stays on the Winterfell rule, which is `prometheus` pulling the -metadata backup. **TrueNAS ships SSH disabled**, so that rule is inert until -the service is switched on — and **§6.2 is where it is switched on**, with the +metadata backup. **TrueNAS ships SSH disabled**, so that rule was inert from +2026-09-16 until 2026-09-19, when **§6.2 switched the service on** — with the pull built, bench-tested and its user created first, per [ADR-0045](../adr/0045-pull-jellyfins-state-from-a-snapshot-over-ssh.md). Not before, and not for administration. @@ -355,10 +355,12 @@ is Seagate's jumper header, which stays empty. > [`hardware.md`](../hardware.md). From **option 8, Open Linux Shell**, at the console — **not over SSH**. -TrueNAS ships SSH disabled, and §0.5's port-22 pass is inert until someone -turns it on. Enabling it here to save a walk to the machine widens this host's -attack surface for the sake of five commands; §6.2's backup pull is the reason -to turn it on, and this is not it. +TrueNAS ships SSH disabled, and on the day this ran §0.5's port-22 pass was +inert. Enabling it here to save a walk to the machine would have widened this +host's attack surface for the sake of five commands; §6.2's backup pull was +the reason to turn it on, on 2026-09-19, and this was not it. The service +now answers one key-only user, `frodo`, who can read a snapshot and nothing +else — still not a way to administer the box. ```bash lsblk @@ -433,20 +435,18 @@ the optical bay exists for. > The Add Dataset dialog calls these *Dataset Presets*; the record size and > atime are under its advanced options. > -> **One row of the table below is decided and not yet done, and it is the -> one that says "backed up".** As deployed on 2026-09-19, Jellyfin's `/config` -> was a Docker named volume, and TrueNAS keeps named volumes on the pool it -> was given for Apps, in a dataset of its own — `erebor/ix-apps/docker`, not -> `erebor/apps`. So `erebor/apps` held the compose file and its `.env` (§6) -> and nothing Jellyfin writes +> **The row that says "backed up" became true on 2026-09-20.** As deployed +> on 2026-09-19, Jellyfin's `/config` was a Docker named volume, and TrueNAS +> keeps named volumes on the pool it was given for Apps, in a dataset of its +> own — `erebor/ix-apps/docker`, not `erebor/apps`. So `erebor/apps` held the +> compose file and its `.env` (§6) and nothing Jellyfin writes > ([#484](https://github.com/Gerrrt/HomeLab/issues/484)). > [ADR-0045](../adr/0045-pull-jellyfins-state-from-a-snapshot-over-ssh.md) -> settles it: `/config` becomes a **bind mount** at -> `/mnt/erebor/apps/jellyfin/config` (§6 migrates the state that already -> exists), this dataset gets the nightly snapshot task in §4.1, and the -> monitoring host pulls the newest snapshot's copy over the port-22 rule -> (§6.2). The row reads **yes** because that is the decision; §6.2's Done -> block is where the date goes once its checklist is complete. +> settled it: `/config` is a **bind mount** at +> `/mnt/erebor/apps/jellyfin/config` (§6 migrated the state that already +> existed), this dataset has the nightly snapshot task in §4.1, and the +> monitoring host pulled the newest snapshot's copy over the port-22 rule +> for the first time on 2026-09-20 — §6.2's Done block has the set. **Storage → `erebor` → Add Dataset.** Two of them, and the split is the backup decision made deliberately rather than drifted into. @@ -506,8 +506,16 @@ left at its default. ls -1 /mnt/erebor/apps/.zfs/snapshot/ ``` -> **Not yet created** as of the day this section was written; the Done block -> goes here. +> **Done 2026-09-19, 23:00 PDT.** Created with every value in the table and +> run once by hand from the task's menu rather than waiting for 03:00, which +> produced `auto-2026-09-19_23-00` — the name the pull in §6.2 read minutes +> later. The host's zone is **`America/Los_Angeles`** (System → General; +> `date` on the box prints PDT while `/etc/timezone` says UTC, because +> TrueNAS keeps the zone in its own config, so read it from the UI and not +> from that file). §6.2 step 5's cross-check agreed to the second: +> `zfs get -Hp creation` on the snapshot and the script's parse of its name +> both gave `1789884000`. Recursive is off for the reason the table now +> states, not the one it used to. ## §5 — The household share @@ -830,9 +838,20 @@ is what makes step 7 safe. [#535](https://github.com/Gerrrt/HomeLab/issues/535) built. Off-host twice, offsite never: one shelf holds all of it. -> **Not yet done** as of the day this section was written. The Done block -> goes here, with the date, what step 2 read off the dataset, and the first -> set's stamp. +> **Done 2026-09-20.** Steps 1 to 8 in order over 2026-09-19 and 2026-09-20 +> local time. Step 2 read `acltype nfsv4`, `aclmode passthrough` off the +> dataset, and `root:root 770` on `/mnt/erebor/apps` and its `jellyfin` +> directory with `nobody:nogroup 770` on `config`; `frodo`'s entry is +> `r-x---a-R-c---:fd-----:allow`, inherited, beneath the preset's own. Step 5 +> tarred `auto-2026-09-19_23-00/jellyfin/config` to nowhere as `frodo` and +> exited 0. Step 6, the first set, is **`20260920T060234Z`** — 76 entries, +> 2.7 MB, `./data/jellyfin.db` present, Jellyfin never stopped — copied to +> `oracle` and hashed there in the same run, and `make verify-backups` +> re-read it beside the six observability sets. Step 7 installed +> `homelab-backup-nas.timer` on the same day; its priming run failed only +> because it came before step 6, exactly as this section warned. Step 8: +> the `igc0.40` tripwire read **0 packets** on 2026-09-20 with the pull +> done. Step 9 is the commit this block landed in. ### §6.3 — Restore Jellyfin's state diff --git a/docs/security.md b/docs/security.md index b2660c34..81a7c32b 100644 --- a/docs/security.md +++ b/docs/security.md @@ -249,15 +249,17 @@ reaches it on `9100` and `22`: four host- and port-scoped passes above *Block access to CasaBonita*, verified in position with `pfctl` rather than read off the web UI, where an appended rule looks present while matching nothing. ADR-0016 wrote three and four exist, because the Hicks pass is split rather -than carrying a port list, and the `22` is inert until -[`build-the-nas.md`](runbooks/build-the-nas.md) §6.2 switches SSH on for the +than carrying a port list, and the `22` was inert until 2026-09-19, when +[`build-the-nas.md`](runbooks/build-the-nas.md) §6.2 switched SSH on for the backup pull — TrueNAS ships it disabled ([ADR-0040](adr/0040-run-truenas-on-smaug-and-keep-the-media-stack-in-this-repository.md)), and [ADR-0045](adr/0045-pull-jellyfins-state-from-a-snapshot-over-ssh.md) is -the decision that turns it on: key authentication only, one unprivileged +the decision that turned it on: key authentication only, one unprivileged read-only user, reachable from `10.0.99.20` alone by the rule that already -exists. §6.2's checklist rewrites this sentence on the day, and the residual -it leaves is one more service on the NAS with one more key that reads it. +existed. The residual it leaves, accepted, is one more service on the NAS +with one more key that reads it — a key that lives on the host already +holding the estate's age identity, and reads a directory that includes +Jellyfin's users' password hashes. [`network.md`](network.md) holds the current list. **Skids' does not exist.** `10.0.99.40 → 10.0.20.104:80,443/tcp` — Home Assistant to the Hue bridge, the one device on that segment with a local API — still waits above the block that