Eugeny/russh

Add support for WebAssembler WASI target

Opened this issue · 3 comments

As the title says, it would be nice to be able to compile russh for the WASI target (i.e. to WASM32 and run it afterwards via wasmtime or wasmer).

What would be the use-case for WASI:

  • first of all, one could write special purpose SSH servers that use one-process-per-client and use stdin/stdout for communication; these are spawned by something like inetd (or systemd via socket activation) and then run via a WASI runtime; thus the whole SSH server is sandboxed and only has access to what the user allows; (think about implementing some TUI games that the user connects via SSH;)
  • second, one can use the client to connect to untrusted servers, and have the SSH code sandboxed inside the WASM runtime;

Now, if such a feature would be accepted, I've already patched the russh code as per, and I could open a pull request:

cipriancraciun/russh@upstream...patches/wasi

The changes are quite minimal in places, and a bit more involved for russh-config, namely:

  • for the moment the upstream tokio runtime doesn't support the net feature for the wasi target; only for the target_os="wasi" I instruct cargo to use the tokio_wasi crate (already in Crates, and maintained by https://github.com/WasmEdge); (once tokio would support the net feature, then this patch can be reverted;)
  • for russh-config the patch is more involved as it has to remove (conditionally based on #[cfg]) the support for ProxyCommand for wasi (WASI doesn't yet support process spawning);
  • russh-cryptovec is patched to have "NOP" implementation for mlock / munlock, operations that are not supported by WASI.

Outside of these changes, nothing else needs to be touched.

Hey, this looks good and I'd be happy to merge! Could you also include a small example with build & runtime instructions as well?

Sure, I can add some minimal documentation, but where should this be added? (The README doesn't seem the right place.)

However, please note that there isn't anything specific to supporting WASM WASI (for someone using russh as a dependency), as one can only run cargo build --target wasm32-wasi and that's it. The resulting binary can then be run with either wasmtime or wasmer as simple as wasmtime run ./target/debug/my-tool.wasm.

(I'll try to see if perhaps one of the server examples can't be easily run via WASM WASI.)


BTW, the diff I mentioned earlier only actually adds support for "building" russh on the WASM target. To actually have it do useful stuff, I would like to submit some additional patches (as a different issue / pull request) that add support for interacting with the server / client / agent over stdio instead of TCP or UNIX sockets. (Because UNIX sockets aren't supported by WASI, and for full sandboxing and security TCP isn't advisable.)

Sorry, I just have limited experience with WebAssembly and even less with WASI. If the existing echoserver example can be directly compiled and run with wasmtime, then I think there's nothing to document :) (IIRC networking used to be just a draft spec in WASI)