---
name: tailscale-remote-access
description: Set up Tailscale on a self-hosted server for remote SSH access from anywhere — no open ports, no dynamic DNS.
---

# Tailscale Remote Access

Use when the user wants to set up remote terminal/SSH access to a self-hosted server via Tailscale.

## Approach: SSH over Tailscale (default)

Keep existing OpenSSH server. Tailscale provides the encrypted tunnel and stable `100.x.y.z` IP. No port forwarding, no firewall changes.

## Installation

```bash
curl -fsSL https://tailscale.com/install.sh | sh
```

Installs via apt on Ubuntu/Debian, adds the Tailscale repo and GPG key, starts `tailscaled.service`.

## Authentication

```bash
sudo tailscale up
```

This prints a one-time auth URL (`https://login.tailscale.com/a/...`). The URL changes each run.

### Pitfall: agent can't complete browser auth

See `references/agent-auth-workaround.md` for detailed reproduction and the background-process workaround.

In short: the agent installs Tailscale, captures the auth URL from `tailscale status`, gives it to the user, then runs `sudo tailscale up` in the background with `notify_on_complete=true`. The user authenticates in their browser and the background process exits. If the user is on the server's terminal, they can just run `sudo tailscale up` themselves — simpler. For fully automated setups, use `--authkey`.

### Auth keys (pre-authenticated)

For fully automated setups, generate an auth key in the Tailscale admin console and pass it:

```bash
sudo tailscale up --authkey tskey-client-...
```

But for one-off setup with an existing account, browser auth is the standard path.

## Post-setup verification

```bash
tailscale status          # should show the server and other devices on the tailnet
tailscale ip -4           # the server's Tailscale IP for SSH
```

## SSH usage

From any other device on the same tailnet with Tailscale installed:

```bash
ssh user@<tailscale-ip>
```

The connection goes through Tailscale's WireGuard tunnel. No port 22 exposed to the internet.

## Pitfall: mobile hotspot doesn't bridge Tailscale

A phone running Tailscale + sharing its mobile hotspot does **not** bridge Tailscale traffic to connected devices. The hotspot creates a local NAT — the tethered tablet/laptop gets a private IP from the phone and routes internet through cellular, but Tailscale's virtual interface (`tailscale0`) is separate and not bridged. Each device that needs to reach Tailscale nodes must install its own Tailscale client.

## Tailscale SSH (alternative)

Tailscale can also manage SSH entirely, removing the need for `openssh-server`. Auth is handled by Tailscale ACLs + SSO instead of SSH keys.

### During initial auth

```bash
sudo tailscale up --ssh
```

### After tailscale is already authenticated

```bash
sudo tailscale set --ssh
```

If the server was set up with plain `tailscale up` (no `--ssh`), use `tailscale set --ssh` to enable SSH post-auth. This is the common case when Tailscale was installed for general connectivity and SSH is added later.

Then from any tailnet device: `ssh user@<hostname>` or `ssh user@<tailscale-ip>`.

If the user explicitly asks for Tailscale SSH, enable it — even if `openssh-server` is already working. The two can coexist.
