diff --git a/README.md b/README.md index 9b95e47..4388011 100644 --- a/README.md +++ b/README.md @@ -92,8 +92,8 @@ documents for different readers. the Makefile, the scripts, the workflow and the runbooks resolves its image from `compose.yaml` too, so an image that is not pinned there cannot be run at all. -- **Documented decisions and runbooks.** 41 ADRs covering what was chosen - and what was rejected — including the costs accepted knowingly; 26 +- **Documented decisions and runbooks.** 42 ADRs covering what was chosen + and what was rejected — including the costs accepted knowingly; 27 runbooks for the operations that are easy to get wrong at 1am, one of which is the handover page a successor reads first. diff --git a/docs/adr/0008-place-services-by-data-trust.md b/docs/adr/0008-place-services-by-data-trust.md index 25cc60c..2523004 100644 --- a/docs/adr/0008-place-services-by-data-trust.md +++ b/docs/adr/0008-place-services-by-data-trust.md @@ -121,7 +121,7 @@ earned its place. This leaves the "no MFA on the internal services" gap in access*. When that premise changes, so does the decision. > *The second half of that premise changed in 2026-09. - > [ADR-0041](0041-terminate-the-remote-path-on-the-lab-and-route-it.md) opens + > [ADR-0042](0042-terminate-the-remote-path-on-the-lab-and-route-it.md) opens > a WireGuard path that terminates on the lab and reaches the lab only, so > "no remote access" becomes "no remote access to the house". It fires > [ADR-0022](0022-expire-the-sso-deferral-when-the-tier-holds-real-data.md)'s diff --git a/docs/adr/0011-keep-the-wiki-internal.md b/docs/adr/0011-keep-the-wiki-internal.md index 2e9076f..6c8b9cb 100644 --- a/docs/adr/0011-keep-the-wiki-internal.md +++ b/docs/adr/0011-keep-the-wiki-internal.md @@ -60,12 +60,12 @@ machinery for publishing a service exists and reusing it would be cheap. > entry"* is the live state of the firewall, not only an intention. > > **Update · 2026-09.** The measurement above is now dated. -> [ADR-0041](0041-terminate-the-remote-path-on-the-lab-and-route-it.md) decides +> [ADR-0042](0042-terminate-the-remote-path-on-the-lab-and-route-it.md) decides > a WireGuard endpoint on the lab jumpbox, and building it makes `morpheus` > carry exactly one `rdr` and one inbound WAN pass. **The decision below is > unchanged and so is its reasoning**: the wiki is still not published, still > has no external hostname and still sits behind no reverse proxy, and reaching -> it still means being inside the house — or, from ADR-0041 onward, on a tunnel +> it still means being inside the house — or, from ADR-0042 onward, on a tunnel > that terminates on VLAN 30 and cannot route to `oracle` at all. What expires > is the estate-wide claim that nothing is reachable from outside, not this > ADR's answer for this service. diff --git a/docs/adr/0014-put-ifrit-on-imaginationlan-and-give-the-targets-no-route.md b/docs/adr/0014-put-ifrit-on-imaginationlan-and-give-the-targets-no-route.md index 428843b..5899912 100644 --- a/docs/adr/0014-put-ifrit-on-imaginationlan-and-give-the-targets-no-route.md +++ b/docs/adr/0014-put-ifrit-on-imaginationlan-and-give-the-targets-no-route.md @@ -16,10 +16,10 @@ > > **The last Consequence below names remote access into VLAN 30 as something > that reopens this decision. It has been wanted, and -> [ADR-0041](0041-terminate-the-remote-path-on-the-lab-and-route-it.md), +> [ADR-0042](0042-terminate-the-remote-path-on-the-lab-and-route-it.md), > 2026-09, is the ADR that answers it.** What moved is the premise, not the > decision: `ifrit` stays on ImaginationLAN, its targets still have no route, -> and every constraint below still holds. What ADR-0041 adds to this segment is +> and every constraint below still holds. What ADR-0042 adds to this segment is > a second source subnet — `172.31.0.0/24`, the WireGuard peers — which is why > it also widens the tripwire this ADR decided. `172.30.` is the range; > `172.31.` is the tunnel. Nothing here is amended. diff --git a/docs/adr/0022-expire-the-sso-deferral-when-the-tier-holds-real-data.md b/docs/adr/0022-expire-the-sso-deferral-when-the-tier-holds-real-data.md index 8f97f94..72211cc 100644 --- a/docs/adr/0022-expire-the-sso-deferral-when-the-tier-holds-real-data.md +++ b/docs/adr/0022-expire-the-sso-deferral-when-the-tier-holds-real-data.md @@ -5,7 +5,7 @@ > [!NOTE] > **Trigger 2 fired in 2026-09, and the deferral was re-accepted rather than > ended.** -> [ADR-0041](0041-terminate-the-remote-path-on-the-lab-and-route-it.md) opens a +> [ADR-0042](0042-terminate-the-remote-path-on-the-lab-and-route-it.md) opens a > WireGuard path terminating on the lab, which takes ADR-0008's *no external > exposure* premise — the thing this trigger makes testable. It is recorded as > fired there rather than argued around, and re-accepted on the grounds this diff --git a/docs/adr/0041-terminate-the-remote-path-on-the-lab-and-route-it.md b/docs/adr/0042-terminate-the-remote-path-on-the-lab-and-route-it.md similarity index 99% rename from docs/adr/0041-terminate-the-remote-path-on-the-lab-and-route-it.md rename to docs/adr/0042-terminate-the-remote-path-on-the-lab-and-route-it.md index 19e106b..096a1e0 100644 --- a/docs/adr/0041-terminate-the-remote-path-on-the-lab-and-route-it.md +++ b/docs/adr/0042-terminate-the-remote-path-on-the-lab-and-route-it.md @@ -1,4 +1,4 @@ -# ADR-0041: Terminate the remote path on the lab, and route it +# ADR-0042: Terminate the remote path on the lab, and route it **Status:** Accepted · 2026-09 diff --git a/docs/network.md b/docs/network.md index 26d371f..0822fa9 100644 --- a/docs/network.md +++ b/docs/network.md @@ -85,7 +85,7 @@ truth for what a box actually does. - The gateway runs in bridge mode; its own Wi-Fi radio stays operational but is unused. All wireless is handled by eero units on tagged VLANs. - **One inbound pass, and one only** — the WireGuard endpoint decided by - [ADR-0041](adr/0041-terminate-the-remote-path-on-the-lab-and-route-it.md): a + [ADR-0042](adr/0042-terminate-the-remote-path-on-the-lab-and-route-it.md): a UDP `rdr` to the lab jumpbox, terminating on ImaginationLAN and reaching the lab only. The endpoint hostname and the listen port are withheld with the WAN address ([`security.md`](security.md#what-this-repository-deliberately-does-not-publish)). @@ -393,7 +393,7 @@ Where things get broken on purpose. - **The WireGuard peers live on `172.31.0.0/24`, and it is routed rather than translated** - ([ADR-0041](adr/0041-terminate-the-remote-path-on-the-lab-and-route-it.md)). + ([ADR-0042](adr/0042-terminate-the-remote-path-on-the-lab-and-route-it.md)). `morpheus` carries one static route for it toward the jumpbox, so a peer's own address is what arrives on this interface and what a firewall log carries — which is what lets a rule name a peer and an alert say which one. diff --git a/docs/observability.md b/docs/observability.md index 884eeb7..630277b 100644 --- a/docs/observability.md +++ b/docs/observability.md @@ -297,7 +297,7 @@ packet anyway, so nothing is weakened by it being there. The terminal three feed a destination. **That alert reads two source subnets, not one.** -[ADR-0041](adr/0041-terminate-the-remote-path-on-the-lab-and-route-it.md) routes +[ADR-0042](adr/0042-terminate-the-remote-path-on-the-lab-and-route-it.md) routes the WireGuard peers on `172.31.0.0/24` rather than masquerading them, so a peer's own address reaches `igc0.30` and appears in `filterlog`. That is the point of routing rather than translating — a peer is nameable in a rule and in diff --git a/docs/roadmap.md b/docs/roadmap.md index dbd89d1..90c8307 100644 --- a/docs/roadmap.md +++ b/docs/roadmap.md @@ -1073,12 +1073,12 @@ them name the condition that would change the answer. the estate, and it stores connection credentials to do it. The estate already has a KVM in U6 for physical console access. Declined. **The remote-access question it gestured at is answered differently** by - [ADR-0041](adr/0041-terminate-the-remote-path-on-the-lab-and-route-it.md): + [ADR-0042](adr/0042-terminate-the-remote-path-on-the-lab-and-route-it.md): WireGuard to the lab jumpbox, terminating on ImaginationLAN and reaching the lab only. That is not a softening of this decline — it stores no connection credentials at a gateway, it never touches Winterfell, and the boundary is the firewall's rather than an application's. Guacamole's objection was about - the management segment, and nothing about ADR-0041 goes near it. + the management segment, and nothing about ADR-0042 goes near it. - **Frigate** — locally-processed object detection on camera streams, and the one service on the shortlist that would change the network's shape rather than its population: continuous RTSP from every camera through the `99 → 20` diff --git a/docs/runbooks/open-the-remote-path.md b/docs/runbooks/open-the-remote-path.md index b3d1c93..df8ba81 100644 --- a/docs/runbooks/open-the-remote-path.md +++ b/docs/runbooks/open-the-remote-path.md @@ -8,7 +8,7 @@ enrol, and **an endpoint** — see §0, which is the step this runbook cannot do for you **Before this:** the jumpbox exists ([#436](https://github.com/Gerrrt/HomeLab/issues/436)), and -[ADR-0041](../adr/0041-terminate-the-remote-path-on-the-lab-and-route-it.md) +[ADR-0042](../adr/0042-terminate-the-remote-path-on-the-lab-and-route-it.md) is read rather than skimmed This opens the estate's **first inbound path from the internet**. It terminates @@ -20,7 +20,7 @@ lab, and a `MASQUERADE` rule copied in from a tutorial. > [!CAUTION] > **There is no `MASQUERADE` in this design, anywhere.** Every guide you will -> find while doing this has one. ADR-0041 §2 is why this one does not: NAT +> find while doing this has one. ADR-0042 §2 is why this one does not: NAT > would make every peer indistinguishable from the jumpbox, which holds a > Proxmox token and an SSH key, and would hand every peer the jumpbox's > standing at the firewall. If you find yourself adding `-j MASQUERADE` to make @@ -47,7 +47,7 @@ key that has been on two machines is a key you cannot reason about later. WireGuard needs a stable address and port to dial. This estate has neither: the WAN address is ISP-assigned by DHCP, and there is no dynamic DNS anywhere in -it. ADR-0041 §4 records that deliberately as a separate decision — a static +it. ADR-0042 §4 records that deliberately as a separate decision — a static address is a recurring purchase, and a dynamic DNS provider is a third party handed a continuously-updated pointer to the house. @@ -124,7 +124,7 @@ ListenPort = PrivateKey = # Forwarding is a capability scoped to the tunnel's lifetime, not a permanent -# property of the host (ADR-0041). Nothing here is in /etc/sysctl.conf, and +# property of the host (ADR-0042). Nothing here is in /etc/sysctl.conf, and # nothing here translates an address. PostUp = sysctl -w net.ipv4.ip_forward=1 PostDown = sysctl -w net.ipv4.ip_forward=0 @@ -162,7 +162,7 @@ Endpoint = : # On the CLIENT, AllowedIPs is a ROUTE: the CIDRs that go down the tunnel. # This is the lab and nothing else. 0.0.0.0/0 here would pull all of the # device's traffic through the house, which is not what this is for and is the -# failure ADR-0041 says will not announce itself. +# failure ADR-0042 says will not announce itself. AllowedIPs = 10.0.30.0/24 PersistentKeepalive = 25 ``` @@ -197,7 +197,7 @@ Then *System → Routing → Static Routes → Add*: | --- | --- | | Destination network | `172.31.0.0/24` | | Gateway | `JUMPBOX_TUNNEL` | -| Description | `WireGuard peers — ADR-0041` | +| Description | `WireGuard peers — ADR-0042` | **Save**, then **Apply Changes**. @@ -213,7 +213,7 @@ Then *System → Routing → Static Routes → Add*: | Destination port range | the listen port, from and to | | Redirect target IP | the jumpbox's lab address | | Redirect target port | the same listen port | -| Description | `WireGuard — ADR-0041` | +| Description | `WireGuard — ADR-0042` | | Filter rule association | **Add associated filter rule** | **Save**, then **Apply Changes**. This is the `rdr` and the WAN pass that @@ -236,7 +236,7 @@ First, *Firewall → Aliases → IP → Add*: | Name | `Tunnel_Peers` | | Type | Network(s) | | Network | `172.31.0.0/24` | -| Description | `WireGuard peers — ADR-0041` | +| Description | `WireGuard peers — ADR-0042` | Then on *Firewall → Rules → ImaginationLAN*, mirror the existing lab rules for this source, keeping the established order — blocks, then the tripwire, then @@ -364,7 +364,7 @@ is strictly more closed than after it. 6. `sudo shred -u /etc/wireguard/server.key /etc/wireguard/wg0.conf`. Removing **one peer** rather than the tunnel is a `wg0.conf` edit and -`sudo systemctl reload wg-quick@wg0`. ADR-0041 records that this does not scale +`sudo systemctl reload wg-quick@wg0`. ADR-0042 records that this does not scale and that the first lost device is when it stops being proportionate. ## If something goes wrong diff --git a/docs/runbooks/restore-the-firewall.md b/docs/runbooks/restore-the-firewall.md index 4883e68..3dd5bf3 100644 --- a/docs/runbooks/restore-the-firewall.md +++ b/docs/runbooks/restore-the-firewall.md @@ -267,10 +267,10 @@ ssh root@10.0.99.1 'pfctl -sr \ # latter names 10.0.30.0/24 itself, and against it every DNS query from the lab # to its own gateway logs as a crossing. ssh root@10.0.99.1 'pfctl -sr | grep -E "^pass in log quick on igc0\.30 " | grep -c ""' -# expect 2 once ADR-0041's tunnel exists: the lab's own tripwire and the +# expect 2 once ADR-0042's tunnel exists: the lab's own tripwire and the # WireGuard peers'. Before it is built, expect 1. -# 6. ADR-0041's rules, if the tunnel has been built. The check above counts +# 6. ADR-0042's rules, if the tunnel has been built. The check above counts # tripwires by their shape and the four in step 5 are sourced from an # interface network macro, which the tunnel's is not — so the tunnel's # tripwire and its blocks need asking after separately, or a restore drops diff --git a/docs/security.md b/docs/security.md index 334d946..8df1e4c 100644 --- a/docs/security.md +++ b/docs/security.md @@ -37,7 +37,7 @@ state rather than leaving it open: the first real secret, photo or document in the sensitive tier, any reachability from outside the house, or a third account holder — whichever comes first. **The second of those has now fired and the deferral was re-accepted**, not ended: -[ADR-0041](adr/0041-terminate-the-remote-path-on-the-lab-and-route-it.md) opens +[ADR-0042](adr/0042-terminate-the-remote-path-on-the-lab-and-route-it.md) opens a WireGuard path terminating on the lab, which takes ADR-0008's *no external exposure* premise with it. Nothing in the tier became reachable — it is unbuilt, and on Winterfell when it is built — but the lab's own Grafana on @@ -731,7 +731,7 @@ fingerprint of a house is not. Withheld on purpose: the same instinct: a repository that withholds the WAN address and then publishes the port a VPN answers on has withheld nothing. The design, the peer subnet and the rules are published - ([ADR-0041](adr/0041-terminate-the-remote-path-on-the-lab-and-route-it.md)); + ([ADR-0042](adr/0042-terminate-the-remote-path-on-the-lab-and-route-it.md)); where to send a packet is not. The public IP was already redacted in the original inventory — the rest of this