Skip to content

Tailscale Zero Trust Architecture

Tailscale is the sole remote access mechanism. No management interfaces or internal services are directly exposed to the internet.

All Tailscale nodes live in the DMZ (VLAN 176).


Nodes

Host CT ID IP Role
ts-gateway CT123 (pve0-core) 10.37.176.22 Subnet router. Primary path into the homelab. Tagged tag:subnet-router.
services-proxy-01 CT124 (pve0-core) 10.37.176.32 Caddy reverse proxy. HTTPS entry point for internal services. Tagged tag:reverse-proxy.
bastion CT109 (pve0-core) 10.37.176.23 SSH bastion. Fallback management access. Tagged tag:bastion.

Access Paths

Management (subnet router)

ts-gateway advertises homelab subnets to the Tailnet. Authenticated Tailscale clients can reach management interfaces (Proxmox, OPNsense, etc.) as if they were on the local network.

Fallback — Tailscale down: if ts-gateway is unreachable, bastion provides shell access with direct connectivity to management interfaces. Since bastion is a separate LXC, it can be up even if the subnet router is having issues.

Fallback — Tailscale completely down: a firewall rule permits SSH (port 22) to bastion from VLAN 192 (Home, 10.37.192.0/24). This allows access from a trusted device on the local network without relying on Tailscale at all. Bastion accepts SSH keys only — password authentication is disabled.

Services (reverse proxy)

services-proxy-01 (Caddy) is a Tailscale node. Internal services are accessed over HTTPS through it. This keeps services off the public internet while still being reachable from anywhere via Tailscale.

Public services

Handled separately by cloudflared (Cloudflare Tunnel) — not through Tailscale.


Users & Groups

Group Members Purpose
group:homelab-admins admin Full admin access.
group:family admin, partner Access to services and media.
group:secours partner Emergency-only access to bastion (girlfriend).

Device Tags

Tag Owner Devices
tag:subnet-router homelab-admins ts-gateway
tag:bastion homelab-admins bastion
tag:reverse-proxy homelab-admins services-proxy-01
tag:media-player homelab-admins Apple TV, etc.

Security Postures

posture:secure-admin = node:tsStateEncrypted AND node:tsReleaseTrack == 'stable'

Required for admin access to Proxmox and network infrastructure. Ensures the connecting device has encrypted Tailscale state and runs a stable release.


IP Sets

IP Set Members Notes
ipset:dns-servers 10.37.64.53, 10.37.64.54 (+ IPv6) AdGuard + BIND
ipset:proxmox-cluster 10.37.16.2, 10.37.16.3 (+ IPv6) Both nodes
ipset:network-infra 10.37.0.1, 10.37.8.2, 10.37.0.15, 10.37.0.17 (+ IPv6) OPNsense, Omada, switch01, switch02
ipset:reverse-proxy 10.37.176.32 (+ IPv6) Caddy
ipset:wazuh 10.37.64.64 Wazuh SIEM
ipset:hdhomerun 10.37.192.64 (+ IPv6) HDHomerun OTA tuner
ipset:ups 10.37.0.2 UPS management
ipset:docker-hosts 10.37.64.41 docker-prod-01

Access Control Rules

Family & Media Players

Source Destination Ports Notes
family, media-player dns-servers 53 DNS resolution
family, media-player reverse-proxy 80, 443 Services via Caddy
family, media-player hdhomerun * Live TV (direct tuner access for non-Jellyfin apps)
family, media-player autogroup:internet * Exit node for privacy/travel

Admins (homelab-admins)

Destination Ports Posture Required
proxmox-cluster 8006, 22 posture:secure-admin
network-infra 80, 443, 8043, 22 posture:secure-admin
dns-servers 53, 80, 12321, 22 No
docker-hosts 9443 No
ups 80, 443 No
wazuh 443 No
tag:bastion 22 No

Emergency Access (group:secours)

Destination Ports Notes
tag:bastion 22 Bastion only. Tailscale SSH as secours user.

Infrastructure

Source Destination Ports Notes
tag:subnet-router dns-servers 53 DNS only — cannot reach other services (defense in depth)
family, subnet-router, bastion, reverse-proxy wazuh 1514, 1515, 55000 Wazuh agent reporting

SSH Policy

Source Destination Auth Method User Notes
group:homelab-admins tag:bastion Traditional SSH (Secure Enclave key) nonroot Not using Tailscale SSH for admin — defense in depth
group:secours tag:bastion Tailscale SSH secours Emergency access only

Tailscale Lock

Tailscale Lock is enabled. All new nodes must be signed by a trusted signing node before they can join the tailnet.

Signing Nodes

Device Role
Personal iPhone Primary signing node
MacBook Pro Primary signing node
bastion Emergency signing node — used if all personal devices are lost

The tailnet disablement secret is stored in Bitwarden (see secrets.md) in case the lock needs to be disabled.


Design Principles

  • No open inbound ports on WAN — all remote access goes through the Tailscale overlay.
  • DMZ placement — all Tailscale nodes sit in VLAN 176 with controlled access to other segments.
  • Posture enforcement — Proxmox and network gear require encrypted state + stable client before granting access.
  • Subnet router is not privilegedts-gateway can only reach DNS. Traffic from Tailscale clients hits destination IPs directly, not via the router. Defense in depth.
  • Redundant management — subnet router (ts-gateway) + bastion cover failure of either path.
  • Emergency path — partner has Tailscale SSH access to bastion only, with a dedicated secours account.
  • randomizeClientPort: true — reduces Tailscale fingerprinting on the WAN.