OxiSH: a modern, memory-safe SSH server – Dirkjan Ochtman
I'm happy to announce OxiSH, a modern, memory-safe SSH server<br>that I've been working on for 20 months. OxiSH is written in Rust, with a safe<br>sans-I/O protocol core and an abstraction for the underlying<br>cryptography primitives.
Why?
Many large organizations have shown that up to 70% of security vulnerabilities in software written in C and C++<br>happen due to memory safety issues (Microsoft,<br>Google). In the US,<br>government agencies have been advocating<br>for the use of memory-safe programming languages for a few years now. The Prossimo project<br>lists three risk criteria to help prioritize where memory safety is most important:
Very widely used (nearly every server and/or client)
On a security boundary
Performing a critical function
SSH servers meet all three of these criteria.
OpenSSH is the predominant implementation; it's written in C and has<br>been around for decades. It continues to suffer from memory safety issues to this day. I started<br>OxiSH because I think it's worth investing in a memory-safe alternative.
What's been done?
Before starting on OxiSH, I spent some time looking for existing SSH implementations in Rust that<br>could help me bring this idea to life sooner. In particular, I looked at russh<br>which seems to be fairly popular. However, I noticed that it implements some old crypto primitives<br>and seems to have a fairly monolithic design, so I decided to start from scratch instead.
Although I could keep working on OxiSH in (semi-) stealth mode, I think it's now in a<br>good enough state to announce publicly. That does not mean it is ready for production usage, and<br>there are a bunch of limitations (see below). This is a starting point, looking for feedback and<br>contributions from other folks; I will soon start dogfooding this on my own server as well.
I have a Tokio-based async networking server with a sans-I/O SSH protocol core, public key<br>authentication support (with Ed25519 and ECDSA P-256 keys only), and a basic shell implementation<br>that can spawn a child process and connect it to the SSH session. It gets tested on Linux and macOS<br>against OpenSSH clients in CI. Windows support would be<br>nice but will require someone else to step in. There is no client implementation yet, and I currently<br>don't have plans to work on that, but the sans-I/O core could well be used to enable it. Beyond the<br>low-level sans-I/O API, there's also a (currently small) library API to enable reuse.
Cryptographic primitives are implemented with two different backends, graviola and aws-lc-rs.<br>Cargo features can be used to select which backend is used at compile time; graviola, the default,<br>is easier to build but only works on x86-64 and ARM64, while aws-lc-rs is more portable, should<br>be slightly more efficient, and can be compiled in FIPS mode on Linux. It implements hybrid<br>post-quantum key exchange using the mlkem768x25519-sha256 algorithm, and curve25519-sha256<br>is supported for key exchange as a fallback algorithm for older clients. Ed25519 and<br>ecdsa-sha2-nistp256 are the only supported public key algorithms, AES-128-GCM is the only<br>supported encryption algorithm and SHA-256 is the only supported hash algorithm. It should be<br>fairly easy to add other algorithms that are supported by the underlying backends, but I'd like<br>to keep the set as small as possible to reduce attack surface.
I have made an effort to review historic OpenSSH vulnerabilities to make sure both the design and<br>implementation of OxiSH avoid similar mistakes outside the memory-safety realm. I would like to pay<br>for an external audit of the codebase in the future, but I'm unlikely to be able to fund that work myself.
Here are some of the more obvious missing features:
No agent forwarding, let alone other kinds of forwarding
No scp or sftp support
No password authentication
Full feature (or even bug for bug compatibility) with OpenSSH is explicitly not a goal of this project,<br>but I'd like to hear more about what people would need to see to replace OpenSSH in their environment.<br>Please file an issue!
Who have been involved?
I wrote most of the code, and I have reviewed all of it in great detail. I have more than<br>10 years of experience writing Rust code, and have been maintaining some popular network protocol<br>projects for the last few years, including:
rustls, a widely used TLS library in Rust
Quinn, a popular implementation of the QUIC protocol in Rust
Hickory DNS, a DNS implementation in Rust
For a few weeks earlier this year, I was fortunate to get help from the fine folks at the Trifecta<br>Tech Foundation, who were able to get an investment from the Sovereign<br>Tech Agency to help figure out some of the core platform interactions<br>in the server, including an initial draft of privilege separation and terminal handling. We hope<br>to continue our collaboratation on this project in the future.
Where to from here?
As mentioned above, this is just a starting point. Please leave feedback<br>and/or contribute...