Build a Zero‑Trust Mesh VPN with Tailscale: Exit Nodes, Subnet Routers, and ACLs

Overview

If you manage a home lab, remote workers, or small office networks, a traditional hub‑and‑spoke VPN can feel clunky and fragile. Tailscale solves this by creating a zero‑trust mesh VPN on top of WireGuard, giving every device a stable, private IP while punching through NAT without port forwarding. In this step‑by‑step guide, you will install Tailscale, configure an exit node, expose LANs via a subnet router, and apply fine‑grained access control with ACLs. You will also learn how to publish a local service securely with Tailscale Serve and Funnel.

Prerequisites

You will need: (1) a Tailscale account (GitHub, Google, Microsoft, or SSO), (2) administrator privileges on the devices you will connect, and (3) at least one Linux machine (Ubuntu/Debian or RHEL/CentOS/Alma/Rocky). Optional: a Windows or macOS device for testing.

Step 1 — Install Tailscale

On Ubuntu/Debian, the one‑liner below adds the repository and installs Tailscale safely. Run it on each machine you want to join to the mesh:

curl -fsSL https://tailscale.com/install.sh | sh
sudo tailscale up

On RHEL/CentOS/Alma/Rocky:

curl -fsSL https://tailscale.com/install.sh | sh
sudo systemctl enable --now tailscaled
sudo tailscale up

On Windows, download the installer from tailscale.com/download and sign in. On macOS, install via the App Store or Homebrew (brew install --cask tailscale), then sign in.

Step 2 — Verify connectivity and name your devices

After running sudo tailscale up and logging in, each device receives a 100.x.y.z Tailscale IP and a MagicDNS name (e.g., host.example.ts.net). Verify from any node:

tailscale status
tailscale ping <other-hostname>
tailscale ip -4

Give devices clear names in the Tailscale admin console to keep your network understandable (e.g., "lab-gw", "media-nuc", "dev-laptop").

Step 3 — Enable an exit node (optional, for secure internet via one device)

An exit node lets clients send all internet traffic through a trusted node (e.g., your home server) when on public Wi‑Fi.

# On the exit node:
sudo tailscale up --advertise-exit-node

Approve the exit node in the admin console (Machines → select the node → check “Exit node”). To use it from a client:

# On the client:
sudo tailscale up --exit-node=<exit-node-name-or-ip> --accept-dns=true

Step 4 — Advertise a LAN via a subnet router

If you want devices on Tailscale to reach non‑Tailscale hosts on your LAN (like printers, NAS, or hypervisors), set up a subnet router. Choose a Linux box on that LAN:

# Enable IP forwarding
sudo sysctl -w net.ipv4.ip_forward=1
sudo sysctl -w net.ipv6.conf.all.forwarding=1
# Make it persistent
echo 'net.ipv4.ip_forward=1' | sudo tee /etc/sysctl.d/99-tailscale.conf
echo 'net.ipv6.conf.all.forwarding=1' | sudo tee -a /etc/sysctl.d/99-tailscale.conf
sudo sysctl --system

# Advertise your LAN subnet(s), e.g., 192.168.1.0/24
sudo tailscale up --advertise-routes=192.168.1.0/24

Approve the routes in the admin console. Now any Tailscale node can reach 192.168.1.x hosts through the router. If your router has a firewall, allow forwarding from the Tailscale interface (usually tailscale0) to the LAN.

Step 5 — Apply zero‑trust ACLs and tags

Tailscale’s policy file lets you define who can reach what. In the admin console (Access controls), start with an explicit allowlist. This example grants SSH and HTTPS from admins to servers and Plex access to everyone, while scoping write access with

Comments