Helix9 Homelab — Architecture Overview
Reference documentation for the Helix9 homelab. This page is the orientation map: what runs where, how traffic flows, and how the moving parts compose. Drill into the section docs for details.
At a glance
- One DSL line (Telekom VDSL) terminates on a dedicated modem, with PPPoE handled by VyOS itself (post-Draytek migration).
- One Proxmox node (
pve02) hosts every internal service as an LXC container or VM. A second node (pve01) is bootstrapped but not yet in inventory. - One VPS (
vyos-edge) acts as the public-facing front door, reverse-tunneling traffic to home over IPsec for services that need to be reachable from outside. - All host config is code. Terraform provisions LXCs from inventory; Ansible configures everything inside them. No clicks, no drift.
- Identity is centralised. Authentik fronts every service that needs more than IP-based gating, via Traefik forward-auth.
Layered architecture
┌──────────────────────────────────────────────────────────────────────┐
│ Layer 6 — Identity │
│ Authentik (10.69.20.68) │
│ ─ forward-auth for *.home.helix9.org behind Traefik │
│ ─ OIDC/SAML for services that speak it natively │
└──────────────────────────────────────────────────────────────────────┘
┌──────────────────────────────────────────────────────────────────────┐
│ Layer 5 — Ingress / TLS │
│ Traefik (10.69.20.40) — single reverse proxy + ACME via Cloudflare │
│ DNS-01. File-provider config rendered by Ansible. │
└──────────────────────────────────────────────────────────────────────┘
┌──────────────────────────────────────────────────────────────────────┐
│ Layer 4 — Services │
│ SERVERS (VLAN 20): Paperless, Pulse, Uptime-Kuma, OneDev, │
│ Docusaurus, Authentik, Traefik, Copyparty, │
│ Mediastack (Jellyfin/Sonarr/Radarr/Sabnzbd) │
│ DMZ (VLAN 70): Synapse, Mumble, Minecraft, OpenClaw, │
│ Hookshot │
│ HOMELAB (VLAN 30): Home Assistant (HAOS VM) │
│ MGMT (VLAN 10): Proxmox, PBS, UniFi │
└──────────────────────────────────────────────────────────────────────┘
┌──────────────────────────────────────────────────────────────────────┐
│ Layer 3 — Network │
│ VyOS home router (vyos-fw) │
│ ─ 8 zones (LOCAL, WAN, MGMT, SERVERS, HOMELAB, TRUSTED, IOT, │
│ GUEST, DMZ, VPN), zone-based stateful firewall │
│ ─ DNS forwarder, DHCP server per zone, NAT, IPsec to VPS │
│ ─ Site-to-site IPsec (10.255.255.0/30) → vyos-edge VPS │
└──────────────────────────────────────────────────────────────────────┘
┌──────────────────────────────────────────────────────────────────────┐
│ Layer 2 — Hypervisor │
│ Proxmox VE — pve02 (active), pve01 (bootstrap only) │
│ ─ LXC for everything Linux-y, VM only for HAOS │
│ ─ Backups → PBS (pbs01) │
└──────────────────────────────────────────────────────────────────────┘
┌──────────────────────────────────────────────────────────────────────┐
│ Layer 1 — Physical │
│ Telekom VDSL → Draytek Vigor 167 (bridge mode) → VyOS eth1.7 │
│ Switch trunk → eth0 (carrier of all VLANs) │
│ UniFi AP trunk → eth2 │
└──────────────────────────────────────────────────────────────────────┘
Network zones
VyOS enforces a strict zone-based firewall. Every interface belongs to exactly one zone; cross-zone traffic is dropped by default.
| Zone | VLAN | Subnet | What lives here |
|---|---|---|---|
| MGMT | 10 | 10.69.10.0/24 | Proxmox, PBS, UniFi controller — admin plane |
| SERVERS | 20 | 10.69.20.0/24 | Internal services accessed via Traefik |
| HOMELAB | 30 | 10.69.30.0/24 | Home Assistant + IoT bridges |
| TRUSTED | 40 | 10.69.40.0/24 | Personal devices (laptops, phones, AppleTV) |
| IOT | 50 | 10.69.50.0/24 | Untrusted IoT (printer, sensors) |
| GUEST | 60 | 10.69.60.0/24 | Guest WiFi, internet-only |
| DMZ | 70 | 10.69.70.0/24 | Public-facing services (port-forwarded via VPS) |
| VPN | — | 10.255.255.0/30 | IPsec tunnel to VPS |
| WAN | — | dynamic | Public PPPoE interface |
Trust direction summary:
- TRUSTED → everywhere with
ALLOW-ALL. The owner's devices are fully trusted. - MGMT → everywhere. Admin operations need full reach.
- SERVERS / HOMELAB / IOT / GUEST / DMZ → internet via
ALLOW-INTERNET(with RFC1918 cross-pivot blocked); cross-zone is established-only by default, with explicit per-service holes (e.g. Pulse → MGMT for Proxmox API, NetBox → everywhere for scanning). - WAN → only
ALLOW-ESTABLISHEDreturning to internal zones. No unsolicited inbound.
Full zone matrix and per-policy rules in Home Router.
Traffic flows
Internal client → internal service
laptop (TRUSTED)
│ https://paperless.home.helix9.org
▼
VyOS DNS forwarder
│ static mapping: paperless.home.helix9.org → 10.69.20.40 (Traefik)
▼
Traefik (10.69.20.40)
│ TLS terminate, route by Host header
│ middleware: authentik (or local-only for LAN-only services)
▼
backend (10.69.20.72:8000 — paperless)
Same VLAN-to-VLAN passes the SERVERS-LOCAL / SERVERS-MGMT / etc. zone policies; cross-zone only because Traefik is the gateway.
External client → public service (DMZ)
internet
│ https://openclaw.helix9.org
▼
Cloudflare DNS → 152.53.173.192 (VPS secondary IP)
│
▼
vyos-edge (VPS, 159.195.87.143)
│ DNAT 152.53.173.192:443 → 10.69.20.40:443 (via vti0)
▼
IPsec tunnel (10.255.255.0/30)
│
▼
vyos-fw (home)
│ routed via vti0 → SERVERS zone
▼
Traefik (10.69.20.40)
│ Authentik forward-auth
▼
backend (e.g. OpenClaw 10.69.70.50)
This is the only path public traffic takes. Home does not expose any port on its own public IP — every external service rides through the VPS tunnel.
Why the VPS
Three reasons:
- Stable public IP — Telekom hands out a dynamic IPv4 with daily forced reconnect. The VPS has a static
159.195.87.143and a secondary152.53.173.192. - DDoS / scan absorption — bad traffic terminates on the VPS edge, never crosses the home WAN.
- Per-service public IP isolation — Mumble/Minecraft/Matrix-federation get the secondary IP; the primary IP is reserved for Matrix HTTPS / federation. Lets the same backend ports coexist.
Infrastructure as Code
Two-stage pipeline. Terraform creates infrastructure, Ansible configures it.
inventory/host_vars/<host>/vars.yml (single source of truth per host)
│ ├─ lxc_cores, lxc_memory, lxc_disk ← Terraform reads
│ └─ <service-specific config> ← Ansible reads
▼
Terraform (terraform/proxmox/) provisions LXC on Proxmox
│ uses bpg/proxmox provider; one .tf file per host
▼
Ansible (playbooks/) configures inside the LXC
│ roles/common, roles/ssh, roles/users → base hardening
│ roles/<service> → service-specific
▼
Service running, registered in DNS via roles/vyos_dns
Adding a new host
The end-to-end flow (full detail in New Host):
- Add to
inventory/hosts.ymlwith IP + VMID. - Create
inventory/host_vars/<host>/vars.ymlwith LXC sizing + service vars. - Add an
lxc_<host>.tfinterraform/proxmox/(or uselxc_managed.tf). terraform apply→ LXC exists.ansible-playbook playbooks/<service>.yml→ LXC configured + service running.ansible-playbook playbooks/vyos_dns.yml→ shortname → IP mapping pushed to VyOS DNS.- If the service has a web UI, add a Traefik router (
roles/traefik/templates/services.yml.j2) and re-runplaybooks/traefik.yml.
Repos
/home/marko/code/ansible— inventory, playbooks, roles, terraform/. Hosted atonedev.home.helix9.org/Ansible./home/marko/code/docusaurus— these docs. Hosted atdocs.home.helix9.org, auto-deployed via webhook on push.
Identity, ingress, DNS
These three layers compose end-to-end:
| Concern | Component | Notes |
|---|---|---|
| Authoritative DNS | Cloudflare | helix9.org zone — public records + ACME DNS-01 token |
| Recursive DNS | VyOS forwarder | Per-zone :53 listener; static mappings for *.home.helix9.org and shortnames; (Technitium LXC at 10.69.20.53 is dormant) |
| Split horizon | VyOS static-host overrides | paperless.home.helix9.org → 10.69.20.40 internally vs. VPS public IP externally |
| TLS / ingress | Traefik | One cert per host via Cloudflare DNS-01; file-provider config rendered by Ansible |
| AuthN/AuthZ | Authentik | Forward-auth via outpost.goauthentik.io/auth/traefik; OIDC for native integrations |
Detailed flow walk-throughs:
Hosts at a glance
| Host | IP | VMID | Zone | Role |
|---|---|---|---|---|
pve02 | 10.69.10.20 | — | MGMT | Proxmox hypervisor (active) |
pbs01 | 10.69.10.25 | 200 | MGMT | Proxmox Backup Server |
unifi | 10.69.10.15 | 115 | MGMT | UniFi controller |
traefik | 10.69.20.40 | 240 | SERVERS | Reverse proxy + TLS |
authentik | 10.69.20.68 | 268 | SERVERS | Identity provider |
paperless | 10.69.20.72 | 272 | SERVERS | Document management |
pulse | 10.69.20.60 | 260 | SERVERS | Proxmox monitoring |
uptime-kuma | 10.69.20.75 | 275 | SERVERS | Service monitoring |
onedev | 10.69.20.76 | 276 | SERVERS | Self-hosted Git + CI |
docusaurus | 10.69.20.77 | 277 | SERVERS | These docs |
copyparty | 10.69.20.20 | 220 | SERVERS | File server |
podman | 10.69.20.10 | 100 | SERVERS | Generic container host |
technitium | 10.69.20.53 | 253 | SERVERS | DNS resolver (dormant) |
synapse | 10.69.70.30 | 730 | DMZ | Matrix homeserver |
hookshot | 10.69.70.40 | 740 | DMZ | Matrix bridge |
mumble | 10.69.70.10 | 710 | DMZ | Voice server |
minecraft | 10.69.70.20 | 720 | DMZ | Minecraft server |
openclaw | 10.69.70.50 | 750 | DMZ | Matrix-integrated game |
haos | (VLAN 30) | 101 | HOMELAB | Home Assistant OS (VM, not Ansible-managed) |
vyos-fw | gateways .1 | — | LOCAL | Home router |
vyos-edge | 159.195.87.143 | — | (VPS) | Public edge router |
Source of truth: inventory/hosts.yml.
Where to read next
- Networking — Home Router, Edge Router (VPS), Draytek migration runbook
- Automation — Ansible setup, Terraform setup, Adding a new host
- Services — Traefik, Authentik, and individual service pages