# README # 🏠 lerkolabs — Home Infrastructure Lab > Personal infrastructure environment for learning, self-hosting, and operational practice. Running 24/7 on production-grade hardware with real network segmentation, SSO, monitoring, and IaC-style documentation. --- ## ⚡ At a Glance | | | |-----|-----| | **Hypervisor** | Proxmox VE | | **Firewall** | pfSense (Intel N100) | | **Switching** | TP-Link Omada (managed, VLANs) | | **ISP** | AT&T Fiber 1Gbps — IP Passthrough → pfSense WAN | | **VPN** | WireGuard (pfSense) | | **Reverse Proxy** | Caddy + Cloudflare DNS-01 — wildcard SSL on `*.lerkolabs.com` | | **Auth** | Authentik SSO — OIDC + forward auth across all services | | **DNS** | Pi-hole → pfSense Unbound → Cloudflare | | **Containers** | 9 LXC containers + 2 VMs | | **Self-hosted services** | 20+ | --- ## 🌐 Network Architecture **8 isolated VLANs** — strict inter-VLAN firewall policy (default deny): | VLAN | Name | Subnet | Purpose | |------|------|--------|---------| | 1000 | MGMT | `10.0.0.0/24` | Network equipment only | | 1010 | LAN | `10.1.0.0/24` | Trusted personal devices | | 1020 | Homelab | `10.2.0.0/24` | All self-hosted services | | 1030 | Guests | `10.3.0.0/24` | Internet only, RFC1918 blocked | | 1040 | IoT | `10.4.0.0/24` | Smart home, isolated | | 1050 | WFH | `10.5.0.0/24` | Work devices, no personal access | | 1 | DMZ | `10.99.0.0/24` | Public-facing, hard-blocked internally | | — | VPN | `10.200.0.0/24` | WireGuard clients = LAN access | Work devices (VLAN 1050) are isolated from *all* personal infrastructure — they use pfSense DNS only, never Pi-hole. WireGuard VPN clients get full LAN-equivalent access without being on the physical network. --- ## 🖥️ Compute — LXC / VM Layout | Container | IP | Cores | RAM | What Runs | |-----------|-----|-------|-----|-----------| | `pihole` | 10.2.0.5 | 1 | 512MB | Pi-hole DNS + ad blocking | | `auth` | 10.2.0.25 | 1 | 512MB | Authentik SSO + Redis | | `infra` | 10.2.0.20 | 2 | 1GB | Caddy reverse proxy, ntfy | | `monitor` | 10.2.0.51 | 4 | 4GB | Victoria Metrics, Grafana, Beszel | | `apps` | 10.2.0.60 | 4 | 6GB | 15+ productivity apps (Docker) | | `vault` | 10.2.0.X | 1 | 256MB | Vaultwarden (isolated) | | `servarr` (VM) | — | 4 | 8GB | Plex, Jellyfin, \*arr stack, qBittorrent | | `haos` (VM) | — | 2 | 4GB | Home Assistant OS | --- ## 🚀 Self-Hosted Services ### Core Infrastructure | Service | Role | |---------|------| | pfSense | Firewall, DHCP, routing, WireGuard VPN | | Pi-hole | Network-wide DNS + ad blocking | | Caddy | Reverse proxy, automatic wildcard TLS | | Authentik | SSO provider — OIDC + forward auth | | Vaultwarden | Self-hosted password manager | | Victoria Metrics + Grafana | Metrics, dashboards, alerting | | Beszel | Container + host monitoring | | ntfy | Push notifications | ### Productivity (`apps` LXC — all behind Authentik SSO) | Service | URL | Purpose | |---------|-----|---------| | Outline | `outline.lerkolabs.com` | Team wiki | | Gitea | `gitea.lerkolabs.com` | Personal Git | | Vikunja | `tasks.lerkolabs.com` | Task management | | Ghostfolio | `finance.lerkolabs.com` | Portfolio tracking | | Hoarder | `hoarder.lerkolabs.com` | Bookmark manager | | Grist | `grist.lerkolabs.com` | Spreadsheets / data | | Actual Budget | `budget.lerkolabs.com` | Personal budgeting | | FreshRSS | `rss.lerkolabs.com` | RSS reader | | Memos | `memos.lerkolabs.com` | Quick notes | | Traggo | `time.lerkolabs.com` | Time tracking | | Baikal | `dav.lerkolabs.com` | CalDAV / CardDAV | | Glance | `glance.lerkolabs.com` | Homepage dashboard | | Filebrowser | `files.lerkolabs.com` | File management | ### Media | Service | Purpose | |---------|---------| | Plex + Jellyfin | Media streaming | | Sonarr / Radarr / Lidarr | Automated media management | | Prowlarr + Bazarr | Indexer aggregation + subtitles | | qBittorrent (VPN-gated) | Downloads via Gluetun | | Calibre-Web Automated | Book library with auto-ingest | | Kavita | E-reader | --- ## 🔒 Security Design * All services require Authentik authentication — no anonymous access * Caddy handles TLS termination; internal services run HTTP only * VPN-only admin access to pfSense, Proxmox, Pi-hole * IoT devices can only reach the internet and Home Assistant * Guests are RFC1918 hard-blocked — internet only * WFH laptop on isolated VLAN, DNS from pfSense only * Vaultwarden isolated in its own LXC — no shared container * Zero open ports for management traffic (all VPN-gated) --- ## 🗂️ Architecture Decisions Short-form ADRs documenting *why* things are built this way: * **AT&T IP Passthrough over EAP bypass** — AT&T locks 802.1X to their gateway; passthrough mode gives pfSense the real public IP without brittle workarounds. * **Caddy over NGINX Proxy Manager** — single Caddyfile, auto-cert via Cloudflare DNS-01, no UI overhead. * **WireGuard over OpenVPN** — lower latency, better mobile battery life, \~600Mbps on the N100. * **Authentik over Authelia** — full OIDC provider + forward auth in one. Lets services like Outline, Gitea, and Vikunja use real SSO rather than just a login gate. * **Shared Postgres + Redis in** `**apps**` **LXC** — one instance, multiple databases. Avoids 15 separate DB containers; a single init script provisions all schemas on first run. * **N100 for pfSense** — 6W idle, handles 2–3Gbps routing + 600Mbps WireGuard. Right-sized for 1Gbps fiber. * **Pi-hole in Homelab VLAN, not MGMT** — MGMT access from all VLANs would be a larger attack surface than filtering DNS traffic. --- ## 📁 Repo Structure ```bash homelab/ ├── docs/ │ ├── README.md # quick reference — IPs, URLs, hardware │ ├── SERVICES.md # full service registry (IP, port, VLAN, status) │ ├── NETWORK.md # VLAN map, firewall policy, DNS architecture │ ├── DECISIONS.md # ADRs — why things are configured the way they are │ ├── RUNBOOKS.md # break-fix procedures │ ├── SECURITY.md # open ports, update cadence, known debt │ └── setup/ # one-time deploy guides (archived, read-only) ├── configs/ │ ├── caddy/ # Caddyfile + compose │ ├── pfsense/ # config.xml exports │ ├── pihole/ # teleporter backups │ └── lxc/ # per-container configs └── scripts/ # automation, health checks ``` --- ## 🔗 Contact \ ![LinkedIn](uploads/164c25fb-9f88-4726-87fb-a640c43b142f/75308bef-4010-4a87-8afb-c9896f0eb6ba/LinkedIn-Connect-0A66C2 " =112x20") ![GitHub](uploads/164c25fb-9f88-4726-87fb-a640c43b142f/10d87e72-d33c-4cd3-99b7-2595a9501f5f/GitHub-lerkolabs-181717 " =123x20") \ > *This lab is actively maintained and evolving. Documentation lives alongside the infrastructure.*