Tailscale Subnet Router vs Exit Node
Subnet routers let you reach a home device that can't run Tailscale; exit nodes route all your traffic through home instead. Here's the decision table, the exact commands for both, and the Linux-only gotcha that leaves an approved route unreachable.

The Tailscale admin console shows two unchecked boxes next to a device: "Subnet routes" and "Use as exit node." One of them gets a laptop on hotel wifi into the home NAS. The other hides that laptop's entire internet connection behind home.
TL;DR — subnet router vs exit node
- A subnet router makes a LAN behind one device reachable to the rest of the tailnet — it does not touch the requesting device's own internet traffic.
- An exit node routes ALL of a client's internet-bound traffic, and its DNS, through the chosen device — the same job a traditional VPN does.
- They use separate flags —
--advertise-routesand--advertise-exit-node— and each needs its own approval in the admin console. Approving one does not approve the other. - A single device can run both roles at once; they don't conflict with each other.
- Need to reach one printer, NAS, or camera that can't run Tailscale? Subnet router. Need to stop hotel wifi from seeing your traffic? Exit node. Need both? Run both.
The 10-Second Decision Table
Skip the theory if this answers it:
| Your situation | What to enable |
|---|---|
| A printer, NAS, or camera on your home LAN that can't run the Tailscale client | Subnet router only |
| You're on untrusted wifi and want ALL your traffic (not just home-LAN traffic) to leave through home | Exit node only |
| Both — reach home devices AND hide your traffic when you're out | Both, on the same device |
| You only want to reach other devices that already run Tailscale | Neither — the mesh already does that natively |
That last row is worth sitting with: as covered in our explainer on what Tailscale actually is, every device running the Tailscale client can already reach every other device on the tailnet directly, with no extra configuration. Subnet routers and exit nodes only exist to extend that reach to devices and traffic that aren't already inside the mesh.
What Each One Actually Does
| Subnet router | Exit node | |
|---|---|---|
| What it extends | Reach to a LAN behind one device | Routing for a client's own traffic |
| Scope | A specific CIDR range you choose | Literally everything the client sends |
| DNS | Untouched by default; can be pointed at an internal resolver via split DNS | Runs a DNS server for connected peers by default, per Tailscale's exit-node docs |
| Flag | --advertise-routes=<CIDR> |
--advertise-exit-node |
| Needs IP forwarding | Yes — Tailscale's subnet router documentation says Linux needs it set manually; macOS enables it automatically when routes are advertised | Yes, same requirement on Linux |
| Devices behind it need Tailscale installed | No — that's the point | N/A — it carries the client's own traffic, not a third device's |
Note
a single device — a Proxmox VM, a Raspberry Pi, whatever is already on 24/7 in a typical homelab Tailscale install — can advertise a subnet route, an exit node, or both.
Setting Up a Subnet Router
On the device that sits on the LAN you want to reach:
sudo sysctl -w net.ipv4.ip_forward=1
sudo sysctl -w net.ipv6.conf.all.forwarding=1
sudo tailscale set --advertise-routes=192.168.1.0/24
IP forwarding has to be enabled first on Linux (macOS does this automatically when you advertise routes), then the subnet is advertised per Tailscale's own subnet router docs. Then approve it once in the admin console: Machines → the device → Edit route settings → enable the advertised subnet. Tailscale's subnet router documentation is explicit that advertising the route from the command line is only half the job — nothing is reachable until that admin-console approval step happens too.
Warning
the approval step is per-subnet, not per-device. If you later advertise a second subnet from the same box, it needs its own separate approval — re-running the tailscale set command doesn't retroactively approve anything.
Setting Up an Exit Node
The flag is --advertise-exit-node instead of --advertise-routes, and it goes through the same two-step dance — advertise, then approve in the admin console:
sudo tailscale set --advertise-exit-node
sudo tailscale set --exit-node=<device-name-or-ip> --exit-node-allow-lan-access
The first command runs on the home device that will carry the traffic, then gets approved in the admin console (Machines → device → Edit route settings → Use as exit node). The second runs on the client that wants to route through it. Our deep-dive on exit nodes covers DNS leak checks and the speed ceiling in detail. The --exit-node-allow-lan-access flag on the client keeps that client's own local network (its printer, its own NAS) reachable while everything else routes home.
To confirm it's actually active, run tailscale status on the client — it marks the exit node you're using — and check that your public-facing IP now matches home rather than the network you're sitting on.
Running Both From the Same Box
Nothing stops one device from doing both jobs — the flags are independent:
sudo tailscale set --advertise-routes=192.168.1.0/24 --advertise-exit-node
That one command advertises a home LAN range AND offers the device as an exit node, with nothing else changing about either feature — which is also why Tailscale's own documentation on routing all traffic except local subnets treats the two as independent settings rather than one combined mode.
Tip
if a connecting client only needs the exit node right now, leave the subnet route unapproved for that client's traffic — there's no requirement to switch both on together just because the same device offers both.
This is also the setup that matches how Tailscale compares to raw WireGuard: under the hood both roles still ride the same WireGuard tunnel, and Tailscale's only job on top is the coordination, NAT traversal, and these two independent advertise/approve flags — instead of hand-writing two separate peer configs yourself.
"I Approved It, So Why Can't I Reach It?"
This is the step that catches people who did everything above correctly. Advertising a route and approving it in the admin console is only half the job on the client side. Tailscale's subnet router documentation states that Android, iOS, macOS, tvOS, and Windows clients automatically pick up newly approved subnet routes — but Linux clients do not. On Linux, a client only discovers Tailscale IP addresses by default and needs an explicit opt-in:
sudo tailscale set --accept-routes
Skip that on a Linux laptop and the subnet route can be fully advertised and fully approved in the admin console, and still be unreachable from that one machine — with nothing in the UI pointing at the actual cause.
Warning
this asymmetry only affects Linux clients. If your phone or Mac can reach the subnet but your Linux desktop can't, --accept-routes is almost always the missing piece.
Exit nodes don't have this particular trap — once a client runs --exit-node=<device>, it applies regardless of the client's OS. The asymmetry only shows up on the subnet-router side.
FAQ
Can I use a Tailscale subnet router and exit node at the same time?
Yes. A single device can advertise both --advertise-routes and --advertise-exit-node in the same command, or separately. The admin console still requires two independent approval steps — one for the subnet route, one for the exit node.
Does a Tailscale subnet router need IP forwarding enabled?
Yes. Tailscale's subnet router documentation requires IP forwarding on the advertising device; Linux needs it set manually via sysctl, while macOS enables it automatically when you advertise routes.
Does a subnet router affect DNS?
Not by default. A subnet router only changes which devices are reachable. DNS queries keep going through your existing resolver unless you separately configure split DNS in the admin console to point lookups at an internal resolver on the advertised subnet.
Do I need to approve subnet routes and exit nodes separately in the admin console?
Yes. Each is its own toggle under Machines → the device → route settings, even when both are advertised from the same device in one command. Approving one does not approve the other.
More from Self-Hosting & Privacy

Tailscale Serve keeps a service on your tailnet; Funnel puts it on the public internet. Real commands, TLS setup, and the gotchas that cause 404s.

Stoat, Spacebar, and Matrix/Element compared for self-hosting a Discord replacement: RAM needs, voice/video maturity, Discord bot compatibility, and the real migration friction for an existing community.

You edit .env, restart the container, and the old value is still there - no error anywhere. The exact precedence order between env_file, environment, and your shell, reproduced on a real stack, plus the fix when Compose won't pick up the change.
Stay in the loop
Get the latest articles delivered to your inbox. No spam, unsubscribe anytime.
Tailscale Serve vs Funnel Explained
Tailscale Serve keeps a service on your tailnet; Funnel puts it on the public internet. Real commands, TLS setup, and the gotchas that cause 404s.
Continue Reading