# SSH Bootstrap Pattern (Key Not Authorized)

When a remote desktop machine's SSH key isn't in authorized_keys, the agent cannot connect. The connection hangs at authentication even though ping works and port 22 is open.

## Symptom
```text
ping → 0.17ms ✅
nc -zv host 22 → port open ✅
ssh host → hangs until timeout ❌
ssh -v host → no auth progress shown, just hangs at some pre-auth phase
```

## Root Cause
Arch/CachyOS ships with `PasswordAuthentication no` by default. Only key-based auth works. If the agent's public key isn't in `~/.ssh/authorized_keys` on the target, SSH hangs silently.

## Fix

### Option A — Direct copy (user types the key)
User runs this on the target (from TTY or existing session):
```bash
mkdir -p ~/.ssh && chmod 700 ~/.ssh
echo "ssh-ed25519 <agent-public-key>" >> ~/.ssh/authorized_keys
chmod 600 ~/.ssh/authorized_keys
```

### Option B — HTTP server (no long key to type)
When the user can't/won't type a long SSH key, serve it from your machine:

**On your machine:**
```bash
echo "ssh-ed25519 AAAA..." > /tmp/pubkey.txt
# Must be in the same directory as the file:
cd /tmp && python3 -m http.server 18900 --bind 0.0.0.0
# VERIFY locally before telling the user:
curl -s http://127.0.0.1:18900/pubkey.txt
```

**User runs on target TTY:**
```bash
curl -s http://<YOUR_IP>:18900/pubkey.txt >> ~/.ssh/authorized_keys && chmod 600 ~/.ssh/authorized_keys
```

### Verify
Ask the user to confirm: `tail -3 ~/.ssh/authorized_keys`
The line should start with `ssh-ed25519` or `ssh-rsa` and end with a hostname comment.

## Key Things That Trip You Up

### 1. Check Your Own SSH Agent First
Before blaming the remote authorized_keys, verify the local agent has the key loaded:
```bash
ssh-add -l
# If "The agent has no identities" → ssh-add ~/.ssh/id_ed25519
```
Even with the key file on disk at `~/.ssh/id_ed25519` with correct permissions, if the agent doesn't have it loaded, authentication can behave inconsistently (especially for key types added to agent mid-session). Run `ssh-add` as a standard first step before deep-diving into the remote side.

### 2. TTY `~` Expands to Root, Not the User
When the user is logged in as root on TTY (Ctrl+Alt+F2/F3), `ls -la ~/.ssh/` shows **/root/.ssh/**, NOT /home/&lt;user&gt;/.ssh/. If SSH connects as a regular user (e.g. raymond) but the key was added to root's authorized_keys, SSH still hangs.

**Always check first:** run `whoami` on the user's TTY. Use absolute paths like `/home/raymond/.ssh/authorized_keys` when the user is root.

### 3. Retry Cadence
You will try SSH 3-4 times with different flags (`-v`, `-o ServerAliveInterval`, Tailscale IP, reverse tunnel) before concluding it's an authorized_keys issue. After ping + nc both confirm the machine is reachable and port 22 is open, move straight to "check authorized_keys" and skip the flag-swapping phase.

### 4. Verify Every Step
When the user says "try now" after running a key-add command, ALWAYS ask them to verify first: `tail -3 ~/.ssh/authorized_keys`. The line should start with `ssh-ed25519` or `ssh-rsa` and be on one line. Don't retry SSH without confirming the key is actually there and well-formed.

### 5. SSH verbose tells you nothing if it hangs at auth
The `-vvv` output will show:
```
debug1: Connection established.
debug1: identity file .../id_ed25519 type 3
debug1: Authenticating to 192.168.1.111:22 as 'raymond'
[hangs → timeout]
```
This pattern means TCP works, version negotiation passes, local key found — but the server doesn't respond to the key offered. Three possibilities: (a) key not in authorized_keys for that user, (b) wrong file permissions on remote side, (c) `AuthorizedKeysFile` points to a non-standard path.

## Last Resort: Reverse SSH Tunnel

If you can't get the key authorized and the target machine can SSH **out** to your machine, use a reverse tunnel:

**User runs on target TTY** (this stays running — it's the tunnel):
```bash
ssh -R 2222:localhost:22 <YOUR_USER>@<YOUR_IP>
```

**Then from your machine** (in another terminal):
```bash
ssh -p 2222 raymond@127.0.0.1
```

This bypasses the target's authorized_keys entirely. The outgoing SSH connection authenticates to your machine (where you control authorized_keys). The `-R 2222:localhost:22` flag forwards the target's port 22 back to your localhost:2222. Your second SSH connects through that tunnel, appearing to the target as a localhost connection that may or may not be subject to key restrictions depending on sshd GatewayPorts setting. Most useful when: the user can SSH to you but you cannot SSH to them, even after multiple key-add attempts.

### Keep the tunnel alive
Use `-o ServerAliveInterval=30` on the user's command to prevent the tunnel from dropping after idle periods:
```bash
ssh -o ServerAliveInterval=30 -R 2222:localhost:22 <YOUR_USER>@<YOUR_IP>
```
