Security

Set Up Tailscale: Connect All Your Devices Into One Private Network

Beginner30 min to complete9 min readJuly 7, 2026

Quick answer

Tailscale makes every device you own act like it's plugged into the same home network — laptop, phone, cloud server, Raspberry Pi — no port forwarding, no firewall wrestling, no VPN server to babysit. Install it on two devices, get private IPs and magic hostnames, then lock SSH to your private network and route your phone's traffic through your own server.

beginner · 30 min

Before you begin

  • A Linux server (Ubuntu/Debian, any cloud provider or homelab box) with sudo access
  • A laptop or phone to connect as a second device
  • A Google, Microsoft, GitHub, or Apple account to sign in with
  • Optional but recommended: UFW set up — see the firewall tutorial
Tailscale
VPN
WireGuard
Networking
Security
Linux
Homelab

Here's the problem Tailscale solves, in plain terms: your devices can't talk to each other. Your laptop at a coffee shop can't reach your home server. Your phone can't hit the dashboard running on your cloud VM unless you expose it to the whole internet. The traditional fixes — port forwarding, public IPs, a self-managed VPN — all mean opening doors that attackers can knock on.

Tailscale flips that around. You install a small agent on each device, sign in, and every device gets a private IP address (in the 100.x.y.z range) that works from anywhere — coffee shop, airplane Wi-Fi, mobile data. It's as if all your machines were plugged into the same invisible switch. Under the hood it builds encrypted WireGuard tunnels directly between devices, and the traffic never passes through Tailscale's servers unencrypted. If you're weighing this against running your own VPN, I've written a full comparison in Tailscale vs. WireGuard — the short version is: Tailscale trades a little control for a lot of convenience, and for most people that's the right trade. (If you want the full-control version, the companion tutorial self-hosts a raw WireGuard server.)

The private network Tailscale creates for you is called a tailnet. Let's build one.

What You'll Build

  • A tailnet with your server, laptop, and phone all holding stable private IPs
  • MagicDNS hostnames, so ssh my-server works from anywhere without remembering IPs
  • SSH locked to the tailnet — port 22 closed to the public internet entirely
  • Your server acting as an exit node, so your phone can route all its traffic through it on sketchy public Wi-Fi
  • Sensible defaults for key expiry so you don't get silently disconnected in six months

Step 1: Create Your Tailnet

Go to login.tailscale.com/start and sign in with an existing identity provider — Google, Microsoft, GitHub, or Apple. There's no separate Tailscale password; it deliberately piggybacks on an account you already protect (put two-factor auth on that account if you haven't — it's now the key to your network).

Signing in creates your tailnet. The free Personal plan covers up to 6 users with no limit on personal devices — more than enough for a homelab, your family, and every gadget you own.

Step 2: Install Tailscale on Your Server

SSH into your Linux server and run the official install script (it detects your distro and adds the right apt repository — the manual per-distro instructions exist if you'd rather not pipe curl to sh):

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

Then bring it up:

bash
sudo tailscale up

It prints a login URL. Open it in your browser, authorize the machine, and you're connected. Verify:

bash
tailscale ip -4      # your server's private tailnet IP, e.g. 100.101.102.103
tailscale status     # every device in your tailnet and how it's connected

That 100.x.y.z address is yours now — it follows the server around and is reachable only by devices in your tailnet.

Step 3: Install It on Your Laptop and Phone

  • macOS / Windows: download from tailscale.com/download, install, sign in with the same account.
  • iOS / Android: install the Tailscale app from the app store, sign in, flip the VPN toggle on.
  • Another Linux box: same two commands as Step 2.

Open the admin console and you'll see all your machines listed with their IPs. From your laptop, ping the server's tailnet IP:

bash
ping 100.101.102.103

That ping works from your home network, a café, or LTE — same IP everywhere. This is the "one invisible switch" effect, and it's the core of what you just built.

Step 4: Use Names Instead of IPs with MagicDNS

Remembering 100.x addresses gets old fast. MagicDNS gives every device a hostname based on its machine name — it's enabled by default on new tailnets, but confirm under DNS settings in the admin console.

With it on, this just works from any of your devices:

bash
ssh deploy@my-server

...where my-server is the machine name shown in the admin console (rename machines there to whatever makes sense to you). Full names like my-server.tail1234.ts.net also work; the short name is enough inside your tailnet.

Step 5: Lock SSH to Your Tailnet

Here's the first big security payoff. Right now your server probably accepts SSH from the entire internet, and bots are hammering it around the clock. Since you can now SSH over Tailscale, the public door can close completely.

If you followed the UFW firewall tutorial, allow everything arriving over the Tailscale interface, then remove the public SSH rule:

bash
sudo ufw allow in on tailscale0
sudo ufw status numbered        # find the number of the public '22/tcp ALLOW' rule
sudo ufw delete <number>

Do this in the right order and test before you burn the bridge: with the tailscale0 rule added but the public rule still in place, open a new terminal and confirm ssh deploy@my-server works over the tailnet. Only then delete the public rule. (This is the same golden rule as the SSH hardening tutorial: never remove a working login path until the replacement is proven.)

Your server is now invisible to every port scanner on the internet, but one ssh my-server away for you.

Step 6: Turn Your Server Into an Exit Node

By default, Tailscale only carries traffic between your devices — your normal browsing goes out the local network as usual. An exit node upgrades that: your phone or laptop routes all its internet traffic through your server, encrypted the whole way. On hotel or airport Wi-Fi, the network sees only gibberish to one address; websites see your server's IP.

On the server, enable IP forwarding (the kernel switch that lets a machine pass traffic through rather than only send/receive its own) and advertise:

bash
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

sudo tailscale up --advertise-exit-node

Advertising is an offer, not a grant — approve it in the admin console: find the server, open its menu → Edit route settings → allow it to be an exit node.

Then, on the client side: in the phone app pick Exit node → my-server; on a Linux laptop run sudo tailscale set --exit-node=my-server (and --exit-node= with nothing to switch back off). Check it worked by visiting an IP-checker site — you should see your server's public IP, not the coffee shop's.

Step 7: Stop Key Expiry From Biting You Later

Every device's keys expire after 180 days by default, at which point it silently drops off the tailnet until you re-authenticate. For your phone and laptop that's a mild nuisance and a reasonable security default. For a headless server it means "SSH mysteriously dead six months from now."

In the admin console, open the server's machine menu and choose Disable key expiry. Do this for servers only — let interactive devices keep the expiry as a safety net for lost or stolen hardware.

Common Issues

  • tailscale up says the daemon isn't running. The install script normally starts it, but if not: sudo systemctl enable --now tailscaled, then retry.
  • Devices connect but throughput is poor. Run tailscale status — if a peer shows relay instead of direct, both sides are behind restrictive NATs and traffic is bouncing through Tailscale's DERP relay servers (still encrypted, just slower). Direct connections usually establish after a little traffic; if not, letting one side send UDP from source port 41641 out to anywhere (or port-forwarding UDP 41641 to it) typically fixes it.
  • Exit node is selectable but no traffic flows. Almost always IP forwarding: rerun the sysctl lines from Step 6 and confirm with sysctl net.ipv4.ip_forward (must print 1). Second suspect: you advertised but never approved it in the admin console.
  • MagicDNS names don't resolve on Linux. Tailscale needs to manage /etc/resolv.conf. Run sudo tailscale up --accept-dns=true, and check for a conflicting DNS manager (resolvconf, custom systemd-resolved setups) if it still fails.
  • Locked out after removing the public SSH rule. Use your provider's serial/VNC console to get in, sudo ufw allow 22/tcp to reopen the public door, and debug the Tailscale connection before closing it again. Prevention is the test in Step 5.

Frequently Asked Questions

Is Tailscale actually free?

The Personal plan is free — up to 6 users, with unlimited personal devices as of the April 2026 pricing update — and it's a real free tier, not a trial: it covers everything in this tutorial including exit nodes, MagicDNS, and ACLs. Paid plans exist for teams that need more users, SSO integration, and audit logging.

Can Tailscale see my traffic?

No. Traffic flows over WireGuard tunnels encrypted end-to-end between your devices; Tailscale's coordination server only handles the bookkeeping — exchanging public keys and telling devices where to find each other. Even when a connection falls back to a DERP relay, the relay forwards ciphertext it cannot read. What Tailscale does see is metadata: which devices exist and when they connect.

How is this different from self-hosting WireGuard?

Tailscale is WireGuard underneath — it automates the painful parts: key distribution, NAT traversal, IP assignment, and roaming. Self-hosting WireGuard gives you zero third-party dependency and full control, but you become the coordination server: every new device means hand-editing configs. I've written a full comparison, and if you want the DIY route, follow the self-hosted WireGuard tutorial.

What is Headscale?

An open-source, self-hosted reimplementation of Tailscale's coordination server. The official Tailscale apps can point at your Headscale instance instead of Tailscale's cloud — you keep the great client software but own the control plane. It's the middle path between this tutorial and raw WireGuard, at the cost of running and securing one more service yourself.

Will routing through an exit node slow my internet down?

Somewhat — your traffic makes a detour through the server, so your speed is capped by the server's bandwidth and the extra round trip. On a decently connected cloud VM the overhead is small (WireGuard itself runs in the kernel and is very fast). Remember the default is not to use an exit node: device-to-device traffic takes the direct path, usually at near line speed.

Tear Down

To disconnect a device temporarily:

bash
sudo tailscale down

To remove Tailscale from a Linux machine entirely:

bash
sudo tailscale logout
sudo apt remove --purge tailscale
sudo rm -rf /var/lib/tailscale

Then delete the machine from the admin console. If you closed public SSH in Step 5, re-open it before removing Tailscale from a remote server (sudo ufw allow 22/tcp) — otherwise you're tearing down your only way in.

Official References

Next steps: put the same discipline on the SSH daemon itself with Harden SSH Access, or take the full-control path and self-host a WireGuard VPN server.

We built Podscape to simplify Kubernetes workflows like this — logs, events, and cluster state in one interface, without switching tools.

Struggling with this in production?

We help teams fix these exact issues. Our engineers have deployed these patterns across production environments at scale.