655 lines
21 KiB
Markdown
655 lines
21 KiB
Markdown
# Dosh Native v1 Spec
|
|
|
|
> **v1 status (annotation, not part of the spec text below).** Native v1 is
|
|
> substantially implemented and being stabilized; it is not yet fully verified.
|
|
> Milestone progress against section 15:
|
|
>
|
|
> - Milestone 1 — host identity and trust: **done.** Host key generation, `dosh trust`,
|
|
> `known_hosts`, and mismatch hard-fail are implemented.
|
|
> - Milestone 2 — native user auth: **done.** `ClientHello`/`ServerHello`/`UserAuth`/
|
|
> `AuthOk`, ssh-agent and OpenSSH identity-file auth for Ed25519, ECDSA P-256,
|
|
> and RSA-SHA2, plus `authorized_keys` verification, exist.
|
|
> - Milestone 3 — default native auth: **done.** `auth_preference = "native,ssh"` is
|
|
> the default with explicit, visible SSH fallback. Local and Docker benchmark gates
|
|
> cover cached attach, SSH fallback, and native cold auth (Track C /
|
|
> `BENCHMARKS.md`).
|
|
> - Milestone 4 — forwarding: **implemented with one reliability caveat.** Stream
|
|
> mux, `-L`, `-R`, `-D`, `-N`, `-f`, and per-stream flow control exist;
|
|
> terminal-priority/load and replay/reorder regressions are covered. Dropped
|
|
> `StreamData` recovery still needs stream retransmission before lossy-link
|
|
> forwarding parity is claimed.
|
|
> - Milestone 5 — hardening: **partly done.** Per-IP token-bucket rate limiting,
|
|
> fail-closed protocol-version checks with a documented v1 policy, parser fuzz
|
|
> targets, fuzz-smoke/deep CI entry points, scripted TUI transport tests,
|
|
> forwarding load/priority/replay tests, and independent persistent session restart
|
|
> tests exist. External review and published long-soak evidence are not yet
|
|
> complete. The threat model is published (`docs/THREAT_MODEL.md`).
|
|
> - Milestone 6 — workflow parity: **mostly done.** `dosh doctor`, host-trust
|
|
> management, and the encrypted-key prompt flow exist; cross-OS daily-driver soak is
|
|
> ongoing.
|
|
>
|
|
> The section 16 verification checklist is **not yet fully green** — see the
|
|
> item-by-item status table in `docs/PUBLIC_READINESS.md` and the residual-risk list in
|
|
> `docs/THREAT_MODEL.md`. The section 17 public-claim gate is therefore **not met**.
|
|
|
|
Native Dosh is a remote-login protocol for Dosh-installed servers. It is intended to
|
|
replace the user's day-to-day `ssh host` workflow for terminals and forwarding while
|
|
keeping SSH as a compatibility and recovery fallback.
|
|
|
|
Native Dosh is not an RFC-compatible SSH implementation. It deliberately avoids the
|
|
full SSH transport/channel protocol and implements the smaller set of behavior Dosh
|
|
needs: authenticated login, encrypted terminal transport, reconnect/roaming, and TCP
|
|
forwarding.
|
|
|
|
## 1. Product Contract
|
|
|
|
User-facing commands:
|
|
|
|
```bash
|
|
dosh host
|
|
dosh host command...
|
|
dosh -L 8080:127.0.0.1:80 host
|
|
dosh -R 9000:127.0.0.1:9000 host
|
|
dosh --session work host
|
|
dosh --view-only --session work host
|
|
```
|
|
|
|
Compatibility expectations:
|
|
|
|
- Existing SSH keys and `ssh-agent` are reused.
|
|
- Server-side authorization uses `~/.ssh/authorized_keys`.
|
|
- Host trust is pinned in a Dosh known-hosts file and can be bootstrapped by SSH.
|
|
- `~/.ssh/config` host aliases, `HostName`, `User`, `Port`, `IdentityFile`,
|
|
`ProxyJump`, and `UserKnownHostsFile` are honored where practical.
|
|
- SSH bootstrap remains available with `--auth=ssh` and is used automatically when
|
|
native auth is disabled or cannot complete.
|
|
|
|
Native v1 is complete only if a normal interactive user can switch their daily
|
|
workflow from `ssh` to `dosh` without keeping SSH open in another tab for routine
|
|
tasks.
|
|
|
|
Non-goals for v1:
|
|
|
|
- RFC-compatible SSH server/client behavior.
|
|
- Arbitrary SSH subsystems.
|
|
- X11 forwarding.
|
|
- SFTP/SCP compatibility.
|
|
- Multi-user daemon mode with privileged account switching.
|
|
- Replacing OpenSSH on hosts that do not run `dosh-server`.
|
|
|
|
## 2. SSH Workflow Parity Target
|
|
|
|
Native v1 targets the SSH workflows interactive users actually use, not the entire
|
|
OpenSSH feature universe.
|
|
|
|
Must work in v1:
|
|
|
|
- Interactive shell: `dosh host`.
|
|
- Remote command: `dosh host command...`.
|
|
- Fresh terminal by default.
|
|
- Named persistent terminal: `dosh --session work host`.
|
|
- Shared/view-only session: `dosh --view-only --session work host`.
|
|
- Local forwarding: `dosh -L [bind:]listen:target:target_port host`.
|
|
- Remote forwarding: `dosh -R [bind:]listen:target:target_port host`.
|
|
- Dynamic forwarding: `dosh -D [bind:]listen host`, if stream flow control is proven;
|
|
otherwise it is the first v1.1 item and must be called out honestly.
|
|
- Multiple forwards in one connection.
|
|
- Forward-only mode: `dosh -N -L ... host`.
|
|
- Background forwarding: `dosh -f -N -L ... host`, or an equivalent supervised
|
|
user-service mode.
|
|
- SSH-agent authentication.
|
|
- Encrypted OpenSSH private-key authentication with prompt.
|
|
- `~/.ssh/config` host aliases for `Host`, `HostName`, `User`, `Port`,
|
|
`IdentityFile`, `ProxyJump`, `UserKnownHostsFile`, and `IdentitiesOnly`.
|
|
- Dosh host config overrides for user, Dosh-specific UDP host/port/auth policy.
|
|
- Clear host-key trust and mismatch errors.
|
|
- Clear auth failure errors that name the attempted key source.
|
|
- Stable reconnect after sleep, network switch, NAT rebinding, and server packet loss.
|
|
- `dosh update`.
|
|
- `dosh doctor host` for config/auth/UDP reachability diagnostics.
|
|
- `dosh sessions host` for session visibility.
|
|
|
|
Should work in v1 if it does not compromise the transport schedule:
|
|
|
|
- Agent forwarding with an explicit opt-in flag and clear warning.
|
|
- `ProxyJump` through SSH for bootstrap/trust and through Dosh-native relay later.
|
|
- `SendEnv`/`SetEnv` equivalent for explicit environment variables.
|
|
- Clipboard integration as a separate opt-in channel.
|
|
|
|
Explicitly not v1:
|
|
|
|
- X11 forwarding.
|
|
- SFTP/SCP wire compatibility.
|
|
- Full OpenSSH config language.
|
|
- Full `sshd` replacement for arbitrary SSH clients.
|
|
- Forced-command subsystems beyond fail-closed enforcement.
|
|
|
|
## 3. Stability Contract
|
|
|
|
Native v1 must be boring under real use:
|
|
|
|
- A closed laptop must not kill the remote session.
|
|
- A client crash must not kill the remote session.
|
|
- A server restart must not kill the remote session when `persist_sessions` is on
|
|
(currently opt-in until stress-tested): each session's shell runs in a detached
|
|
per-session *holder*
|
|
process whose PTY master fd the server passes back to itself via SCM_RIGHTS, so
|
|
the shell + scrollback survive a server crash/upgrade/`systemctl restart` and a
|
|
reattaching client lands on the same shell with its screen restored. With
|
|
`persist_sessions = false` the old behavior applies: live PTYs drop on restart,
|
|
but the client must still fail clearly and reconnect cleanly afterward.
|
|
- Decrypt failures from stale packets must be ignored or trigger reconnect, never
|
|
terminate the terminal by themselves.
|
|
- Terminal cleanup must restore cursor, mouse mode, bracketed paste, alternate
|
|
screen, and raw mode on exit.
|
|
- Forwarding streams must close cleanly without leaving orphan listeners.
|
|
- Every public error must be actionable: host trust, auth failure, UDP blocked,
|
|
forwarding denied, version mismatch, or server unavailable.
|
|
- `dosh host` must never attach to another active unnamed terminal by accident.
|
|
- The default install must be secure without hand-editing configs.
|
|
- Upgrades must preserve existing trusted host keys and credentials unless explicitly
|
|
rotated.
|
|
|
|
## 4. Security Contract
|
|
|
|
Native Dosh must match the security properties users rely on from SSH for this use
|
|
case:
|
|
|
|
- Server authentication before terminal data is trusted.
|
|
- User authentication by possession of an authorized private key or agent key.
|
|
- Forward secrecy for terminal and forwarding traffic.
|
|
- AEAD encryption and authentication for every post-handshake packet.
|
|
- Replay protection for handshake and transport packets.
|
|
- Host-key pinning with explicit first-use behavior.
|
|
- No plaintext terminal bytes after handshake begins.
|
|
- No custom cryptographic primitives.
|
|
- Clear downgrade behavior: native auth failure must not silently fall back to an
|
|
unauthenticated mode.
|
|
|
|
Native Dosh does not claim SSH's full protocol security surface. It claims equivalent
|
|
security for Dosh terminal and forwarding sessions on Dosh-installed servers.
|
|
|
|
## 5. Threat Model
|
|
|
|
In scope:
|
|
|
|
- Passive network observer.
|
|
- Active network attacker that can spoof, drop, replay, reorder, or modify packets.
|
|
- NAT rebinding and client IP/port changes.
|
|
- Stolen attach-ticket cache without the user's private key.
|
|
- Server restart and key rotation.
|
|
- Malicious unauthenticated client flooding auth attempts.
|
|
- Compromised low-privilege local user trying to read Dosh caches on a shared client.
|
|
|
|
Out of scope:
|
|
|
|
- Compromised client machine.
|
|
- Compromised server account.
|
|
- Malicious kernel, terminal emulator, or PTY implementation.
|
|
- Protecting against a server that is already authorized and then becomes malicious.
|
|
|
|
## 6. Cryptographic Building Blocks
|
|
|
|
Allowed primitives:
|
|
|
|
- Handshake pattern: Noise `NK` or `XX` through a maintained Rust Noise framework, or
|
|
a small audited construction over `x25519-dalek` plus transcript binding.
|
|
- KEX: X25519.
|
|
- Signatures for user auth: Ed25519 and ECDSA P-256 via SSH-agent and OpenSSH key
|
|
formats. RSA may be accepted only for compatibility and must use SHA-2 signatures.
|
|
- AEAD: ChaCha20-Poly1305 by default; AES-GCM optional when hardware support is known.
|
|
- KDF: HKDF-SHA256.
|
|
- Hash/transcript: SHA-256.
|
|
- Randomness: OS CSPRNG only.
|
|
|
|
Disallowed:
|
|
|
|
- Homegrown ciphers, MACs, padding, or key derivation.
|
|
- Reusing a nonce/key pair.
|
|
- Unauthenticated encryption.
|
|
- MD5/SHA-1 signatures for user auth.
|
|
|
|
## 7. Identity And Trust
|
|
|
|
### Server Identity
|
|
|
|
Each `dosh-server` has a persistent host key:
|
|
|
|
```text
|
|
~/.config/dosh/host_key
|
|
~/.config/dosh/host_key.pub
|
|
```
|
|
|
|
Default host-key algorithm: Ed25519.
|
|
|
|
Client pins host keys in:
|
|
|
|
```text
|
|
~/.config/dosh/known_hosts
|
|
```
|
|
|
|
Entry format:
|
|
|
|
```text
|
|
host-pattern key-type base64-public-key first-seen=unix-seconds source=tofu|ssh|manual
|
|
```
|
|
|
|
First-use policy:
|
|
|
|
- Default for public internet: refuse unknown native host key and suggest
|
|
`dosh trust host` or SSH bootstrap.
|
|
- Default for local/private hosts may be TOFU only when `trust_on_first_use = true`.
|
|
- `dosh trust host` may verify the Dosh host key over the existing SSH bootstrap path.
|
|
|
|
Host-key mismatch:
|
|
|
|
- Hard fail.
|
|
- Print old fingerprint, new fingerprint, and known-hosts file path.
|
|
- Never auto-replace.
|
|
|
|
### User Identity
|
|
|
|
Native auth user identity is the login user resolved from:
|
|
|
|
1. Explicit CLI user: `user@host`.
|
|
2. Dosh host config.
|
|
3. `ssh -G host` `user`.
|
|
4. Local username.
|
|
|
|
Server verifies user keys against:
|
|
|
|
```text
|
|
~/.ssh/authorized_keys
|
|
~/.config/dosh/authorized_keys
|
|
```
|
|
|
|
`~/.config/dosh/authorized_keys` is optional and may restrict Dosh access without
|
|
changing SSH access.
|
|
|
|
Authorized-key options required in v1:
|
|
|
|
- `from=`
|
|
- `command=` must reject native Dosh terminal login unless explicitly supported later.
|
|
- `restrict`
|
|
- `no-port-forwarding`
|
|
- `permitopen=`
|
|
|
|
Unsupported restrictive options must fail closed.
|
|
|
|
## 8. Native Auth Handshake
|
|
|
|
Native auth runs over UDP on the same Dosh port. It establishes a short-lived
|
|
authenticated control channel and returns the same terminal attach material that SSH
|
|
bootstrap returns today.
|
|
|
|
Target path:
|
|
|
|
```text
|
|
client -> server: ClientHello
|
|
server -> client: ServerHello
|
|
client -> server: UserAuth
|
|
server -> client: AuthOk + first terminal snapshot
|
|
```
|
|
|
|
The server may combine `AuthOk` and `AttachOk` to get terminal-ready in the final
|
|
handshake flight.
|
|
|
|
### ClientHello
|
|
|
|
Fields:
|
|
|
|
- protocol version
|
|
- client random
|
|
- client ephemeral X25519 public key
|
|
- requested host alias
|
|
- requested user
|
|
- requested session
|
|
- requested mode
|
|
- terminal size
|
|
- supported AEAD algorithms
|
|
- supported user key algorithms
|
|
- optional cached host-key id
|
|
- optional attach ticket envelope
|
|
|
|
### ServerHello
|
|
|
|
Fields:
|
|
|
|
- protocol version
|
|
- server random
|
|
- server ephemeral X25519 public key
|
|
- server host public key
|
|
- server host-key signature over transcript
|
|
- chosen AEAD
|
|
- server key epoch
|
|
- auth challenge
|
|
- rate-limit metadata when applicable
|
|
|
|
The client must verify the host key before sending user authentication.
|
|
|
|
### UserAuth
|
|
|
|
Fields:
|
|
|
|
- selected public key
|
|
- key algorithm
|
|
- signature over transcript and auth challenge
|
|
- optional agent identity metadata
|
|
- optional requested forwarding declarations
|
|
|
|
The signature must bind:
|
|
|
|
- both ephemeral keys
|
|
- both randoms
|
|
- server host key
|
|
- requested user/session/mode/terminal size
|
|
- selected algorithms
|
|
- protocol version
|
|
|
|
### AuthOk
|
|
|
|
Fields:
|
|
|
|
- assigned `ClientId`
|
|
- session name
|
|
- mode
|
|
- session key id
|
|
- encrypted session key material or derived key confirmation
|
|
- attach ticket
|
|
- attach ticket PSK encrypted to the handshake key
|
|
- initial output sequence
|
|
- first snapshot
|
|
- server policy flags
|
|
|
|
`AuthOk` is AEAD-encrypted under the handshake traffic key.
|
|
|
|
## 9. Key Schedule
|
|
|
|
Handshake transcript:
|
|
|
|
```text
|
|
H = SHA256(protocol_label || ClientHello || ServerHello || UserAuth)
|
|
```
|
|
|
|
Shared secret:
|
|
|
|
```text
|
|
dh = X25519(client_ephemeral, server_ephemeral)
|
|
```
|
|
|
|
Handshake key:
|
|
|
|
```text
|
|
handshake_key = HKDF-SHA256(dh, H, "dosh/native/handshake/v1")
|
|
```
|
|
|
|
Session traffic keys:
|
|
|
|
```text
|
|
c2s_key = HKDF-SHA256(handshake_key, H, "dosh/native/c2s/v1")
|
|
s2c_key = HKDF-SHA256(handshake_key, H, "dosh/native/s2c/v1")
|
|
```
|
|
|
|
Attach ticket PSKs and rotated session keys must be derived independently from server
|
|
secret material and fresh randomness. They must not reuse handshake traffic keys.
|
|
|
|
## 10. Attach Tickets And Cache
|
|
|
|
Native attach tickets replace most cold auth after first login.
|
|
|
|
Ticket properties:
|
|
|
|
- Server-sealed AEAD blob.
|
|
- Scoped to server host key, user, session, mode, client key fingerprint, server key
|
|
epoch, and policy flags.
|
|
- Paired with a client-held random PSK.
|
|
- Default TTL: 24 hours for trusted personal machines, configurable down to zero.
|
|
- Stored mode `0600`.
|
|
- Revoked by server host-key rotation, server secret rotation, or user key removal.
|
|
|
|
Client cache path:
|
|
|
|
```text
|
|
~/.local/share/dosh/credentials/
|
|
```
|
|
|
|
Cache entries must include:
|
|
|
|
- host identity fingerprint
|
|
- user
|
|
- session
|
|
- mode
|
|
- ticket expiry
|
|
- last rendered sequence
|
|
- client id
|
|
- session key id
|
|
- attach ticket
|
|
- attach ticket PSK
|
|
|
|
## 11. Transport
|
|
|
|
Post-auth terminal traffic continues to use the current Dosh UDP packet model:
|
|
|
|
- fixed binary header
|
|
- AEAD body
|
|
- monotonic packet sequence
|
|
- ack field
|
|
- replay window
|
|
- server snapshots for recovery
|
|
|
|
Required v1 changes:
|
|
|
|
- Separate packet namespaces for terminal frames, control messages, and forwarding
|
|
streams.
|
|
- Explicit `key_epoch` or `session_key_id` in packet metadata so stale packets can be
|
|
ignored without fatal decrypt errors.
|
|
- Rekey command after configurable packet count or wall-clock interval.
|
|
- Connection migration must be accepted after any valid encrypted packet from a new
|
|
source address.
|
|
|
|
## 12. Forwarding
|
|
|
|
Native forwarding is a Dosh stream multiplexer over the encrypted transport.
|
|
|
|
CLI:
|
|
|
|
```bash
|
|
dosh -L [bind_host:]listen_port:target_host:target_port host
|
|
dosh -R [bind_host:]listen_port:target_host:target_port host
|
|
dosh -D [bind_host:]listen_port host
|
|
dosh -A host # forward the local ssh-agent (opt-in, server-gated)
|
|
```
|
|
|
|
Stream packet types:
|
|
|
|
- `StreamOpen`
|
|
- `StreamOpenOk`
|
|
- `StreamOpenReject`
|
|
- `StreamData`
|
|
- `StreamWindowAdjust`
|
|
- `StreamEof`
|
|
- `StreamClose`
|
|
|
|
Forwarding rules:
|
|
|
|
- Terminal traffic has priority over stream bulk data.
|
|
- Each stream has independent flow control.
|
|
- Backpressure must not block PTY input or output.
|
|
- Server enforces `no-port-forwarding` and `permitopen=`.
|
|
- Remote listeners bind to loopback by default.
|
|
- Non-loopback remote bind requires explicit config.
|
|
- `-N` opens forwarding without creating a PTY.
|
|
- `-f` backgrounds only after all requested listeners are successfully active.
|
|
- Listener setup failures fail the entire command unless `--partial-forwarding` is
|
|
explicitly requested.
|
|
- Forwarding reconnect must preserve listeners and re-open streams after network
|
|
migration when protocol state allows it.
|
|
- Stream packet scheduling must enforce terminal priority; a large port-forward copy
|
|
cannot make shell keystrokes lag.
|
|
|
|
### 12.1 SSH-Agent Forwarding (opt-in, security-gated)
|
|
|
|
- Activated only on explicit client opt-in (`-A` / `forward_agent = true`) **and**
|
|
server `allow_agent_forwarding = true`. Off by default on both ends.
|
|
- The client requests a `ForwardingKind::Agent` entry during auth. If the server
|
|
policy allows it, the server binds a per-session proxy unix socket in a
|
|
process-private directory (dir 0700, socket 0600) and exports its path as the
|
|
spawned shell's `SSH_AUTH_SOCK`.
|
|
- Each connection from a remote process to that proxy socket is tunneled to the
|
|
client over a server-initiated `StreamOpen` carrying the reserved target sentinel
|
|
`@dosh-agent` (port 0). The client splices it into its local `SSH_AUTH_SOCK`
|
|
(a unix socket, not a TCP target). Data/window/close reuse the existing stream
|
|
packets unchanged.
|
|
- Only applies to a freshly spawned shell; an already-running attached/prewarmed
|
|
session keeps its existing environment (same constraint as ssh/mosh).
|
|
- SECURITY: forwarding exposes the local agent to the remote host for the session's
|
|
lifetime, which is why it is double-gated and never the default.
|
|
|
|
## 13. Diagnostics And Operations
|
|
|
|
Native v1 must include operations commands:
|
|
|
|
```bash
|
|
dosh doctor host
|
|
dosh trust host
|
|
dosh trust --remove host
|
|
dosh sessions host
|
|
dosh update
|
|
```
|
|
|
|
`dosh doctor host` checks:
|
|
|
|
- host alias resolution
|
|
- Dosh known-host state
|
|
- SSH fallback reachability
|
|
- native UDP reachability
|
|
- server version
|
|
- native auth enabled/disabled
|
|
- usable keys from ssh-agent and identity files
|
|
- server authorization result without opening a terminal
|
|
- configured forwarding policy
|
|
|
|
`dosh trust host` checks:
|
|
|
|
- fetch Dosh host key through SSH fallback when available
|
|
- show fingerprint before writing trust
|
|
- refuse overwrite on mismatch unless `--replace` is explicit
|
|
|
|
## 14. Config
|
|
|
|
Client:
|
|
|
|
```toml
|
|
auth_preference = "native,ssh"
|
|
trust_on_first_use = false
|
|
native_auth_timeout_ms = 700
|
|
known_hosts = "~/.config/dosh/known_hosts"
|
|
credential_cache = "~/.local/share/dosh/credentials"
|
|
identity_files = ["~/.ssh/id_ed25519"]
|
|
use_ssh_agent = true
|
|
forward_agent = false
|
|
send_env = ["LANG", "LC_*", "TERM", "COLORTERM"]
|
|
set_env = {}
|
|
forwardings = []
|
|
```
|
|
|
|
Server:
|
|
|
|
```toml
|
|
native_auth = true
|
|
host_key = "~/.config/dosh/host_key"
|
|
authorized_keys = ["~/.ssh/authorized_keys", "~/.config/dosh/authorized_keys"]
|
|
native_auth_rate_limit_per_minute = 30
|
|
attach_ticket_ttl_secs = 86400
|
|
allow_tcp_forwarding = true
|
|
allow_remote_forwarding = false
|
|
allow_remote_non_loopback_bind = false
|
|
allow_agent_forwarding = false
|
|
accept_env = ["LANG", "LC_*", "TERM", "COLORTERM"]
|
|
```
|
|
|
|
## 15. Migration Plan
|
|
|
|
Milestone 1: host identity and trust
|
|
|
|
- Generate Dosh host key on server install.
|
|
- Add `dosh trust host`.
|
|
- Add known-hosts file and mismatch handling.
|
|
- Keep SSH bootstrap as the only auth path.
|
|
|
|
Milestone 2: native user auth
|
|
|
|
- Implement `ClientHello`/`ServerHello`/`UserAuth`/`AuthOk`.
|
|
- Support ssh-agent Ed25519 first.
|
|
- Verify against `authorized_keys`.
|
|
- Add `--auth=native|ssh|auto`.
|
|
|
|
Milestone 3: default native auth
|
|
|
|
- Make `auth_preference = "native,ssh"` default.
|
|
- Keep SSH fallback explicit and visible.
|
|
- Add benchmark gates for native cold auth.
|
|
|
|
Milestone 4: forwarding
|
|
|
|
- Add stream mux.
|
|
- Add `-L`, `-N`, and `-f`.
|
|
- Add `-R`.
|
|
- Add `-D` only after flow control is proven.
|
|
|
|
Milestone 5: hardening
|
|
|
|
- Fuzz packet parsing, authorized-key parsing, known-host parsing, and handshake state.
|
|
- Add hostile-network integration tests.
|
|
- Add external review checklist before public security claims.
|
|
|
|
Milestone 6: workflow parity
|
|
|
|
- Implement `dosh doctor`.
|
|
- Implement complete host-trust management.
|
|
- Implement private-key prompt flow.
|
|
- Implement forwarding policy diagnostics.
|
|
- Run daily-driver soak on macOS and Linux clients.
|
|
|
|
## 16. Verification
|
|
|
|
Native v1 is not complete until all are true:
|
|
|
|
- Unknown host key fails by default unless TOFU is explicitly enabled.
|
|
- Known host key mismatch hard fails.
|
|
- Native Ed25519 auth succeeds via ssh-agent.
|
|
- Native Ed25519 auth succeeds via encrypted private key prompt.
|
|
- Removed authorized key can no longer authenticate.
|
|
- Restrictive unsupported authorized-key options fail closed.
|
|
- Replayed handshake packets are rejected.
|
|
- Replayed transport packets are rejected.
|
|
- Stale encrypted packets after reconnect are ignored, not fatal.
|
|
- Client IP/port change preserves the session.
|
|
- Native cold auth benchmark beats cold `ssh host true` on the same host.
|
|
- Cached attach remains near network RTT plus local render overhead.
|
|
- `-L` forwarding works without delaying terminal input.
|
|
- `-R` forwarding enforces bind and permission policy.
|
|
- `-N -L` forward-only mode does not allocate a PTY.
|
|
- `-f -N -L` backgrounds only after listener readiness.
|
|
- Multiple forwards in one command work.
|
|
- `dosh doctor` identifies UDP-blocked, auth-denied, host-key-mismatch, and
|
|
forwarding-denied states.
|
|
- Closing the laptop for at least 30 minutes does not kill the remote session.
|
|
- Three concurrent Dosh terminals remain independent unless explicitly named.
|
|
- Large forwarded transfers do not add visible terminal input lag.
|
|
- Fuzz targets run in CI.
|
|
- Threat model is updated with any accepted residual risks.
|
|
|
|
## 17. Public Claim Gate
|
|
|
|
Dosh may claim "native SSH replacement for Dosh-installed servers" only after:
|
|
|
|
- Native auth is default on at least one real host.
|
|
- SSH fallback remains available.
|
|
- The verification checklist is green.
|
|
- The threat model is published.
|
|
- Benchmarks include raw samples for SSH cold, Dosh native cold, Dosh cached attach,
|
|
and Mosh startup.
|
|
|
|
Dosh must not claim generic SSH compatibility unless it implements the SSH protocol.
|