#!/usr/bin/env bash # Expose the tracker to the tailnet with `tailscale serve`. # # scripts/tailscale.sh on # forward tailnet port $PORT to the tracker # scripts/tailscale.sh off # stop forwarding # scripts/tailscale.sh status # show the serve config and the URL # # Uses raw TCP forwarding (`serve --tcp`), not HTTP serve: HTTP serve routes by # hostname, so it only answers on the MagicDNS name, and MagicDNS is off in our # tailnet. TCP forwarding answers on the Tailscale IP and passes the live-update # stream (Server-Sent Events) through unbuffered. # # Works with Tailscale inside WSL or on the Windows host. With WSL2 in NAT mode, # Windows reaches the tracker through WSL's localhost forwarding, which here # listens on ::1 only, so the target is "localhost" (not 127.0.0.1). set -euo pipefail PORT="${PORT:-8099}" TS="${TAILSCALE:-}" if [[ -z "$TS" ]]; then if command -v tailscale >/dev/null 2>&1; then TS=tailscale elif [[ -x "/mnt/c/Program Files/Tailscale/tailscale.exe" ]]; then TS="/mnt/c/Program Files/Tailscale/tailscale.exe" else echo "tailscale not found: install it in WSL or on Windows, or set TAILSCALE=/path/to/tailscale" >&2 exit 1 fi fi url() { local ip ip="$("$TS" ip -4 | tr -d '\r' | head -1)" echo "http://${ip}:${PORT}/" } case "${1:-status}" in on) if ! curl -sf -m 3 "http://localhost:${PORT}/healthz" >/dev/null; then echo "warning: the tracker is not answering on localhost:${PORT}; start it with: cd tracker && go run ." >&2 fi "$TS" serve --bg --tcp="$PORT" "tcp://localhost:${PORT}" | tr -d '\r' echo "Tracker on the tailnet: $(url)" ;; off) "$TS" serve --tcp="$PORT" off | tr -d '\r' ;; status) "$TS" serve status | tr -d '\r' echo "URL: $(url)" ;; *) echo "usage: $0 on|off|status" >&2 exit 2 ;; esac