# 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 `. - **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 palav homelab # write a hosts.toml entry from an SSH alias dosh update # update the installed client ``` If something fails, `dosh doctor ` 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 `. Render one frame and detach: `dosh --attach-only `. 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 ` to reattach a known session; bare `dosh ` 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 `. ## 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.