Skip to content

Instantly share code, notes, and snippets.

@skylarbpayne
Last active January 11, 2026 00:29
Show Gist options
  • Select an option

  • Save skylarbpayne/5ee9604dff0631d1b3f2357e62db7dba to your computer and use it in GitHub Desktop.

Select an option

Save skylarbpayne/5ee9604dff0631d1b3f2357e62db7dba to your computer and use it in GitHub Desktop.
Setup Tailscale CLI with SSH support on macOS
#!/bin/bash
# Setup Tailscale CLI with SSH support on macOS
# This script installs the CLI version (not GUI) which supports acting as an SSH server
set -e
echo "=== Tailscale CLI Setup for macOS ==="
echo ""
# Step 1: Quit the GUI app if running
echo "[1/5] Checking for Tailscale GUI app..."
if pgrep -f "Tailscale.app" > /dev/null; then
echo " → Quitting Tailscale GUI app..."
osascript -e 'quit app "Tailscale"' 2>/dev/null || true
sleep 2
echo " ✓ GUI app quit"
else
echo " ✓ No GUI app running"
fi
# Step 2: Install Tailscale CLI via Homebrew
echo ""
echo "[2/5] Installing Tailscale CLI..."
if ! brew list tailscale &>/dev/null; then
echo " → Installing tailscale via Homebrew..."
brew install tailscale
echo " ✓ Installed"
else
echo " ✓ Already installed"
fi
# Step 3: Start the Tailscale daemon (will start on boot)
echo ""
echo "[3/5] Starting Tailscale daemon..."
if ! pgrep tailscaled > /dev/null; then
echo " → Starting tailscaled service..."
echo " (This will prompt for your password)"
sudo brew services start tailscale
sleep 2
echo " ✓ Daemon started and configured to run on boot"
else
echo " ✓ Daemon already running"
fi
# Step 4: Authenticate and enable SSH
echo ""
echo "[4/5] Authenticating Tailscale with SSH enabled..."
if tailscale status &>/dev/null; then
echo " ✓ Already authenticated"
else
echo " → Running: tailscale up --ssh"
tailscale up --ssh
echo " ✓ Authentication complete"
fi
# Step 5: Display status and next steps
echo ""
echo "[5/5] Setup complete!"
echo ""
tailscale status
echo ""
echo "=== Next Steps ==="
echo ""
echo "1. Configure ACL for SSH access:"
echo " - Go to: https://login.tailscale.com/admin/acls"
echo " - In the 'ssh' section, change 'action': 'check' to 'action': 'accept'"
echo " - This prevents re-authentication hangs on each connection"
echo ""
echo "2. If you see a duplicate device (with '-1' suffix):"
echo " - Go to: https://login.tailscale.com/admin/machines"
echo " - Remove the OLD offline device"
echo " - Run: tailscale set --hostname $(hostname -s)"
echo ""
echo "3. SSH into this machine from any device on your tailnet:"
echo " ssh $(whoami)@$(hostname -s)"
echo " (Note: Specify username to avoid mismatch errors)"
echo ""
echo "4. The Tailscale daemon will auto-start on boot"
echo ""
echo "=== Key Learnings ==="
echo "- macOS GUI app CANNOT act as SSH server (sandboxed)"
echo "- CLI version (open source tailscaled) supports SSH server"
echo "- Use 'tailscale up --ssh' to enable SSH in one command"
echo "- Homebrew service automatically configures boot startup"
echo "- ACL default uses 'check' mode - change to 'accept' for seamless SSH"
echo "- Always specify username when SSHing: ssh username@hostname"
echo ""
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment