# SSH Access Guide for Homelab

This guide documents the actual SSH configuration used to access all homelab hosts. All access goes through the **Tailscale mesh network** (`tail.vish.gg` MagicDNS suffix). There is no direct LAN SSH — all hosts are accessed via their Tailscale IPs.

## Network Overview

- **Mesh network**: Tailscale / Headscale (`headscale.vish.gg:8443`)
- **MagicDNS suffix**: `tail.vish.gg`
- **SSH key**: `~/.ssh/id_ed25519` (default key, no IdentityFile needed in config)
- **Config location**: `~/.ssh/config` on homelab VM

---

## SSH Config (`~/.ssh/config`)

The full working SSH config on the homelab VM:

```
# Atlantis - Primary Synology NAS (DS1821+)
Host atlantis
    HostName 100.83.230.112
    User vish
    Port 60000

# Calypso - Secondary Synology NAS (DS723+)
Host calypso
    HostName 100.103.48.78
    User Vish
    Port 62000

# Homelab VM
Host homelab
    HostName 100.67.40.126
    User homelab
    # Note: password authentication only (no key auth configured on this host)

# Proxmox VE host
Host pve
    HostName 100.87.12.28
    User root

# Concord NUC (Intel NUC)
Host vish-concord-nuc
Host concord
Host nuc
    HostName 100.72.55.21
    User vish

# TrueNAS Scale (Guava)
Host guava
Host truenas
    HostName 100.75.252.64
    User vish

# Raspberry Pi 5
Host pi-5
    HostName 100.77.151.40
    User vish

# Setillo (Proxmox LXC / container)
Host setillo
    HostName 100.125.0.20
    User vish

Host setillo-root
    HostName 100.125.0.20
    User root

# Jellyfish (GL-MT3000 LAN device)
Host jellyfish
    HostName 100.69.121.120
    User lulu

# Home Assistant OS
Host homeassistant
    HostName 100.112.186.90
    User hassio
    Port 22

# GL-MT3000 (Beryl AX - IoT/HA gateway router)
Host gl-mt3000
    HostName 100.126.243.15
    User root

# GL-BE3600 (Slate 7 - travel/repeater router)
Host gl-be3600
    HostName 100.105.59.123
    User root

# mastodon-rocky (Rocky Linux 10 VM - Mastodon)
Host mastodon-rocky
    HostName 100.64.0.3
    User root

# vishdebian (Debian 13 Trixie desktop)
Host vishdebian
    HostName 100.64.0.2
    User vish

# shinku-ryuu (Windows desktop)
Host shinku-ryuu
    HostName 100.98.93.15
    User vish

# Seattle VPS
Host seattle
Host seattle-tailscale
    HostName <seattle-tailscale-ip>
    User root

# Laptop (offline when sleeping)
Host laptop
    HostName 100.124.91.52
    User vish
```

---

## Host Reference

| Alias(es) | Tailscale IP | User | Port | Host |
|-----------|-------------|------|------|------|
| `atlantis` | 100.83.230.112 | vish | 60000 | Synology DS1821+ |
| `calypso` | 100.103.48.78 | Vish | 62000 | Synology DS723+ |
| `homelab` | 100.67.40.126 | homelab | 22 | Homelab VM (password auth) |
| `pve` | 100.87.12.28 | root | 22 | Proxmox VE |
| `concord`, `nuc`, `vish-concord-nuc` | 100.72.55.21 | vish | 22 | Intel NUC |
| `guava`, `truenas` | 100.75.252.64 | vish | 22 | TrueNAS Scale |
| `pi-5` | 100.77.151.40 | vish | 22 | Raspberry Pi 5 |
| `setillo` | 100.125.0.20 | vish | 22 | Proxmox LXC container |
| `setillo-root` | 100.125.0.20 | root | 22 | Proxmox LXC container (root) |
| `jellyfish` | 100.69.121.120 | lulu | 22 | Device on GL-MT3000 LAN |
| `homeassistant` | 100.112.186.90 | hassio | 22 | Home Assistant OS |
| `gl-mt3000` | 100.126.243.15 | root | 22 | GL-MT3000 router (dropbear) |
| `gl-be3600` | 100.105.59.123 | root | 22 | GL-BE3600 router (dropbear) |
| `vishdebian` | 100.64.0.2 | vish | 22 | Debian 13 Trixie desktop |
| `mastodon-rocky` | 100.64.0.3 | root | 22 | Rocky Linux 10 VM (Mastodon) |
| `shinku-ryuu` | 100.98.93.15 | vish | 22 | Windows desktop (Win32-OpenSSH) |
| `laptop` | 100.124.91.52 | vish | 22 | Laptop (offline when sleeping) |

---

## Special Notes Per Host

### Atlantis & Calypso (Synology)
- SSH port is non-standard (60000 / 62000) — configured in DSM → Terminal & SNMP
- Synology Docker is at `/usr/local/bin/docker`, requires `sudo`
- `User` is case-sensitive: `vish` on Atlantis, `Vish` (capital V) on Calypso

### homelab VM
- **Password authentication only** — no SSH key installed on this host
- Auth: password (same as the username) # pragma: allowlist secret

### pve (Proxmox)
- Root login; key-based auth
- To access containers: `ssh pve "pct exec <CTID> -- <command>"`

### GL-MT3000
- Uses **dropbear** SSH (not OpenSSH) — no `/etc/ssh/sshd_config`
- Authorized keys: `/etc/dropbear/authorized_keys`
- Is the **gateway for jellyfish and Home Assistant** (LAN: `192.168.12.0/24`)
- Advertises subnet route `192.168.12.0/24` via Headscale
- Tailscale version: `1.92.5-tiny` (GL-inet custom build)

### GL-BE3600
- Uses **dropbear** SSH (not OpenSSH)
- Authorized keys: `/etc/dropbear/authorized_keys`
- Acts as a **Wi-Fi repeater** on the home network (management: `192.168.68.53`, own LAN: `192.168.8.1`)
- Ports are filtered from homelab VM and NUC — only reachable directly via its `192.168.8.x` LAN or Tailscale
- Advertises subnet route `192.168.8.0/24` via Headscale
- Tailscale version: `1.90.9-tiny` (GL-inet custom build)

### shinku-ryuu (Windows)
- Running **Win32-OpenSSH v10.0.0.0** (installed via MSI from GitHub)
- Authorized keys location: `C:\ProgramData\ssh\administrators_authorized_keys`
  - (NOT `~/.ssh/authorized_keys` — Windows OpenSSH ignores per-user authorized_keys for Administrator group members)
- Permissions on that file must be restricted to SYSTEM and Administrators only

### TrueNAS (guava)
- User `vish` is in the `docker` group — no `sudo` needed for Docker commands

---

## Headscale Subnet Routes

All subnet routes are approved via Headscale. Non-overlapping:

| Node | Subnet | Status |
|------|--------|--------|
| calypso | 192.168.0.0/24 | Serving (primary) — **advertiser** |
| atlantis | 192.168.0.0/24 | Approved, not serving (backup) — **advertiser** |
| vish-concord-nuc | 192.168.68.0/22 | Serving |
| setillo | 192.168.69.0/24 | Serving |
| gl-mt3000 | 192.168.12.0/24 | Serving |
| gl-be3600 | 192.168.8.0/24 | Serving |

To inspect/approve routes:
```bash
# On Calypso (where Headscale container runs):
ssh calypso
docker exec headscale headscale nodes list
docker exec headscale headscale nodes list-routes --identifier <ID>
docker exec headscale headscale nodes approve-routes --identifier <ID> --routes <CIDR>
```

> **Note**: In Headscale v0.28, `--user` takes a numeric ID, not a username. Use `headscale users list` to find IDs.

---

## Common SSH Tasks

```bash
# Run a docker command on Atlantis
ssh atlantis "sudo /usr/local/bin/docker ps"

# Run a docker command on Guava (no sudo needed)
ssh guava "docker ps"

# Access a Proxmox LXC container
ssh pve "pct exec 103 -- docker ps"

# Copy a file to Atlantis
scp myfile.yaml atlantis:/volume1/docker/

# Port forward a remote service locally
ssh -L 8080:localhost:8080 atlantis
```

---

## Troubleshooting

```bash
# Debug connection
ssh -vvv <host>

# Remove stale host key (after host rebuild)
ssh-keygen -R <hostname-or-ip>

# Fix local permissions
chmod 700 ~/.ssh
chmod 600 ~/.ssh/config
chmod 600 ~/.ssh/authorized_keys
chmod 600 ~/.ssh/id_ed25519
chmod 644 ~/.ssh/id_ed25519.pub
```

---

*Last Updated*: 2026-03-10 (added vishdebian, mastodon-rocky)
*All hosts accessed via Tailscale mesh — no direct LAN SSH*
