Skip to content
Go back

The Zero-Trust Home Lab

· Updated:
By SumGuy 6 min read
The Zero-Trust Home Lab

Let’s be real: setting up a traditional VPN like OpenVPN in 2024 feels like trying to tune a carburetor in a Tesla world. You spend three hours generating certificates, another two fighting with your ISP’s CGNAT (Carrier-Grade NAT), and eventually, you just give up and open Port 1194, praying the script kiddies don’t notice.

We’re done with that. If you want to access your Home Assistant dashboard or your “totally legal” Linux ISO collection from a coffee shop, you need a Mesh VPN. We’re pitting the WireGuard-powered Tailscale against the virtual-ethernet magic of ZeroTier and the aging king, OpenVPN.

Key Takeaways

The Comparison: Choose Your Fighter

FeatureOpenVPN (The Classic)Tailscale (The Darling)ZeroTier (The Swiss Army Knife)Setup Time45 mins (if lucky)2 minutes3 minutesFirewallRequires open portsWorks behind NATWorks behind NATProtocolTLS/SSL (Heavy)WireGuard (Fast)Custom (Layer 2 Ethernet)Best ForHardcore LegacyEase of Use / SSOLAN Games / MulticastScalabilityManual & PainfulAutomaticNetwork ID based

Method 1: The “I Just Want It to Work” (Tailscale Docker)

Tailscale is a “SaaS” wrapper around WireGuard. It’s slick, it handles SSO (Google/GitHub/Microsoft), and it just works. Here is how you spin up a node on your server using Docker Compose.

docker-compose.yml
services:
tailscale:
image: tailscale/tailscale:latest
container_name: tailscale
hostname: homeserver-primary
network_mode: "host"
volumes:
- ./state:/var/lib/tailscale # Persists keys so you don't re-auth every reboot
- /dev/net/tun:/dev/net/tun # Required for tunnel creation
cap_add:
- NET_ADMIN
- NET_RAW
environment:
- TS_STATEFUL_FILTERING=true
restart: unless-stopped

Method 2: The “Virtual Ethernet” Approach (ZeroTier)

While Tailscale is like a smart router, ZeroTier is like an invisible Ethernet cable. Because it operates at Layer 2, it supports things Tailscale struggles with—like mDNS, broadcast, and multicast. If you’re trying to play StarCraft over a VPN or discovery-based protocols, this is your winner.

Joining a Network via CLI

If you already have a ZeroTier Network ID, joining from a Linux server is a one-liner:

# Install and join in one go (standard Debian/Ubuntu)
curl -s [https://install.zerotier.com](https://install.zerotier.com) | sudo bash
sudo zerotier-cli join <your_network_id> # Replace with your 16-digit ID
# Check your status
sudo zerotier-cli listnetworks

Dockerized ZeroTier Node

Want to keep your host OS clean? Run ZeroTier in a container:

zerotier-compose.yml
services:
zerotier:
image: zerotier/zerotier:latest
container_name: zerotier
devices:
- /dev/net/tun:/dev/net/tun
network_mode: host
cap_add:
- NET_ADMIN
- SYS_ADMIN
volumes:
- ./zt-data:/var/lib/zerotier-one
restart: unless-stopped

Method 3: The “De-Clouded” Path (Headscale)

If the proprietary “Control Plane” of Tailscale gives you the creeps, Headscale is your savior. It’s an open-source implementation of the coordination server. You host it on a $5 VPS, and suddenly, you own the entire map. No Big Tech required.

# Quick Headscale config initialization
mkdir -p ./headscale/config
curl [https://raw.githubusercontent.com/juanfont/headscale/main/config-example.yaml](https://raw.githubusercontent.com/juanfont/headscale/main/config-example.yaml) -o ./headscale/config/config.yaml
# Point it to your actual domain
sed -i 's|[http://127.0.0.1:8080](http://127.0.0.1:8080)|[https://vpn.sumguy.com](https://vpn.sumguy.com)|g' ./headscale/config/config.yaml

Why “Zero-Trust” is the Real Flex

In the old days of OpenVPN, once a user was “in,” they could see everything. It was a security nightmare. Modern mesh VPNs use Identity-Based Networking.

In Tailscale or ZeroTier, a device doesn’t just “connect”—it must be Authorized. You can write ACLs (Access Control Lists) that say “My phone can see the Plex server, but the Plex server can’t see my phone.” That is the essence of Zero-Trust: verify everything, trust nothing.

Final Thought

OpenVPN served us well for a decade, but we’ve moved past the era of static IPs and manual port forwarding. Tailscale is the king of UX, ZeroTier is the king of “it feels like a local wire,” and both are miles ahead of punching holes in your firewall. Choose your tool, stop opening ports, and start building.

The Gotcha Nobody Warns You About: DNS Leaks and Split Horizons

Here’s the thing — you get Tailscale or ZeroTier humming along, traffic tunnels beautifully, and then you try to reach your Proxmox node by hostname from your laptop at the coffee shop. Nothing. You ping the Tailscale IP directly and it works fine. What gives?

DNS. It’s always DNS.

Mesh VPNs tunnel your traffic, but they don’t automatically fix your resolver. Your laptop is still asking your ISP’s DNS (or 8.8.8.8) to resolve proxmox.home.lab, and obviously that’s not in their zone file. You need a split-horizon DNS setup where internal hostnames resolve to internal addresses, everywhere you are.

Tailscale makes this unusually painless with MagicDNS. Once enabled in the admin panel, your nodes register their Tailscale hostnames automatically. Your server named homeserver-primary becomes reachable at homeserver-primary.your-tailnet.ts.net without any manual DNS records. Enable it once, forget about it forever.

For ZeroTier, you have to do it yourself. The most common approach is running a lightweight DNS server — Pi-hole or a dedicated Unbound instance — on a node inside the ZeroTier network, then pushing that resolver via DHCP or manual config to all your devices.

If you’re running Pi-hole already, point your client’s DNS at the ZeroTier IP of your Pi-hole node:

Terminal window
# Check your ZeroTier node's assigned IP
sudo zerotier-cli listnetworks
# Then set your client's DNS manually (Linux / systemd-resolved)
sudo resolvectl dns ztXXXXXXXX 10.147.17.2
sudo resolvectl domain ztXXXXXXXX ~home.lab

For Tailscale users who also run a local resolver, you can override MagicDNS for specific domains in the admin panel under DNS → Nameservers → Restrict to search domain. This lets Tailscale handle .ts.net resolution while your Pi-hole handles .home.lab — the best of both worlds.

The quick sanity check when something feels off:

Terminal window
# On the client, check which resolver is actually being used
resolvectl status
# Then try resolving a known internal hostname explicitly
dig @10.147.17.2 proxmox.home.lab

If dig works but normal browsing doesn’t, your resolver routing is the problem, not the tunnel. Fix the DNS, and everything else snaps into place.


Share this post on:

Send a Webmention

Written about this post on your own site? Send a webmention and it'll show up above once verified.


Previous Post
The Role of Antivirus and Endpoint Detection and Response Systems
Next Post
Ubuntu Debian packages have been kept back error

Discussion

Powered by Garrul . Sign in with GitHub or Google, or post anonymously.

Related Posts