Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -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.

Expand Down
2 changes: 1 addition & 1 deletion docs/adr/0008-place-services-by-data-trust.md
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
4 changes: 2 additions & 2 deletions docs/adr/0011-keep-the-wiki-internal.md
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
Original file line number Diff line number Diff line change
@@ -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

Expand Down
8 changes: 4 additions & 4 deletions docs/network.md
Original file line number Diff line number Diff line change
Expand Up @@ -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)).
Expand Down Expand Up @@ -303,8 +303,8 @@ Televisions and consoles. Internet only.
not exist yet and neither does `stacks/media`; what exists is a host on its
address. **It does not change the *Reaches* column**, and that is the point
ADR-0016 made in advance: nothing on this segment initiates anywhere, and the
four rules created that day all let a more trusted segment reach **in**.
That is the direction this row records, and it is the one that is unchanged.
rules created that day all let a more trusted segment reach **in**. That is
the direction this row records, and it is the one that is unchanged.
- **Inbound is no longer nothing, and that is deliberate.** Since 2026-09-16
Hicks reaches `10.0.40.30` on `443` and `8096`, and `10.0.99.20` reaches it
on `9100` and `22` — four host-scoped, port-scoped passes above *Block access
Expand Down Expand Up @@ -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.
Expand Down
2 changes: 1 addition & 1 deletion docs/observability.md
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
4 changes: 2 additions & 2 deletions docs/roadmap.md
Original file line number Diff line number Diff line change
Expand Up @@ -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`
Expand Down
18 changes: 12 additions & 6 deletions docs/runbooks/build-the-nas.md
Original file line number Diff line number Diff line change
Expand Up @@ -174,7 +174,7 @@ the box and in the firewall, not here.
The static is set on the host and the reservation is set on the server, and
both are done because either alone is a single point of drift.

### §0.5 — Create the three rules, in order and in position
### §0.5 — Create the four rules, in order and in position

**Position is the whole difficulty.** Two of these sit above a deny that has
been in place since 2025; appended where new rules naturally land they would
Expand All @@ -183,14 +183,20 @@ reason.

| On interface | Protocol / source → destination | Position |
| --- | --- | --- |
| Hicks (50) | `tcp` `vlan50 net` → `10.0.40.30` ports `443,8096` | **above** *Block access to CasaBonita* |
| Hicks (50) | `tcp` `vlan50 net` → `10.0.40.30` port `443` | **above** *Block access to CasaBonita* |
| Hicks (50) | `tcp` `vlan50 net` → `10.0.40.30` port `8096` | **above** *Block access to CasaBonita* |
| Winterfell (99) | `tcp` `10.0.99.20` → `10.0.40.30` port `9100` | **above** *Block access to CasaBonita* |
| Winterfell (99) | `tcp` `10.0.99.20` → `10.0.40.30` port `22` | **above** *Block access to CasaBonita* |

**The Hicks rule's ports differ from ADR-0016's table, and deliberately.** That
table says `22,8096`, which assumed a box administered over SSH — ADR-0016
decided Ubuntu Server. `smaug` runs TrueNAS, which is administered over HTTPS,
so the admin port is **443** and not 22.
**Four rules and not ADR-0016's three.** That table wrote the Hicks pass as a
single row carrying a port list; what was created on 2026-09-16 is one rule per
port, which is what this table now describes. Three was a count of the rows the
ADR wrote, not of rules that exist.

**The Hicks ports differ from ADR-0016's table, and deliberately.** That table
says `22,8096`, which assumed a box administered over SSH — ADR-0016 decided
Ubuntu Server. `smaug` runs TrueNAS, which is administered over HTTPS, so the
admin port is **443** and not 22.
[ADR-0040](../adr/0040-run-truenas-on-smaug-and-keep-the-media-stack-in-this-repository.md)
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.
Expand Down
18 changes: 9 additions & 9 deletions docs/runbooks/open-the-remote-path.md
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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
Expand All @@ -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.

Expand Down Expand Up @@ -124,7 +124,7 @@ ListenPort = <LISTEN_PORT>
PrivateKey = <contents of /etc/wireguard/server.key>

# 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
Expand Down Expand Up @@ -162,7 +162,7 @@ Endpoint = <ENDPOINT>:<LISTEN_PORT>
# 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
```
Expand Down Expand Up @@ -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**.

Expand All @@ -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
Expand All @@ -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
Expand Down Expand Up @@ -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
Expand Down
4 changes: 2 additions & 2 deletions docs/runbooks/restore-the-firewall.md
Original file line number Diff line number Diff line change
Expand Up @@ -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 "<House_Segments>"'
# 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
Expand Down
4 changes: 2 additions & 2 deletions docs/security.md
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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
Expand Down
Loading