A flat home network with Tailscale instead of port forwarding

Reach every device on your home LAN from anywhere, without port forwarding, dynamic DNS, or a public IP. One subnet router, one afternoon.

last verified 2026-05-04 · difficulty 3/5 · Free ·1 to 3 hours
  • A free Tailscale account. The Personal plan covers up to 6 users and unlimited personal devices, which is plenty for a household.
  • An always-on Linux box for the subnet router. A Raspberry Pi 3/4/5, an old laptop, a small VM, or a NAS that runs Tailscale all work. RAM use is tiny (under 100 MB).
  • Tailscale clients on the devices that will dial in: phone, laptop, tablet. Apps for iOS, Android, macOS, Windows, and Linux are linked from tailscale.com/download.
  • Your home subnet in CIDR notation (usually something like 192.168.1.0/24 or 10.0.0.0/24). Check your router's DHCP page if you don't know.

Tailscale is a mesh VPN built on WireGuard, with a hosted control plane that handles key exchange and NAT traversal so you don’t have to. You install a client on each device, sign in, and they can reach each other directly over an encrypted tunnel. Nothing you do touches your router’s port-forward table or your firewall’s WAN side. Port forwarding is a perfectly fine 2008 solution. This is the 2026 one.

The “flat home network” trick is the one most people skip on their first try: instead of installing Tailscale on every device you want to reach, you install it on a single always-on Linux box and tell it to advertise the rest of your LAN as a routed subnet. Now your phone on cellular can reach your printer, your NAS, your Home Assistant box, and the router admin page, by their normal LAN IPs, with no Tailscale on any of them. This is also the answer if your ISP put you behind CGNAT and you can’t port-forward at all.

Honest tradeoff: Tailscale’s coordination server is hosted by Tailscale Inc. The data plane is direct WireGuard between your devices, but the control plane is theirs. If you want to keep the whole thing on your own infrastructure, Headscale is an open-source reimplementation of the control server. It’s out of scope here. This guide uses the hosted Tailscale because it’s the path with the smoothest mobile clients and the lowest moving-parts count.

Two approaches

You have two options, and which one fits depends on how many things you actually need to reach.

Option 1: Tailscale on every device. Install the client on each machine you want remote access to, sign each into your tailnet. Simple, no routing config, no subnet approvals. Fine if the list is short (3 to 5 devices) and they all run an OS Tailscale supports.

Option 2: Subnet router for the whole LAN. Install Tailscale on one always-on Linux box and have it route traffic to the rest of your home network. Your TV, your printer, your IP cameras, your router’s admin page, and anything else with an IP becomes reachable, no client install needed on any of them. This is the option this guide walks through.

You can mix both. Many people run a subnet router for the bulk of the LAN, then put Tailscale directly on the one or two boxes (laptop, dev server) where they want a Tailscale-native hostname.

Step 1: Install Tailscale on the subnet router

SSH into your subnet router box. Anything that runs Linux works; the commands below assume Debian or Ubuntu. For other distros, the universal installer handles repo setup automatically:

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

For Debian/Ubuntu specifically, the apt repo route looks like this (check tailscale.com/download/linux for the exact URLs for your release codename):

curl -fsSL https://pkgs.tailscale.com/stable/ubuntu/noble.noarmor.gpg \
  | sudo tee /usr/share/keyrings/tailscale-archive-keyring.gpg >/dev/null

curl -fsSL https://pkgs.tailscale.com/stable/ubuntu/noble.tailscale-keyring.list \
  | sudo tee /etc/apt/sources.list.d/tailscale.list

sudo apt-get update && sudo apt-get install -y tailscale

Verify the daemon is running:

systemctl status tailscaled

End state: tailscaled is active, but the node is not yet logged into your tailnet.

Step 2: Enable IP forwarding

Tailscale needs the kernel to forward packets from the tailnet interface to your LAN. Without this, advertised routes won’t actually carry traffic.

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

Skip the IPv6 line if your home network is IPv4-only and you want to keep it that way. Adding it costs nothing if you’re unsure.

Verify:

sysctl net.ipv4.ip_forward
# expected: net.ipv4.ip_forward = 1

Step 3: Bring up Tailscale and advertise your LAN

Replace 192.168.1.0/24 with your actual home subnet:

sudo tailscale up --advertise-routes=192.168.1.0/24

The command prints an auth URL. Open it on any device, sign into your Tailscale account, and approve. The router box will appear in your admin console under Machines.

If you’d rather keep the box’s existing DNS configuration unchanged, add --accept-dns=false:

sudo tailscale up --advertise-routes=192.168.1.0/24 --accept-dns=false

End state: tailscale status lists the node and shows it as connected. The box has a Tailscale IP in the 100.x.y.z range.

Step 4: Approve the route in the admin console

Advertising a route is a request, not a fait accompli. You have to approve it.

  1. Open the Machines page.
  2. Find your subnet router. It will have an “Subnets” indicator showing pending routes.
  3. Click the device, find the Subnets section, click Edit, tick the route, save.

End state: the route shows as approved (green check or similar) on the device’s row.

Step 5: Disable key expiry on the subnet router

By default, Tailscale node keys expire after 180 days. When the subnet router’s key expires, every device that depends on it loses LAN access until you re-auth on the router. This is a perfectly preventable 3 AM emergency.

In the admin console, on the subnet router’s machine page, find the menu and pick Disable key expiry. Do this only for infrastructure devices (the subnet router, a home server). Leave it enabled for laptops and phones, where rotating credentials is healthy.

Step 6: Connect client devices

Install Tailscale on each device that needs access and sign into the same account.

Linux:

sudo tailscale up --accept-routes

The --accept-routes flag is required on Linux: clients only pick up Tailscale node IPs by default, not advertised subnet routes. Without it, the client connects fine but your LAN is still invisible.

iOS / Android: open the app, tap your tailnet, enable “Use Tailscale subnets” (exact label varies by version).

macOS / Windows: the apps accept subnet routes automatically. If you don’t see your LAN, look for an “Use Tailscale subnets” toggle in preferences.

End state: from a client (phone on cellular is the best test), tailscale ping <a-LAN-IP> succeeds, and you can reach LAN services by IP and port.

Step 7: Enable MagicDNS

Admin console, DNS tab, enable MagicDNS. From now on, any device on your tailnet is reachable by its short hostname (e.g. nas, pi-hole, subnet-router) instead of a 100.x.y.z IP. MagicDNS does what it says, which is unusual.

A clarification that catches people out: MagicDNS only resolves Tailscale node names. It does not resolve your home network’s .local mDNS names, and it does not resolve a custom internal domain you might serve from a local DNS server. Devices on the LAN that don’t run Tailscale won’t get a MagicDNS name; you reach those by their LAN IP, which is the whole point of the subnet router.

If you do run a local DNS server (Pi-hole, AdGuard Home, your router) and you want internal hostnames to resolve from outside, configure split DNS in the same admin console DNS page: add a nameserver entry pointing at your LAN DNS server’s IP, and restrict it to your internal domain. Tailscale clients will then forward queries for that domain over the subnet route.

Step 8: Sharing access with family or housemates

Two paths, depending on who they are.

Pre-auth keys suit headless devices and Linux boxes you set up on someone else’s behalf. In the admin console, Settings, Keys, generate an auth key (reusable, expiry to taste, not ephemeral). On the target device:

sudo tailscale up --authkey=tskey-auth-... --accept-routes

User invites suit phones and laptops where the person logs in themselves. Admin console, Users, invite their email. They make a free Tailscale account, install the app, sign in, and their devices show up in your Machines list. You can remove them anytime.

ACLs (controlling which users can reach which subnets and ports) live in the same admin console under Access controls. They’re worth setting up if you share with anyone outside your household, but the defaults are fine for a single-user or trusted-family tailnet. Out of scope here.

  • tailscale status from any client lists the subnet router with the advertised route.
  • From a client off your home WiFi (cellular phone is ideal), tailscale ping <a-LAN-IP> succeeds.
  • Initial replies say 'via DERP' (relayed); subsequent ones say 'direct' once the WireGuard tunnel establishes.
  • Loading http://<router-IP> in the phone's browser shows the router admin page as if you were sitting at home.
  • Route advertised but not approved

    The subnet router shows up in the admin console, the client connects, but LAN IPs don't resolve. You forgot Step 4. Approve the route in the admin console.

  • IP forwarding disabled

    Routes approved, client connected, packets go nowhere. Check sysctl net.ipv4.ip_forward on the router. If it's 0, redo Step 2 and confirm sudo sysctl -p /etc/sysctl.d/99-tailscale.conf actually applied.

  • Linux client didn't accept routes

    tailscale status on the client shows the route as available but unused. Re-run sudo tailscale up --accept-routes. The flag is per-invocation; if you ran tailscale up later without it, the previous flags don't persist.

  • Subnet router key expired

    Random morning, nothing on the LAN reachable, subnet router shows "Expired" in the admin console. SSH in, run sudo tailscale up --advertise-routes=... again, do the auth URL dance. Then go disable key expiry (Step 5) so it doesn't recur.

  • MagicDNS conflicts with a corporate VPN

    Some corporate VPN clients aggressively claim the system DNS. If you're on a work laptop and Tailscale stops resolving names while the work VPN is up, this is why. Either disable MagicDNS on that client, drop the work VPN when you're not working, or use IPs directly.

  • Two devices with the same MagicDNS name

    Tailscale appends -1, -2, etc. to disambiguate. If a name resolves somewhere unexpected, check the Machines page; you probably have an old device from a reinstall hanging around. Delete it.

Tailscale doesn't change your existing network setup. There's nothing to undo on the LAN. To stop using it:

sudo tailscale down

To uninstall:

sudo apt remove tailscale

Or, if you used the universal installer:

sudo /usr/sbin/tailscale-uninstall

(path varies by distro; check which tailscale and the install script's output). Remove the device from the admin console afterwards so it stops showing up in your Machines list.

The IP forwarding sysctl in /etc/sysctl.d/99-tailscale.conf is harmless to leave in place but trivial to remove if you prefer a tidy box.


Did this work for you?


Comments (0)

No comments yet. Be the first.

Add a comment