# dosh (Dormant Shell)

> dosh is a low-latency remote terminal for homelab/personal servers. It is mosh-shaped
> but not a mosh clone: `dosh-server` is a resident daemon that keeps terminal sessions
> hot, and the client reconnects over encrypted UDP — so attach and reconnect are
> near-instant (~3 ms of local overhead + one network RTT). SSH is used once to
> establish trust; after that, repeat attaches skip SSH entirely. It also does SSH-style
> TCP port forwarding (`-L`/`-R`/`-D`) over the same encrypted transport, which is what
> makes back-and-forth client↔server homelab comms easy.

This file orients an AI agent (or a human) on what dosh is, what it can do, and how to
drive it. It is intentionally self-contained. For deeper detail, see the linked docs at
the bottom.

## What dosh is for

Use dosh instead of `ssh`/`mosh` for **interactive shells and TCP forwarding** to a
server where you control both ends and have installed `dosh-server` (typically a homelab
box, VPS, or workstation). It shines when you:

- want a terminal that survives laptop sleep, Wi-Fi changes, and NAT rebinding, and
  resumes instantly instead of hanging;
- reconnect to the same box many times a day and don't want to pay SSH startup each time;
- need to reach services on the server from your laptop (or vice-versa) without standing
  up a VPN.

dosh is **not** a drop-in for every SSH use. It does not do `scp`/`sftp` file transfer,
X11, or act as an `sshd` for arbitrary SSH clients. Keep `ssh` installed for those.

## Core capabilities

- **Encrypted UDP terminal transport** — AEAD-encrypted, with packet sequencing, a
  sliding replay window, ACKs, and server-side retransmit of unacked output.
- **Resident server + hot sessions** — `dosh-server` runs as a daemon; named sessions
  (and a prewarmed `default`) stay alive across client disconnects.
- **Fast attach / reconnect** — see "Fast path order" below; cached attach is ~one RTT.
- **Roaming** — the session follows the client across IP/port changes.
- **Named & shared sessions** — reattach the same persistent terminal from multiple
  clients; optional **view-only** clients.
- **TCP port forwarding** — local (`-L`), remote (`-R`), and dynamic SOCKS (`-D`) over
  the encrypted transport, with per-stream flow control and terminal-priority
  scheduling (bulk transfers don't lag your keystrokes).
- **Native UDP auth** — Ed25519 user auth via ssh-agent or an (optionally encrypted)
  OpenSSH key, verified against `authorized_keys`. Falls back to SSH bootstrap when
  native auth isn't available. SSH host config (`HostName`, `User`, `Port`,
  `IdentityFile`, `ProxyJump`, etc.) is honored.
- **Host-key pinning** — TOFU/known-hosts with hard-fail on mismatch.
- **Speculative local echo** — optional predictive echo for laggy links (display-only;
  real input is always sent to the server).
- **Ops commands** — `doctor`, `sessions`, `trust`, `import-ssh`, `update`.

## Quickstart

Install the server on each box you want to reach (default UDP port `50000`):

```bash
curl -fsSL https://git.palav.dev/Palav/dosh/raw/branch/main/install.sh \
  | DOSH_PORT=50000 sh -s -- server
```

Install the client (macOS/Linux), then attach:

```bash
curl -fsSL https://git.palav.dev/Palav/dosh/raw/branch/main/install.sh \
  | DOSH_SERVER=homelab DOSH_HOST=homelab.example.com DOSH_PORT=50000 sh -s -- client

dosh homelab                 # fresh interactive shell
dosh homelab uptime          # run one command
dosh --session work homelab  # named, persistent, reattachable session
```

- Detach (leave the server session running): **Ctrl-]**.
- End the session: type `exit` in the remote shell.
- If UDP stalls, dosh keeps the terminal open, sends keepalives, and ticket-reconnects.

## Client↔server homelab comms (the back-and-forth)

Forwarding is the key to "make homelab comms easy." Three directions:

| Command | Direction | Effect |
| --- | --- | --- |
| `dosh -L [bind:]LPORT:THOST:TPORT host` | pull server→you | A listener on **your machine** (`bind`, default localhost) forwards to `THOST:TPORT` reached **from the server**. |
| `dosh -R [bind:]LPORT:THOST:TPORT host` | push you→server | A listener on **the server** (loopback by default) forwards to `THOST:TPORT` reached **from your machine**. |
| `dosh -D [bind:]LPORT host` | SOCKS via server | A SOCKS5 proxy on **your machine**; traffic egresses **from the server**. |

Concrete homelab patterns:

```bash
# Reach the homelab's internal Grafana (server-side :3000) from your laptop browser:
dosh -L 3000:127.0.0.1:3000 homelab            # open http://localhost:3000

# Reach a DB that only listens on the homelab LAN:
dosh -L 5432:10.0.0.5:5432 homelab             # psql -h 127.0.0.1 -p 5432

# Let the homelab hit a dev server running on your laptop (e.g. a webhook target):
dosh -R 9000:127.0.0.1:8080 homelab           # homelab curls http://127.0.0.1:9000

# Route browser traffic out through the homelab's network:
dosh -D 1080 homelab                           # SOCKS5 proxy at 127.0.0.1:1080

# Forward-only, no shell; multiple forwards; background after listeners are up:
dosh -N -L 3000:127.0.0.1:3000 -L 5432:10.0.0.5:5432 homelab
dosh -f -N -L 3000:127.0.0.1:3000 homelab
```

Server policy controls forwarding: `allow_tcp_forwarding`, `allow_remote_forwarding`,
`allow_remote_non_loopback_bind`, and per-key `permitopen=`/`no-port-forwarding` in
`authorized_keys`. Remote listeners bind to loopback unless explicitly allowed.

## Fast path order (why it's quick)

The client tries the cheapest valid path first:

1. **UDP resume** — existing client id + session key; one encrypted UDP round-trip.
2. **UDP attach ticket** — cached server-issued ticket; one round-trip, no SSH.
3. **Native UDP auth** — Ed25519 handshake (ssh-agent/key) when enabled.
4. **SSH bootstrap** — `ssh user@host dosh-auth …` once, then a UDP attach.

Measured locally (loopback, release): cached attach ≈ **3 ms**, cold native auth ≈ 9 ms.
Over a real link, add one RTT. See `docs/BENCHMARKS.md`.

## Architecture (1-minute model)

- **dosh-server** — single UDP socket on one port; a session table keyed by name; one
  PTY per named session; per-session terminal screen state (vt100) for snapshots/diffs;
  a per-session client table; encrypted UDP protocol; a small SSH-invoked `dosh-auth`
  helper. Abandoned (clientless, non-prewarmed) sessions and their shells are reaped
  after a grace period; prewarmed sessions stay hot.
- **dosh-client** — raw-mode terminal; local credential cache; tries resume/ticket/native
  before SSH; forwards PTY I/O; reconnect/roaming state machine; optional predictive echo.
- **Binaries** — `dosh-server`, `dosh-client` (symlinked as `dosh`), `dosh-auth`
  (SSH-invoked trust helper), `dosh-bench` (benchmarks).

## Security model (summary)

- First trust via SSH; thereafter encrypted Dosh transport. Native auth available.
- KEX X25519; AEAD ChaCha20-Poly1305; KDF HKDF-SHA256; host & user auth Ed25519;
  SHA-256 transcript binding. Per-direction, per-sequence nonces; replay window.
- Host keys pinned in `~/.config/dosh/known_hosts`; mismatch hard-fails.
- User auth against `~/.ssh/authorized_keys` (+ optional `~/.config/dosh/authorized_keys`);
  removed keys can't authenticate; unsupported restrictive options fail closed.
- Forward secrecy from ephemeral X25519; attach tickets are server-sealed and scoped.

dosh claims security **equivalent to, and in places stronger than, SSH for the dosh
terminal/forwarding use case** — not full SSH-protocol parity. Read `docs/THREAT_MODEL.md`
for the honest stance, residual risks, and what's still pending before public claims.

## Configuration

- **Client** `~/.config/dosh/client.toml` — `auth_preference` (e.g. `"native,ssh"`),
  `trust_on_first_use`, `identity_files`, `use_ssh_agent`, `forward_agent`, `send_env`,
  `set_env`, `dosh_port`, `default_session`, `predict`, `reconnect_timeout_secs`,
  `credential_cache`, `known_hosts`.
- **Hosts** `~/.config/dosh/hosts.toml` — per-alias `[name]` with `ssh`, `dosh_host`,
  `port`, `user`, `default_command`, `predict`. Generate from SSH aliases with
  `dosh import-ssh <alias> <name>`.
- **Server** `~/.config/dosh/server.toml` — `port`, `bind`, `shell`, `prewarm_sessions`,
  `native_auth`, `host_key`, `authorized_keys`, `attach_ticket_ttl_secs`,
  `client_timeout_secs`, `allow_tcp_forwarding`, `allow_remote_forwarding`,
  `allow_remote_non_loopback_bind`, `allow_agent_forwarding`, `accept_env`,
  `native_auth_rate_limit_per_minute`.

Paths: host key `~/.config/dosh/host_key`; credential cache
`~/.local/share/dosh/credentials/`.

## Operating & diagnostics

```bash
dosh doctor homelab     # host resolution, trust state, UDP reachability, server
                        # version, usable keys, auth result, forwarding policy
dosh sessions homelab   # list live sessions
dosh trust homelab      # fetch + pin the Dosh host key (via SSH fallback)
dosh trust --remove homelab
dosh import-ssh homelab   # write a hosts.toml entry from an SSH alias
dosh update             # update the installed client
```

If something fails, `dosh doctor <host>` is the first stop — every public error is meant
to be actionable (host trust, auth failure, UDP blocked, forwarding denied, version
mismatch, server unavailable).

## For agents driving dosh

- Run one command and exit: `dosh <host> <cmd...>`. Render one frame and detach:
  `dosh --attach-only <host>`. Both are non-interactive-friendly.
- A real terminal size is needed for full-screen rendering; with no TTY the client falls
  back to 80×24. Pass `-v`/`-vv` for timing/diagnostic logs on stderr.
- Prefer `--session <name>` to reattach a known session; bare `dosh <host>` opens a
  fresh, uniquely-named session each time.
- Never assume file transfer or X11 — use `ssh`/`scp` for those.
- Diagnostics are scriptable via `dosh doctor <host>`.

## Reference docs

- `README.md` — overview, install, develop, performance rules.
- `docs/NATIVE_V1_SPEC.md` — the native auth + forwarding v1 contract and verification
  checklist (with current status).
- `docs/THREAT_MODEL.md` — security claims, threat model, residual risks.
- `docs/PUBLIC_READINESS.md` — feature matrix and §16 verification status.
- `docs/BENCHMARKS.md` — how to benchmark; metric definitions; sample numbers.
- `SPEC.md` — protocol/wire details.
