# Tailscale Connect your Toes appliance to your Tailscale network for secure access from anywhere. Tailscale is pre-installed on the appliance but not configured. The user authenticates through the dashboard or CLI — no SSH required. ## how it works 1. User clicks "Connect to Tailscale" in the dashboard (or runs `toes tailscale connect`) 2. Toes runs `tailscale login` and captures the auth URL 3. Dashboard shows the URL and a QR code 4. User visits the URL and authenticates with Tailscale 5. Toes detects the connection, runs `tailscale serve --bg 80` 6. Appliance is now accessible at `https://..ts.net` ## dashboard Settings area shows one of three states: **Not connected:** - "Connect to Tailscale" button **Connecting:** - Auth URL as a clickable link - QR code for mobile - Polls `tailscale status` until authenticated **Connected:** - Tailnet URL (clickable) - Tailnet name - Device hostname - `tailscale serve` toggle - "Disconnect" button ## cli ```bash toes tailscale # show status toes tailscale connect # start auth flow, print URL, wait toes tailscale disconnect # log out of tailnet toes tailscale serve # toggle tailscale serve on/off ``` ### `toes tailscale` ``` Tailscale: connected Tailnet: user@github Hostname: toes.tail1234.ts.net IP: 100.64.0.1 Serve: on (port 80) ``` Or when not connected: ``` Tailscale: not connected Run `toes tailscale connect` to get started. ``` ### `toes tailscale connect` ``` Visit this URL to authenticate: https://login.tailscale.com/a/abc123 Waiting for authentication... done! Connected to tailnet user@github https://toes.tail1234.ts.net ``` ## server api All endpoints shell out to the `tailscale` CLI and parse output. ### `GET /api/tailscale` Returns current status. ```json { "installed": true, "connected": true, "hostname": "toes", "tailnetName": "user@github", "url": "https://toes.tail1234.ts.net", "ip": "100.64.0.1", "serving": true } ``` When not connected: ```json { "installed": true, "connected": false } ``` When tailscale isn't installed: ```json { "installed": false } ``` ### `POST /api/tailscale/connect` Runs `tailscale login`. Returns the auth URL. ```json { "authUrl": "https://login.tailscale.com/a/abc123" } ``` ### `POST /api/tailscale/disconnect` Runs `tailscale logout`. ### `POST /api/tailscale/serve` Toggles `tailscale serve`. Body: ```json { "enabled": true } ``` ## install `scripts/install.sh` installs tailscale and enables the daemon, but does not authenticate: ```bash curl -fsSL https://tailscale.com/install.sh | sh sudo systemctl enable tailscaled ``` ## permissions The `toes` user needs passwordless sudo for tailscale commands. Add to sudoers during install: ``` toes ALL=(ALL) NOPASSWD: /usr/bin/tailscale ``` This lets the server run `sudo tailscale login`, `sudo tailscale serve`, etc. without a password prompt.