Setup recipe: Tailscale

A ready-made first-boot script that installs Tailscale from its own repository and can join the server to your tailnet with a one-off auth key.

This is a setup script that installs Tailscale on a new server's first boot, using Tailscale's own install script and package repository, and starts it at boot. It works on Ubuntu, Debian, AlmaLinux, Rocky Linux and Fedora.

With Tailscale on the server, you can reach it, and services you keep off the public internet, from your other devices over your private tailnet.

The auth key

Leave TS_AUTHKEY empty and the server installs Tailscale but doesn't join anything. Log in afterwards, run sudo tailscale up, and open the link it prints.

To have it join by itself, make an auth key in Tailscale's admin console under Settings > Keys and put it in TS_AUTHKEY before ordering. The script is copied onto the server's disk to run (see keep secrets out of it), so use a key that is not reusable, ideally ephemeral or with a short expiry. Once the server has joined, the key has done its job.

Deploy it

Deploy with VPSNine: this opens the order form with the script in the setup script field (you log in first). Add your key to TS_AUTHKEY there if you want one, then order.

With the CLI:

bash
vps9 servers create --plan budget --image debian-13 --hostname vpn-1 --key key_… --setup-script ./tailscale.sh

The script

bash
#!/bin/bash
# VPSNine setup recipe: Tailscale
# https://vpsnine.com/help/tailscale-setup-script
# Tailscale from its own repository, started at boot, and joined to your tailnet if you give it
# an auth key.
set -euo pipefail
umask 022

# ---- settings: change these before you run it ----
# An auth key from https://login.tailscale.com/admin/settings/keys joins the server by itself. Leave it
# empty to join by hand afterwards (run: tailscale up). The script is stored on the server, so use a
# one-off or ephemeral key, never a reusable one.
TS_AUTHKEY=""

# Which family of distributions this is: Debian and Ubuntu, or AlmaLinux, Rocky Linux and Fedora.
. /etc/os-release
case " ${ID:-} ${ID_LIKE:-} " in
  *" debian "*|*" ubuntu "*) family=debian ;;
  *" rhel "*|*" fedora "*|*" centos "*) family=rhel ;;
  *) echo "This recipe supports Ubuntu, Debian, AlmaLinux, Rocky Linux and Fedora, not ${PRETTY_NAME:-this system}" >&2; exit 1 ;;
esac

echo "== Installing Tailscale"
if [ "$family" = debian ]; then
export DEBIAN_FRONTEND=noninteractive
apt-get -o DPkg::Lock::Timeout=300 update
apt-get -o DPkg::Lock::Timeout=300 install -y ca-certificates curl
command -v tailscale >/dev/null 2>&1 || curl -fsSL https://tailscale.com/install.sh | sh
systemctl enable --now tailscaled
else
command -v tailscale >/dev/null 2>&1 || curl -fsSL https://tailscale.com/install.sh | sh
systemctl enable --now tailscaled
fi

if [ -n "$TS_AUTHKEY" ]; then
  echo "== Joining the tailnet"
  tailscale up --auth-key="$TS_AUTHKEY"
  tailscale ip -4 || true
else
  echo "== Installed. To join your tailnet, log in and run: tailscale up"
fi
echo "== Done"

Check the result

bash
tail -n 20 /var/log/vps9-setup.log
tailscale status
tailscale ip -4

The address tailscale ip -4 prints starts with 100. and only your tailnet can reach it. To keep SSH off the public internet once Tailscale works, allow port 22 only from the tailnet in the server firewall, and keep the serial console in mind as the way back in if you lock yourself out.

Be first when orders open

Join the waitlist and we'll send you one email when VPSNine launches. Pick a plan if you already know which one you want, and we'll size the first servers around it.

  • One email, on launch day
  • Monthly or yearly, no lock-in
  • 14-day money-back guarantee