Guides

Tailscale exit node on a VPS: routing your traffic through a server you control

Set up a VPS as a Tailscale exit node: install, enable IP forwarding, advertise and approve it, then route a device's traffic through it. Plus exit node vs subnet router and vs plain WireGuard.

Published ~6 min read

Short answer: install Tailscale on a VPS, run sudo tailscale up --advertise-exit-node, turn the node on as an exit node in the Tailscale admin console, enable IP forwarding, then on any device in your tailnet run tailscale up --exit-node=VPS-NAME. Every packet from that device now leaves through the VPS’s public IP, routed over WireGuard, with no port to open on the VPS and no separate VPN server software to configure.

Why an exit node needs a VPS, not a home connection

Tailscale can turn any device in your tailnet into an exit node, including a laptop at home, but a home connection has a dynamic or CGNAT’d IP, goes offline when the laptop sleeps, and exits other traffic through your own residential address — rarely the point of running an exit node. A VPS has a static public IP that stays up, and sits on a different network and provider than wherever you are connecting from, which is the actual use case: route a phone on a hotel Wi-Fi, or a self-hosted service that only sees a server’s own uplink, through an address that belongs to neither.

  1. 1Install Tailscale on the VPS
    Debian · Ubuntu
    curl -fsSL https://tailscale.com/install.sh | sh

    The official script adds Tailscale’s own apt repository and installs the package rather than shipping a one-off binary, so later apt upgrade runs keep it current. Read it before piping it into a shell if that matters to you; the repository add and package install are the only things it does.

  2. 2Enable IP forwarding
    /etc/sysctl.d/99-tailscale.conf
    net.ipv4.ip_forward = 1
    net.ipv6.conf.all.forwarding = 1
    apply it now
    sudo sysctl -p /etc/sysctl.d/99-tailscale.conf

    Without this, the VPS accepts the role but drops every packet it is supposed to forward on behalf of other devices — it only routes its own traffic. This is the step people skip and then find the exit node connects but nothing loads.

  3. 3Bring Tailscale up and advertise as an exit node
    Linux
    sudo tailscale up --advertise-exit-node

    The first run opens a URL to authenticate the device against your Tailscale account (or your identity provider, if your tailnet uses one). Give the machine a sensible name first with --hostname=vps-exit if you want to recognise it easily on the client side later.

  4. 4Approve it as an exit node

    Open the admin console (login.tailscale.com), find the machine, open its menu and tick Use as exit node. A personal tailnet on the free plan approves this automatically from the CLI flag in step 3; an organisation’s tailnet usually requires an admin to approve it here before other devices can select it, and the console is also where you turn it back off later.

  5. 5Use it from another device
    Linux · macOS
    tailscale up --exit-node=vps-exit
    tailscale up --exit-node=vps-exit --exit-node-allow-lan-access

    On Windows, iOS and Android, the exit node is a picker in the app’s own menu rather than a command. --exit-node-allow-lan-access keeps your local network (a printer, a NAS) reachable while everything else routes through the VPS; without it, the whole default route goes over the tailnet.

Confirming it actually works

on the client, after connecting
tailscale status
curl ifconfig.me

tailscale status shows which exit node is active; curl ifconfig.me should now print the VPS’s public IP, not your own connection’s. If it still shows your real IP, check step 2 first — a missing sysctl setting is the most common reason an exit node accepts the connection but routes nothing.

Exit node vs subnet router: not the same setting

These two Tailscale features are easy to confuse because both need --advertise-* and IP forwarding:

Exit nodeSubnet router
Flag--advertise-exit-node--advertise-routes=10.0.0.0/24
RoutesAll of the client's internet trafficOnly the named subnet(s)
Typical useHide your exit IP, reach geo-restricted servicesReach a home LAN or office network from the tailnet
Client opts in with--exit-node=NAMEAutomatic once the route is approved

A VPS can advertise both at once, and a client can use one, the other, or neither.

Tailscale vs plain WireGuard on a VPS

TailscalePlain WireGuard
SetupOne install script, one command, authenticate onceGenerate keys, write a config per peer, open a UDP port
NAT traversalAutomatic (DERP relay as fallback)Needs a reachable public port, or it simply fails to connect
Adding a new deviceInstall and authenticate, nothing to edit on the VPSEdit the server config, add a peer, reload
Key rotationAutomatic, in the backgroundManual, unless you build your own tooling
Access controlACLs in the admin console, by device and tagWhatever the config file allows — all or nothing per peer
Control planeTailscale's cloud (or self-hosted Headscale)None — fully self-contained
Underlying protocolWireGuardWireGuard

Tailscale is WireGuard underneath with a coordination layer on top, which is exactly the convenience it trades for a dependency on a control plane you do not run yourself — unless you point the client at a self-hosted one. Running the VPN end entirely by hand instead, with full control and nothing to trust but your own server, is in setting up a WireGuard VPN server.

Running your own control plane instead of Tailscale’s

Headscale is an open-source, self-hosted reimplementation of Tailscale’s coordination server. Official Tailscale clients point at it instead of login.tailscale.com, which keeps the exit-node mechanics exactly as above while removing Tailscale’s own servers from the picture entirely — useful once a tailnet grows past the free plan’s device limit, or when policy means nothing should phone home to a third party. It still needs a server to run on, which is itself a natural fit for the same VPS that is already the exit node.

What exit-node traffic costs you

  • Bandwidth is doubled on the VPS: every byte in and out of the client passes through the VPS’s own network allowance, in both directions, not just the client’s own usage.
  • Latency goes up by roughly the round trip between the client and the VPS, on top of the VPS’s own path to whatever it is reaching — pick a location close to where you actually are, not close to the service you are trying to reach, unless the goal is specifically to appear to come from there.
  • Direct connections (no DERP relay) need UDP reachability; Tailscale falls back to a relay automatically when NAT blocks a direct path, which works but adds another hop’s worth of latency.

Firewall notes

Tailscale needs outbound UDP on port 41641 (and a fallback to DERP over 443 when that is blocked) and manages its own firewall rules through iptables or nftables automatically on Linux — you do not add a rule for the tailnet interface yourself. A separately managed firewall such as UFW still governs everything else on the box; it does not need a rule for Tailscale specifically, but double check it is not blocking outbound UDP if the connection never comes up at all.

Turning exit-node status off

on the client
tailscale set --exit-node=
on the VPS, to stop advertising entirely
sudo tailscale up --advertise-exit-node=false

Removing the machine from the admin console’s exit-node list also works, and is the only option when the device that advertised it is unreachable.

Frequently asked

How do I turn a VPS into a Tailscale exit node?

Install Tailscale, enable IP forwarding (net.ipv4.ip_forward=1 and net.ipv6.conf.all.forwarding=1 in a sysctl file), run sudo tailscale up --advertise-exit-node, then approve it as an exit node in the Tailscale admin console. A device elsewhere in the tailnet then selects it with tailscale up --exit-node=NAME.

I set up the exit node but my traffic still shows my real IP — why?

Almost always a missing IP-forwarding setting: the VPS accepts the exit-node role but drops every packet it is meant to forward for other devices. Confirm net.ipv4.ip_forward is set to 1 with sysctl net.ipv4.ip_forward, and check with curl ifconfig.me on the client after reconnecting.

What is the difference between a Tailscale exit node and a subnet router?

An exit node routes all of a client's internet traffic through it. A subnet router (--advertise-routes) only exposes a specific network range, such as a home LAN, to the rest of the tailnet — the rest of the client's traffic keeps using its own connection. A single machine can advertise both at once.

Should I use Tailscale or plain WireGuard for a VPS exit node?

Tailscale is WireGuard underneath, with automatic key rotation, NAT traversal and a one-command setup on top, at the cost of trusting Tailscale's coordination service (or running your own with Headscale). Plain WireGuard has no such dependency but needs manual key and peer management for every device.

Related articles

All guides