Infrastructure
Segmented Home Lab & Observability Stack
Seven VLANs, default-deny between every one of them.
- Proxmox VE
- pfSense
- Docker
- Prometheus
- Grafana
- Loki
- isolated VLANs
- 7
- inter-VLAN rules total
- 2
- alert rules
- 40
- dashboard panels
- 79
Most home labs are a flat network with a hypervisor on it. This one is segmented the way a real environment is, because the point is to produce realistic telemetry: if everything can reach everything, lateral movement generates no interesting signal and a detection that fires here proves nothing.
Seven VLANs sit behind a pfSense firewall with default-deny between every segment. Exactly two inter-VLAN rules exist, both deliberate and both documented. IoT, media, and guest segments are terminal — egress only, no path back inward. Every allowance is an explicit decision with a written rationale rather than an accumulated exception.
Observability is the other half. Prometheus and Loki feed five provisioned Grafana dashboards across 79 panels, with 40 alert rules — 32 Prometheus and 8 Loki LogQL. That is what makes the lab useful for detection work: a technique can be run and the resulting artifacts observed end to end.
It is maintained like production. Container images are pinned by sha256 digest rather than floating tags, decisions are captured in architecture decision records, and operational procedures are written down as runbooks so recovery is not reconstructed from memory at 2am.
Details
- Seven VLANs, default-deny between all segments, exactly two documented inter-VLAN allowances
- IoT, media, and guest networks are terminal — egress only, no inbound path
- Five provisioned Grafana dashboards, 79 panels, 40 alert rules (32 Prometheus + 8 Loki LogQL)
- Every container image pinned by sha256 digest — no floating tags, no surprise upgrades
- 5 architecture decision records and 4 operational runbooks
- CI validates with promtool and amtool, boots a real Loki instance, and runs gitleaks over full history
- Secrets encrypted at rest with SOPS + age; nothing sensitive in plaintext in the repo