Skip to content
Merged
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
6 changes: 3 additions & 3 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.** 42 ADRs covering what was chosen
and what was rejected — including the costs accepted knowingly; 28
- **Documented decisions and runbooks.** 43 ADRs covering what was chosen
and what was rejected — including the costs accepted knowingly; 30
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 Expand Up @@ -207,7 +207,7 @@ Full topology and data flow in [`docs/architecture.md`](docs/architecture.md).
├── docs/
│ ├── architecture.md network.md hardware.md
│ ├── observability.md security.md roadmap.md
│ ├── adr/ # 41 architecture decision records
│ ├── adr/ # 43 architecture decision records
│ └── runbooks/ # successor handover (start here), deploy, converge,
│ # add device, rotate creds, certs, key backup,
│ # purge, restore the firewall, restore the stack,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,18 @@
> 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.
>
> ---
>
> **One rule is superseded, 2026-09.** The management-plane rule below admits
> `8006`, `8007` and `22` from `10.0.50.0/24` only. Since
> [ADR-0043](0043-keep-the-ca-on-prometheus-and-build-phoenix-as-the-deployment-host.md)
> it also admits one address on VLAN 30, `10.0.30.70`, to `8006` alone — the
> deployment host, driving the API it exists to drive, and the host the
> tunnel above terminates on. That is a change to a decision rather than a
> premise, which is why it is a supersession of that one rule and not a
> note; every other bullet below stands. The text is left as written, per
> ADR-0001.

## Context

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,15 @@

**Status:** Accepted · 2026-09

> [!NOTE]
> **One consequence is amended, 2026-09.** The first bullet under
> Consequences says nothing on VLAN 30 gains a path to `8006` on either
> hypervisor. Since
> [ADR-0043](0043-keep-the-ca-on-prometheus-and-build-phoenix-as-the-deployment-host.md)
> one address does — `10.0.30.70`, the deployment host, to `Saruman` alone.
> The decision this ADR records is unchanged: neither hypervisor reaches the
> other. The text below is left as written, per ADR-0001.

## Context

[#443](https://github.com/Gerrrt/HomeLab/issues/443) asked for a decision
Expand Down
10 changes: 10 additions & 0 deletions docs/adr/0042-terminate-the-remote-path-on-the-lab-and-route-it.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,16 @@

**Status:** Accepted · 2026-09

> [!NOTE]
> **One of the conditions under *What would reopen this* has fired, 2026-09.**
> The Proxmox `8006` rule widens to admit the jumpbox, by
> [ADR-0043](0043-keep-the-ca-on-prometheus-and-build-phoenix-as-the-deployment-host.md)
> — the decision this ADR's consequences left to #436, and the one that names
> the jumpbox `phoenix` at `10.0.30.70`. Nothing here is amended: routed mode,
> decision 3, is what that widening relies on to admit one host and not every
> peer, and ADR-0014 carries the supersession of its rule. The text below is
> left as written, per ADR-0001.

## Context

The estate has no remote access. Every path in is a workstation physically on
Expand Down

Large diffs are not rendered by default.

3 changes: 2 additions & 1 deletion docs/architecture.md
Original file line number Diff line number Diff line change
Expand Up @@ -185,9 +185,10 @@ hole from the monitoring VLAN into the monitored one.
| Host | VLAN | Stack | Contents |
| --- | --- | --- | --- |
| `prometheus` (10.0.99.20) | 🔴 99 | [`stacks/observability`](../stacks/observability) | Prometheus, Alertmanager, Loki, Grafana, snmp-exporter, blackbox-exporter, docker-socket-proxy, Alloy |
| `Saruman` (10.0.30.110) | 🟢 30 | *(none — and none intended)* | Proxmox VE 9, running one guest — `alexander`, built 2026-09-05 ([#262](https://github.com/Gerrrt/HomeLab/issues/262)) — and seven more planned below: `odin` for the security tooling (ADR-0030) and ADR-0029's six-machine domain; Alloy agent (native package). It runs no compose stack by decision, not by omission: Docker would rewrite the iptables its own firewall relies on ([ADR-0014](adr/0014-put-ifrit-on-imaginationlan-and-give-the-targets-no-route.md)), which is why the agent here is the native package and why `stacks/lab` runs in a guest |
| `Saruman` (10.0.30.110) | 🟢 30 | *(none — and none intended)* | Proxmox VE 9, running one guest — `alexander`, built 2026-09-05 ([#262](https://github.com/Gerrrt/HomeLab/issues/262)) — and eight more planned below: `odin` for the security tooling (ADR-0030), `phoenix` for the deployment toolchain (ADR-0043) and ADR-0029's six-machine domain; Alloy agent (native package). It runs no compose stack by decision, not by omission: Docker would rewrite the iptables its own firewall relies on ([ADR-0014](adr/0014-put-ifrit-on-imaginationlan-and-give-the-targets-no-route.md)), which is why the agent here is the native package and why `stacks/lab` runs in a guest |
| `alexander` (10.0.30.40) | 🟢 30 | [`stacks/lab`](../stacks/lab) | Prometheus, Loki, Grafana, Alloy — the lab's own observability, which never remote-writes to VLAN 99 ([ADR-0007](adr/0007-defensive-estate-and-offensive-range.md), [ADR-0020](adr/0020-run-the-lab-stack-in-a-guest-with-its-own-prometheus.md)). A guest on `Saruman`, not the hypervisor; Alloy agent (Docker) |
| `odin` (10.0.30.60) | 🟢 30 | [`stacks/soc`](../stacks/soc) | **Not built yet** — Wazuh (indexer, manager, dashboard), Velociraptor and Alloy: the security half of ADR-0007, placed by [ADR-0030](adr/0030-give-the-security-tooling-its-own-guest-and-its-own-stack.md) on a second guest on `Saruman` because `alexander`'s 8 GiB cannot hold both. The stack is authored and CI-validated ahead of the guest, the way `stacks/lab` was ahead of `alexander`; the build is [`build-the-soc-guest.md`](runbooks/build-the-soc-guest.md), behind [#414](https://github.com/Gerrrt/HomeLab/issues/414). The six domain machines report to it as agents; its Alloy pushes to `alexander`, never to VLAN 99, and the indexer's health is the one series that crosses into the lab's Prometheus. Alloy agent (Docker) |
| `phoenix` (10.0.30.70) | 🟢 30 | *(none — a toolchain host, no Docker)* | **Not built yet** — the deployment host: a Proxmox API token, an SSH key and a checkout, so that the Packer, OpenTofu and Ansible work after [#436](https://github.com/Gerrrt/HomeLab/issues/436) has somewhere to run from. A guest on `Saruman`, placed by [ADR-0043](adr/0043-keep-the-ca-on-prometheus-and-build-phoenix-as-the-deployment-host.md), which also decides that the estate's CA key stays on `prometheus` and does not follow the toolchain here. It holds no age key and converges nothing; it is the WireGuard endpoint of [ADR-0042](adr/0042-terminate-the-remote-path-on-the-lab-and-route-it.md) once that is built; the one thing it reaches that no other guest does is `8006` on `Saruman`, by a single host-firewall rule. Its Alloy pushes to `alexander`, never to VLAN 99; the build is [`build-the-jumpbox.md`](runbooks/build-the-jumpbox.md). Alloy agent (native package, `scripts/deploy-agent.sh`) |
| `oracle` (10.0.99.30) | 🔴 99 | *(none — hand-run containers)* | The Lemmiwinks wiki and its Postgres, since 2025-11-12 ([ADR-0011](adr/0011-keep-the-wiki-internal.md)); Alloy agent (Docker, `scripts/deploy-agent.sh`); the off-host copy of the firewall export (`make backup-firewall`). The estate's host for small off-host jobs — [ADR-0015](adr/0015-give-oracle-the-off-host-jobs.md) |
| `trinity` (10.0.99.40) | 🔴 99 | [`stacks/sensitive`](../stacks/sensitive) | **Not built yet** — ADR-0008's sensitive tier on the ProDesk 600 G4 of [ADR-0034](adr/0034-run-the-sensitive-tier-on-the-prodesk-and-make-it-the-spare-hardware.md), after the firewall restore is rehearsed on it ([#404](https://github.com/Gerrrt/HomeLab/issues/404)). The foundation is authored: Caddy as the published HTTPS port and step-ca issuing beneath the tier's own root rather than the estate's, which is left untouched ([#129](https://github.com/Gerrrt/HomeLab/issues/129), [#130](https://github.com/Gerrrt/HomeLab/issues/130), [ADR-0037](adr/0037-give-the-sensitive-tier-its-own-root-and-issue-beneath-it-over-acme.md)), with AdGuard Home behind Caddy and publishing 53 to the firewall's forwarder alone ([#135](https://github.com/Gerrrt/HomeLab/issues/135), [ADR-0010](adr/0010-keep-the-resolver-on-the-gateway.md)); Home Assistant ([#134](https://github.com/Gerrrt/HomeLab/issues/134)), Immich — four containers behind Caddy with a memory limit on each ([#132](https://github.com/Gerrrt/HomeLab/issues/132)) — Paperless-ngx with a Postgres and a Valkey of its own ([#133](https://github.com/Gerrrt/HomeLab/issues/133)) and Vaultwarden ([#131](https://github.com/Gerrrt/HomeLab/issues/131)) are authored as well; the rest follow. Alloy agent (Docker, `scripts/deploy-agent.sh`), pushing to `prometheus` like `oracle`'s |
| `smaug` (10.0.40.30) | 🟡 40 | [`stacks/media`](../stacks/media) | [ADR-0008](adr/0008-place-services-by-data-trust.md)'s media tier on the ThinkServer TS150 of [#413](https://github.com/Gerrrt/HomeLab/issues/413), placed and addressed by [ADR-0016](adr/0016-open-casabonita-inward-and-keep-it-terminal-outward.md) and running TrueNAS rather than Ubuntu Server by [ADR-0040](adr/0040-run-truenas-on-smaug-and-keep-the-media-stack-in-this-repository.md). **The host is built and the pool is not**: TrueNAS is installed on its boot SSD, it holds the static above since 2026-09-16, and the four inbound rules are created and verified in position — but the ZFS mirror waits on two Exos X20 drives and nothing is deployed on it. The stack is authored and CI-validated ahead of the storage, the way `stacks/sensitive` was ahead of `trinity`: Jellyfin alone, publishing 8096 to the segment because the televisions reach it natively and no firewall rule is involved at all ([#138](https://github.com/Gerrrt/HomeLab/issues/138)). Runs no agent of its own: this host is scraped and never pushes, which makes it the estate's first scraped host and is why [#256](https://github.com/Gerrrt/HomeLab/issues/256) exists — that issue now also has a fork in it, because TrueNAS ships its own metrics endpoint where the issue specifies `node_exporter` |
Expand Down
20 changes: 20 additions & 0 deletions docs/network.md
Original file line number Diff line number Diff line change
Expand Up @@ -370,6 +370,26 @@ Where things get broken on purpose.
pushes to `alexander` and not to Winterfell — "guests get no such rule"
covers it — and ADR-0029's six machines report to it as agents. Every path
it needs is intra-segment, so it adds no firewall rule.
- A third guest, `phoenix`, is planned at `10.0.30.70` — the next decade — as
the deployment host: the Proxmox API token, the SSH key and the checkout
that the Packer, OpenTofu and Ansible work after
[#436](https://github.com/Gerrrt/HomeLab/issues/436) runs from, placed by
[ADR-0043](adr/0043-keep-the-ca-on-prometheus-and-build-phoenix-as-the-deployment-host.md).
**Not built**; it enters the table above when it is
([`build-the-jumpbox.md`](runbooks/build-the-jumpbox.md)). It runs no stack
and holds no key that signs anything — the estate's CA stays on
`prometheus`, and that ADR says why. It is also where
[ADR-0042](adr/0042-terminate-the-remote-path-on-the-lab-and-route-it.md)'s
WireGuard tunnel terminates once the endpoint it records as blocking exists;
the peers reach the lab through it and nothing else. Its Alloy pushes to
`alexander` and
not to Winterfell, and it gets no pass out of this segment: a rule from it
into 99 would make it the bastion ADR-0002 and ADR-0012 declined. It adds
nothing on `morpheus`. What it adds is on `Saruman`: one line in the
hypervisor's own firewall admitting `10.0.30.70` to `8006`, the first
address on this segment with a path to the Proxmox API, which
`firewall-claims.yaml` cannot see because it lives in `/etc/pve` and not in
pf.
- `Saruman` runs an Alloy agent and is the one host on this segment with a path
into Winterfell: a single pass, `10.0.30.110 → 10.0.99.20` on 9090 and 3100
TCP, unlogged and above the ADR-0014 tripwire. The hypervisor's own telemetry
Expand Down
26 changes: 26 additions & 0 deletions docs/roadmap.md
Original file line number Diff line number Diff line change
Expand Up @@ -1028,6 +1028,32 @@ what left this one unfireable for months.
unifying that.
- **[#100](https://github.com/Gerrrt/HomeLab/issues/100) Automate the Grafana

- **[#436](https://github.com/Gerrrt/HomeLab/issues/436) Build a deployment
jumpbox on ImaginationLAN, and decide where the CA lives.** Decided by
[ADR-0043](adr/0043-keep-the-ca-on-prometheus-and-build-phoenix-as-the-deployment-host.md);
the guest is not built. The host is `phoenix`, `10.0.30.70`, a guest on
`Saruman` that holds the estate's first Proxmox API credential and the SSH
key the toolchain will inject into what it builds — the prerequisite for
the Packer, OpenTofu and Ansible issues, which today have nowhere to run
from. The CA question the issue carried was answered by reading the root
first: the issue's premise — that the tier's step-ca already sits beneath
the estate's CA — is the sentence ADR-0037 retracted, and the estate's
root is `pathlen:0`, so the only question was where one key file sits. It
stays on `prometheus`, because the host that holds credentials for every
other host must not also hold the key every other host trusts, and
because VLAN 30 is the segment ADR-0014 built to hold attackers. Two things
the issue did not count: the Proxmox firewall on `Saruman` admits `8006`
from Hicks only, so the build widens ADR-0014's rule by one address on one
port, recorded as a marked amendment there and on ADR-0039; and
`certificates/ca-key.pem` has no backup or custody story at all, unlike
the age key and the tier's root — found, named in the ADR with what the
answer is not, and carried by
[#496](https://github.com/Gerrrt/HomeLab/issues/496). The same host is
where [ADR-0042](adr/0042-terminate-the-remote-path-on-the-lab-and-route-it.md)
terminates the remote path; that ADR left the `8006` question to this issue,
and it is taken here.
→ [runbook](runbooks/build-the-jumpbox.md)

## Decided but not built

Accepted ADRs with no work behind them. Recorded here because an accepted ADR
Expand Down
Loading
Loading