Secure Remote Access: Tailscale Subnet Routing + Cloudflare Zero Trust

Objective

Reach the lab’s dashboards — Splunk, Pi-hole, Proxmox — from anywhere, without doing the one thing that turns a homelab into an internet-facing liability: opening inbound ports. The design goal was layered access with different trust models: full network access for my own devices, and identity-checked, browser-only access for individual web UIs.

Tools & Technologies

  • Tailscale — WireGuard-based mesh overlay, with subnet routing advertised from the Proxmox host
  • Cloudflare Tunnel (cloudflared) — outbound-only connector running in an LXC on Proxmox
  • Cloudflare Access (Zero Trust) — identity-provider-backed policies with JWT validation in front of each service

Architecture / Workflow

Layer 1 — device-level (Tailscale)
  My devices ⇄ Tailscale mesh ⇄ Proxmox host
  Proxmox advertises --advertise-routes=192.168.1.0/24
  → any lab IP reachable from any of my devices, full protocols

Layer 2 — service-level (Cloudflare)
  Browser → service subdomain → Cloudflare edge
  → Access policy (IdP login, JWT issued)
  → Cloudflare Tunnel (outbound from cloudflared LXC)
  → internal service (Splunk / Pi-hole / Proxmox)

What I Configured

  • Tailscale subnet routing on the Proxmox host with --advertise-routes=192.168.1.0/24, approved in the admin console — one node makes the entire lab subnet reachable across the mesh without installing agents on every guest.
  • cloudflared in a dedicated LXC, establishing an outbound-only tunnel to Cloudflare’s edge. The lab initiates the connection; nothing on the WAN listens.
  • Public hostnames per service — subdomains mapped through the tunnel to internal IPs and ports for Splunk, Pi-hole, and Proxmox.
  • Cloudflare Access policies in front of every hostname: authentication against the identity provider, session JWTs validated at the edge, so a request never reaches the lab without a verified identity.
  • Proxmox behind the tunnel required the “No TLS Verify” origin setting, since the Proxmox web UI presents a self-signed certificate to cloudflared inside the LAN.

Key Findings

  • The two layers answer different questions. Tailscale answers “is this my device?” — great for SSH, full dashboards, and anything non-HTTP. Cloudflare Access answers “is this my identity?” — great for browser access from any machine, including ones I don’t own.
  • Outbound-only tunneling inverts the exposure model: the attack surface of “open ports on a residential IP” simply doesn’t exist. Scanning my WAN address finds nothing.
  • Zero Trust concepts from the enterprise world — identity-aware proxying, per-application policy, JWT session validation — translate directly to a homelab at zero cost, and configuring them by hand teaches more than any diagram.

Skills Demonstrated

Zero Trust architecture design, WireGuard/overlay networking, subnet routing, reverse tunneling, identity-provider integration and policy design, TLS trust chain troubleshooting.

What I Learned

Remote access design is threat modeling. Writing down “who needs to reach what, from where, with what proof” produced a two-layer answer no single product covers — and the same reasoning applies one-to-one to how enterprises are replacing legacy VPNs with identity-aware access.

Next Steps

  • Add device posture checks to Access policies (require known devices, not just known identities)
  • Tailscale ACLs to scope which mesh devices can reach which lab IPs — least privilege inside the overlay
  • Alerting on Access logins from new locations, fed back into the Splunk pipeline