jerry@homelab:~/docs$ cat architecture.md
Homelab Architecture & The Mesh
Security in a homelab shouldn't mean relying on a tangle of firewall port forwards. Here is a breakdown of how I designed my infrastructure so that no internal service is ever bound to 0.0.0.0 -- everything routes through a tightly controlled reverse proxy layer combined with Authelia for single sign-on (SSO) and multi-factor authentication.
kroskinski.com root/www *.kroskinski.com apps
βββββββββββββββββββββββββββ ββββββββββββββββββββββββββββββββ
β Oracle Cloud VM β β TransIP A records point at β
β its OWN public Caddy β β Wasteland's TAILSCALE IP -- β
β (static file_server) β β not actually reachable off β
β unrelated to Wasteland β β the tailnet despite being β
βββββββββββββββββββββββββββ β "public" DNS β
βββββββββββββββββ¬βββββββββββββββββ
β
[ LAN device ] βββΆ Pi-hole local DNS βββΆ β
[ Tailscale device ] ββββββββββββββββββββββββββββββΆ
βΌ
ββββββββββββββββββββββββββββββββ
β Caddy (runs ON Wasteland) β
β binds ONLY LAN IP + Tailscaleβ
β IP -- never 0.0.0.0 β
βββββββββββββββββ¬βββββββββββββββββ
β forward_auth
βΌ
ββββββββββββββββββββββββββββββββ
β Authelia (also on Wasteland) β
ββββββββββββββββββββββββββββββββ
Minecraft game ports: router-port-forwarded straight to
Wasteland, bypassing Caddy entirely -- the one deliberate
raw public exposure in this whole project.
The Edge & Tailscale
Caddy and Authelia run together, directly on Wasteland -- there's no separate reverse-proxy VM in front of it. Caddy binds only to Wasteland's LAN IP and its own Tailscale IP, never 0.0.0.0. Most *.kroskinski.com subdomains do have public TransIP A records, but they resolve to Wasteland's Tailscale IP -- an overlay-only address that's meaningless to reach from the open internet. On the LAN or over Tailscale, Pi-hole's local DNS records resolve the same hostnames straight to Caddy instead. Apps that actually run on Badlands, or on the external Oracle Uptime VM, are reverse-proxied to *by* Wasteland's Caddy over their Tailscale IPs -- Caddy on Wasteland remains the single entry point regardless of which host serves the request.
The kroskinski.com root site is a genuinely separate thing: it lives on its own Oracle Cloud VM with its own independently, publicly-bound Caddy instance, and has no relationship to Wasteland's traffic at all -- see Website. The only other deliberate public exception anywhere in this project is Minecraft's game ports, router-port-forwarded straight to Wasteland, bypassing Caddy entirely.
Zero-Trust via Authelia
Before Caddy allows traffic to reach private services like Immich or Paperless, it issues a forward-auth request to Authelia. If the device isn't authenticated with SSO and a 2FA hardware key, the packet never makes it to the target container.
- One-Factor / Two-Factor Policies: Administrative dashboards demand hardware-backed 2FA, while lighter endpoints utilize basic session validation.
- Internal Mesh: Tailscale overlays everything, allowing secure node-to-node communication between
wastelandandbadlandswithout exposing ports to the open internet.
For the full breakdown -- forward-auth vs. real OIDC, session behaviour, and the gotchas that came with rolling it out -- see Single Sign-On. For how this extends across every host in the mesh, not just requests through Caddy, see Multi-Host Management.
Security Rule: If a container doesn't explicitly need external exposure via Caddy, it lives entirely behind the Tailscale tailnet or local Docker bridge networks.
jerry@homelab:~/docs$ β
cd ..