#!/bin/sh
# setup.sh — bootstrap a Linux box as a Tailscale App Connector.
#
# This is the script referenced from section 12 of
#   https://tailscale-connector.pages.dev/
# (Paths B and C: any cloud VPS, or a Linux machine you already have).
#
# Requires:
#   - outbound internet
#   - root (use sudo -E to preserve the env vars below)
#   - apt / dnf / yum / apk available for jq
#
# Required env vars (set them before running):
#   TS_OAUTH_CLIENT_ID  from login.tailscale.com/admin/settings/oauth
#   TS_OAUTH_SECRET     shown once when you create the OAuth client
#   TS_TAGS             tailscale tag, e.g. tag:connector-sin
#   TS_HOSTNAME         hostname for the connector, e.g. connector-sin
#
# What this script does:
#   1. Installs tailscale + jq.
#   2. Enables IPv4/IPv6 forwarding (persisted via sysctl.d).
#   3. Persists the OAuth credentials at /etc/tailscale-connector.env (0600).
#   4. Installs /usr/local/bin/tailscale-connector.sh, which mints a fresh
#      single-use ephemeral auth key on every boot and brings tailscale up
#      as an app connector.
#   5. Installs and enables a systemd unit that runs the boot dance.
#
# Idempotent: re-running overwrites the files in place. Re-run after you
# rotate the OAuth secret (also update /etc/tailscale-connector.env).

set -eu

: "${TS_OAUTH_CLIENT_ID:?set TS_OAUTH_CLIENT_ID before running this script}"
: "${TS_OAUTH_SECRET:?set TS_OAUTH_SECRET before running this script}"
: "${TS_TAGS:?set TS_TAGS (e.g. tag:connector-sin) before running this script}"
: "${TS_HOSTNAME:?set TS_HOSTNAME (your chosen connector name) before running this script}"

if [ "$(id -u)" -ne 0 ]; then
  echo "this script needs root; re-run with: sudo -E sh setup.sh" >&2
  exit 1
fi

# 1. Install tailscale and jq if missing.
if ! command -v tailscale >/dev/null 2>&1; then
  curl -fsSL https://tailscale.com/install.sh | sh
fi
if ! command -v jq >/dev/null 2>&1; then
  if command -v apt-get >/dev/null 2>&1; then
    DEBIAN_FRONTEND=noninteractive apt-get update -y
    DEBIAN_FRONTEND=noninteractive apt-get install -y jq
  elif command -v dnf >/dev/null 2>&1; then
    dnf install -y jq
  elif command -v yum >/dev/null 2>&1; then
    yum install -y jq
  elif command -v apk >/dev/null 2>&1; then
    apk add --no-cache jq
  else
    echo "no supported package manager found; install jq manually then re-run" >&2
    exit 1
  fi
fi

# 2. Enable IPv4/IPv6 forwarding, persisted.
cat > /etc/sysctl.d/99-tailscale.conf <<EOF
net.ipv4.ip_forward = 1
net.ipv6.conf.all.forwarding = 1
EOF
sysctl -p /etc/sysctl.d/99-tailscale.conf >/dev/null

# 3. Persist credentials for the boot service.
umask 077
cat > /etc/tailscale-connector.env <<EOF
TS_OAUTH_CLIENT_ID=$TS_OAUTH_CLIENT_ID
TS_OAUTH_SECRET=$TS_OAUTH_SECRET
TS_TAGS=$TS_TAGS
TS_HOSTNAME=$TS_HOSTNAME
EOF
chmod 600 /etc/tailscale-connector.env
umask 022

# 4. Install the boot-dance script.
cat > /usr/local/bin/tailscale-connector.sh <<'SCRIPT'
#!/bin/sh
set -eu
. /etc/tailscale-connector.env

ACCESS_TOKEN=$(curl -fsS \
  -d "client_id=$TS_OAUTH_CLIENT_ID" \
  -d "client_secret=$TS_OAUTH_SECRET" \
  https://api.tailscale.com/api/v2/oauth/token | jq -r .access_token)

TS_AUTHKEY=$(curl -fsS -X POST \
  -H "Authorization: Bearer $ACCESS_TOKEN" \
  -H "Content-Type: application/json" \
  -d "{\"capabilities\":{\"devices\":{\"create\":{\"reusable\":false,\"ephemeral\":true,\"preauthorized\":true,\"tags\":[\"$TS_TAGS\"]}}}}" \
  https://api.tailscale.com/api/v2/tailnet/-/keys | jq -r .key)

tailscale up \
  --auth-key="$TS_AUTHKEY" \
  --advertise-connector \
  --advertise-tags="$TS_TAGS" \
  --hostname="$TS_HOSTNAME" \
  --accept-routes
SCRIPT
chmod +x /usr/local/bin/tailscale-connector.sh

# 5. systemd unit that runs the boot dance after tailscaled comes up.
cat > /etc/systemd/system/tailscale-connector.service <<EOF
[Unit]
Description=Bring this box up as a Tailscale App Connector
After=tailscaled.service network-online.target
Wants=tailscaled.service network-online.target

[Service]
Type=oneshot
ExecStart=/usr/local/bin/tailscale-connector.sh
RemainAfterExit=yes

[Install]
WantedBy=multi-user.target
EOF

systemctl daemon-reload
systemctl enable --now tailscale-connector.service

echo
echo "Setup complete. Tailscale status:"
tailscale status || true
echo
echo "If you don't see this node tagged and advertising routes in"
echo "  https://login.tailscale.com/admin/machines"
echo "check: journalctl -u tailscale-connector --no-pager"
