October 31, 2026 · James Meadlock & Milo (Milo, on session model claude-opus-5-5 via anthropic; reasoning setting not recorded) · plan, nothing deployed yet

Leaving Tailscale for plain WireGuard: one hub, one DNS name, and Bob's Mac

Created · Updated

In plain English. Tailscale has been doing three jobs for us: building encrypted tunnels, finding each machine wherever it is, and keeping a list of names. Plain WireGuard only does the first job. So moving off Tailscale means picking a replacement for the other two.

Bottom line: it is doable with gear we already own. Run it side by side with Tailscale for two weeks before switching anything off.

RECOMMENDATION Hub and spoke on the UniFi gateway's built-in WireGuard server. Dynamic DNS for the hub only. Every remote device, Bob's Mini included, dials out with a 25-second keepalive. Run it next to Tailscale until each node has a proven WireGuard path.
Tailnet today18 nodes8 online at check time
Hubs1UniFi Dream Machine Pro
Names that need DDNS1the hub
DDNS at Bob'snonehe dials out
Hub and spoke: only the hub needs a DNS name vpn.(infra domain) DDNS → hub's current IP funland gateway (hub) WireGuard server · UDP 51820 James: phone + laptop on-demand, off home Wi-Fi funland2 site site-to-site tunnel Remote family Minis dial out, keepalive 25 s Bob's Mac Mini dials out · no DDNS needed Arrows = who starts the tunnel. Bob → funland LAN is blocked; James → Bob is allowed.

Figure 1. Target shape. The dashed box is the only name that has to follow a changing IP address.

What we have today

Checked from the M4 Max on October 31, 2026. The tailnet has 18 nodes and 8 were online: workstations, the GB300 Station, a NetBox/agent box, family Macs, phones and tablets. Most lab machines share one LAN with the gateway. They only use Tailscale when James is away from home. Bob is not on this tailnet.

Both of our sites run UniFi gateways on UniFi OS 5.1.132. The main gateway holds a real public IPv4 address. We checked that the address on its WAN port is the same one the internet sees, so there is no carrier-grade NAT in front of it. That matters, because a WireGuard server behind CGNAT cannot take incoming connections at all. The address is assigned by DHCP, so it can change.

The dynamic DNS problem

A WireGuard peer can point at a hostname, but WireGuard looks that name up once and then never again (ArchWiki). DDNS only helps if two things happen. The name has to stay current. And clients have to look it up again when the address changes.

Keeping the name current

Making clients look the name up again

Bob's Mac Mini

The request was that Bob "advertise his dynamic IP somehow." The better design gets rid of that need. WireGuard has built-in roaming: after each authenticated packet, the receiver remembers the address that packet came from. If Bob's Mini dials our hub and sends a keepalive every 25 seconds, the hub always knows where Bob is. James can reach Bob through the tunnel. Bob's router needs no open port, and his house needs no DDNS.

What we give up

CapabilityTailscalePlain WireGuard hub
Path between two remote machinesDirect, via NAT traversalThrough the hub, both ways
Networks that block UDP (some hotels)DERP relay over HTTPSTunnel fails; keep a fallback
NamesMagicDNSGateway local DNS, pushed as the tunnel's DNS server
Who can reach whatCentral ACL policy + identityGateway firewall rules per tunnel IP
KeysRotated and expired by the serviceOurs: generate on device, vault any config that holds a private key
Extras (Taildrop, Tailscale SSH)Built inGone; plain SSH and AirDrop instead
Third-party coordination serviceRequiredNone

Middle path. If the main goal is getting off Tailscale's cloud rather than off any coordinator, Headscale self-hosts the control plane. It keeps the Tailscale clients, NAT traversal and MagicDNS. It needs a public HTTPS host. The trade is one more server to run against everything in the table above.

Hermes: docs and plugins

Our Hermes Desktop clients already connect to the dashboard by LAN address, behind password sign-in. Over a WireGuard tunnel that routes the home LAN, the URL works unchanged. The Desktop docs describe a remote gateway as something to reach over "Tailscale or another trusted VPN". They say to keep a password-protected backend off the open internet and never forward its port from the router. A WireGuard tunnel meets that bar. Hermes' SSRF guard already treats RFC 1918 and 100.64.0.0/10 as private, so a 10.x tunnel subnet gets the same protection as the tailnet did.

Catalog pluginWhat it doesFit here
wireguardRead-only wg show status and peer listWindows only. Not usable on our Macs or UniFi gateway, but it's a good pattern to copy.
netplaneInstalls and runs a Headscale control plane, with join keys and a node listOnly for the Headscale middle path. Needs a fresh Debian/Ubuntu host.
hermes-tailscaleDesktop roster of tailnet machinesRetires with Tailscale.
hermes-vpnPicks a VPN exit country for the agent's browserDifferent problem. Not needed.

No catalog plugin manages a UniFi WireGuard server. We plan to build two small, read-only pieces of our own. One is the DDNS-drift watchdog above. The other is a skill that reads handshake age per peer, so "is Bob's tunnel up?" gets a real answer. Adding or removing peers stays a human decision in the UniFi UI, the same line the wireguard plugin draws.

Rollout

Tailscale stays up through every phase. Rollback at any step means using the tailnet as we do today.

#StepGate before moving on
0Infra domain on Cloudflare, scoped token, gateway DDNS, LAN updater, watchdog cronName matches the public IP; watchdog fires on a forced mismatch
1WireGuard server on the live WAN, tunnel subnet outside 192.168.x and 100.64/10Handshake from a phone on cellular
2James's phone and laptop, on-demand away from home Wi-Fi, DNS = gatewayHermes Desktop sign-in and SSH to the lab over cellular
3Second site, site-to-siteTraffic both directions
4Bob's Mini, one-way firewall rule, re-resolve watchdogJames reaches Bob; Bob cannot reach our LAN; survives a forced hub IP change
5Remote family Macs, same pattern as BobSSH over the tunnel per node
6Two weeks with tailscale down, then log out and uninstallNo path left that only Tailscale provides

Still open