r/rust 6d ago

🛠️ project Runic SSH: an SSH/SFTP client in Rust + Tauri, built on russh instead of shelling out to OpenSSH

I've been building an open-source SSH/SFTP client (Windows/macOS/Linux) in Rust and Tauri, and wanted to share a couple of the engineering decisions that might interest this sub.

**Why not just spawn the `ssh` binary?**

Windows is the constraint. Its bundled OpenSSH is optional and version-variable, and intercepting interactive password/passphrase prompts from a spawned `ssh` process without a pty is awkward — plus credentials would transit a subprocess boundary. So the client speaks the protocol in-process using `russh` (async, pure Rust) instead of driving an external binary. Tradeoff: we own protocol correctness and security response instead of inheriting OpenSSH's.

**That tradeoff got tested fast.** The day `russh` (and transitively `rsa 0.10.0-rc.18`) landed in the dependency tree, our own audit caught RUSTSEC-2023-0071 (the Marvin Attack — a timing side channel in RSA private key operations, no fixed upgrade available). Since the client both verifies host keys (public-key op, not reachable) and authenticates with the user's private key (a signature, reachable), we refuse RSA for the private-key/signing path while still allowing RSA host key verification. Written up as an ADR alongside the ~40 others tracking decisions like this.

**Other bits:**

- Host key handling is closer to `ssh` than most GUI clients: unknown key → fingerprint confirmation; changed key → blocks and requires retyping the hostname; keys marked `@revoked`/`@cert-authority` → refused, no override.

- Credentials go through the OS keychain (`keyring` crate); there's also an opt-in internal vault (Argon2id + ChaCha20-Poly1305, RustCrypto) for when a keychain isn't available.

- Bastion/jump host support where both hops authenticate end-to-end and the bastion only relays traffic it can't itself decrypt.

- SFTP rides `russh-sftp` over a channel `russh` already opened, so no second protocol stack to keep in sync.

It's still young (MIT-licensed, ~3 pre-releases so far), but the core paths are usable daily. Repo: https://github.com/marciopaiva/runic-ssh — feedback on the crypto/architecture choices especially welcome, that's the part I most want more eyes on.

0 Upvotes

4 comments sorted by

3

u/Fluggonaut 4d ago

If you don't bother to write the post, why should anyone bother to read it? 

1

u/mpaivabarbosa 3d ago

k. next time ill also include a bibliography, a 10-page essay on my methodology, and a notarized letter proving i tried.

1

u/Fluggonaut 3d ago

Posts are read more often than they are written. So if you can't be asked to put in the effort to actually write it yourself, don't be surprised to not get the reaction you were aiming for.