Secure remote access to the homelab with Tailscale

20 October 2025 ยท Luke Gillmore-White

Remote access to a homelab usually means one of two things: port forwarding (which expands your attack surface every time you add something new) or a traditional VPN server (which needs its own port open and its own maintenance). Tailscale sidesteps both by building a private mesh network between devices using WireGuard under the hood, coordinated through Tailscale’s own control plane โ€” no inbound ports required at all.

Why Tailscale over a traditional VPN

A conventional VPN server (OpenVPN, WireGuard self-hosted) still needs an open inbound port on your firewall for clients to connect to. Every open port is something that needs monitoring and something an attacker can probe โ€” the DMZ writeup covers exactly why minimising that surface matters. Tailscale instead has each device make an outbound connection to Tailscale’s coordination servers, and the actual encrypted tunnels between your devices form directly using NAT traversal techniques โ€” meaning nothing needs to be exposed inbound on your home network at all.

Installing the node

On the Proxmox host and other Linux machines:

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

The tailscale up command prints a login URL โ€” authenticating there links the device to your Tailscale account (or organisation, if using a team plan).

On Windows clients, the official installer handles everything through a GUI, with the same login flow.

Subnet routing

By default Tailscale only makes the device itself reachable โ€” to reach everything else on your home network (the DMZ, other VLANs, devices without Tailscale installed) you advertise a subnet route from a single node acting as a gateway:

tailscale up --advertise-routes=192.168.50.0/24,172.16.30.0/24

This needs approving in the Tailscale admin console under Machines โ†’ [device] โ†’ Edit route settings before it takes effect โ€” a deliberate manual step so a compromised or misconfigured node can’t silently start advertising routes it shouldn’t. This is genuinely worth double-checking after any change: an unapproved route just silently doesn’t work, with no error surfaced to the device advertising it, which can look like a Tailscale bug when it’s actually just an unapproved route sitting in the admin console waiting on a click.

On the advertising node, IP forwarding also needs enabling at the OS level:

echo 'net.ipv4.ip_forward = 1' | sudo tee -a /etc/sysctl.conf
echo 'net.ipv6.conf.all.forwarding = 1' | sudo tee -a /etc/sysctl.conf
sudo sysctl -p

Missing this step is the other common failure mode โ€” the route shows as approved in the admin console, but traffic never actually flows, because the Linux kernel on the advertising node itself isn’t configured to forward packets between interfaces at all.

Access Control Lists

Tailscale’s ACLs (configured as JSON in the admin console) control exactly which devices and users can reach which parts of the network โ€” meaning even though everything sits on one flat Tailscale mesh, granular restriction is still possible:

{
  "acls": [
    {
      "action": "accept",
      "src": ["luke@example.com"],
      "dst": ["172.16.30.0/24:*", "192.168.50.0/24:*"]
    },
    {
      "action": "accept",
      "src": ["tag:server"],
      "dst": ["tag:server:*"]
    }
  ]
}

This means my phone and laptop (tagged to my identity) can reach the full home network remotely, while any future guest or shared devices can be scoped down to only what they specifically need. The default ACL policy (before any custom rules) is actually “allow all” between every device on the tailnet โ€” worth knowing, since a tailnet with no ACLs configured at all is more permissive than it might appear, especially once more than one person’s devices are on it.

MagicDNS

Rather than remembering Tailscale’s own IP ranges for each device, MagicDNS (enabled in the admin console under DNS) gives every device a friendly hostname automatically:

ssh proxmox
ssh layer8

resolves correctly from any device on the tailnet, without any manual DNS configuration required. One thing worth knowing: MagicDNS names only resolve while connected to the tailnet โ€” a device running a split-tunnel configuration where only specific traffic routes through Tailscale might not resolve these hostnames for traffic outside that tunnel, which is a common point of confusion the first time someone tries to ping proxmox from a script or tool that doesn’t respect the system’s Tailscale-provided DNS settings.

Result

From any device with Tailscale installed โ€” phone, laptop, anywhere with an internet connection โ€” the entire home network is reachable exactly as if sitting on the home LAN, fully encrypted end-to-end, with zero open inbound ports and granular per-device access control. Compared to the DMZ port-forwarding required for the public blog, this is the deliberate opposite approach: everything private stays private, reachable only through an authenticated, encrypted mesh rather than any public-facing surface at all.