docs/sdk/rust/ssh.mdx
Reach a running sandbox over SSH: open a native in-process SSH client, run exec requests, attach an interactive shell, transfer files over SFTP, or stand up a reusable SSH server endpoint. Requires the ssh feature. See SSH for usage flows.
microsandbox = { version = "0.5.8", features = ["ssh"] }
fn ssh(&self) -> SandboxSshOps
let client = sb.ssh().connect().await?;
Return the SSH namespace for this sandbox. The namespace holds the SSH client and server helpers; nothing connects until you call connect or server.
SSH operations for a sandbox.
async fn connect(&self) -> MicrosandboxResult<SshClient>
let client = sb.ssh().connect().await?;
let out = client.exec("uname -a").await?;
Connect a native in-process SSH client to this sandbox. Generates an ephemeral Ed25519 client and host key pair, stands up an internal server bound to a duplex stream, and authenticates over public key. Uses default client options (user root, terminal from $TERM, SFTP enabled).
async fn open_client(&self) -> MicrosandboxResult<SshClient>
Alias for connect.
async fn connect_with(
&self,
f: impl FnOnce(SshClientOptionsBuilder) -> SshClientOptionsBuilder,
) -> MicrosandboxResult<SshClient>
let client = sb.ssh().connect_with(|opts| opts
.user("app")
.term("xterm-256color")).await?;
Connect a native in-process SSH client with custom options. The closure configures the login user, terminal name, and whether SFTP is enabled on the internal server.
<p className="msb-label">Parameters</p> <div className="msb-params"> <div className="msb-param"> <div className="msb-param-key"><code>f</code><a className="msb-type" href="#sshclientoptionsbuilder">FnOnce(SshClientOptionsBuilder)</a></div> <div className="msb-param-desc">Configure user, terminal, and SFTP support.</div> </div> </div> <p className="msb-label">Returns</p> <div className="msb-params"> <div className="msb-param"> <div className="msb-param-key"><a className="msb-type" href="#sshclient">SshClient</a></div> <div className="msb-param-desc">Connected SSH client session.</div> </div> </div>async fn open_client_with(
&self,
f: impl FnOnce(SshClientOptionsBuilder) -> SshClientOptionsBuilder,
) -> MicrosandboxResult<SshClient>
Alias for connect_with.
<Tooltip tip="Serving with the convenience defaults is not available on microsandbox cloud; supply explicit host-key and authorized-key material, or use the SSH client."><span className="msb-badge-local">Local-only <Icon icon="circle-info" size={11} /></span></Tooltip>
async fn server(&self) -> MicrosandboxResult<SshServer>
let server = sb.ssh().server().await?;
let (client_io, server_io) = tokio::io::duplex(64 * 1024);
server.serve(server_io).await?;
Prepare a reusable SSH server endpoint for this sandbox. Loads or creates the host key and resolves authorized keys from the default authorized-keys file. The returned SshServer is cloneable and can serve many connections.
<Tooltip tip="Serving with the convenience defaults is not available on microsandbox cloud; supply explicit host-key and authorized-key material, or use the SSH client."><span className="msb-badge-local">Local-only <Icon icon="circle-info" size={11} /></span></Tooltip>
async fn prepare_server(&self) -> MicrosandboxResult<SshServer>
Alias for server.
<Tooltip tip="On microsandbox cloud, serving works when you supply explicit host-key and authorized-key material; the convenience defaults are local-only."><span className="msb-badge-limited">Limited on cloud <Icon icon="circle-info" size={11} /></span></Tooltip>
async fn server_with(
&self,
f: impl FnOnce(SshServerOptionsBuilder) -> SshServerOptionsBuilder,
) -> MicrosandboxResult<SshServer>
let server = sb.ssh().server_with(|opts| opts
.authorized_key("ssh-ed25519 AAAAC3Nza...")
.user("app")
.sftp(false)).await?;
Prepare a server endpoint with custom host-key, authorization, guest-user, or SFTP options. If no authorized keys are configured, the default authorized-keys file is loaded; an empty key set is an error.
<p className="msb-label">Parameters</p> <div className="msb-params"> <div className="msb-param"> <div className="msb-param-key"><code>f</code><a className="msb-type" href="#sshserveroptionsbuilder">FnOnce(SshServerOptionsBuilder)</a></div> <div className="msb-param-desc">Configure host key, authorized keys, guest user, and SFTP.</div> </div> </div> <p className="msb-label">Returns</p> <div className="msb-params"> <div className="msb-param"> <div className="msb-param-key"><a className="msb-type" href="#sshserver">SshServer</a></div> <div className="msb-param-desc">Reusable SSH server endpoint.</div> </div> </div><Tooltip tip="On microsandbox cloud, serving works when you supply explicit host-key and authorized-key material; the convenience defaults are local-only."><span className="msb-badge-limited">Limited on cloud <Icon icon="circle-info" size={11} /></span></Tooltip>
async fn prepare_server_with(
&self,
f: impl FnOnce(SshServerOptionsBuilder) -> SshServerOptionsBuilder,
) -> MicrosandboxResult<SshServer>
Alias for server_with.
Native in-process SSH client session.
async fn exec(&self, command: impl Into<String>) -> MicrosandboxResult<SshOutput>
let out = client.exec("echo hello").await?;
println!("exit {}: {}", out.status, String::from_utf8_lossy(&out.stdout));
Run an SSH exec request and collect stdout, stderr, and the exit status. The command is run through the sandbox's configured shell (default /bin/sh -c). No PTY is requested.
async fn exec_with(
&self,
command: impl Into<String>,
f: impl FnOnce(SshExecOptionsBuilder) -> SshExecOptionsBuilder,
) -> MicrosandboxResult<SshOutput>
let out = client.exec_with("top -bn1", |opts| opts.tty(true)).await?;
Run an SSH exec request with options. The closure can request a PTY via tty; when a PTY is allocated, stderr is folded into stdout.
async fn attach(&self) -> MicrosandboxResult<i32>
let code = client.attach().await?;
println!("shell exited with {code}");
Attach the local terminal to an interactive SSH shell. Requests a PTY sized to the current terminal, puts the terminal into raw mode, forwards keystrokes, relays window-resize events, and returns when the shell exits or the default detach key sequence is typed.
<p className="msb-label">Returns</p> <div className="msb-params"> <div className="msb-param"> <div className="msb-param-key"><span className="msb-type">i32</span></div> <div className="msb-param-desc">Shell exit code (128 if terminated by signal).</div> </div> </div>async fn attach_with(
&self,
f: impl FnOnce(SshAttachOptionsBuilder) -> SshAttachOptionsBuilder,
) -> MicrosandboxResult<i32>
let code = client.attach_with(|opts| opts
.term("xterm-256color")
.detach_keys("ctrl-p,ctrl-q")).await?;
Attach an interactive shell with custom terminal and detach-key options.
<p className="msb-label">Parameters</p> <div className="msb-params"> <div className="msb-param"> <div className="msb-param-key"><code>f</code><a className="msb-type" href="#sshattachoptionsbuilder">FnOnce(SshAttachOptionsBuilder)</a></div> <div className="msb-param-desc">Configure terminal name and detach keys.</div> </div> </div> <p className="msb-label">Returns</p> <div className="msb-params"> <div className="msb-param"> <div className="msb-param-key"><span className="msb-type">i32</span></div> <div className="msb-param-desc">Shell exit code (128 if terminated by signal).</div> </div> </div>async fn sftp(&self) -> MicrosandboxResult<SftpClient>
let sftp = client.sftp().await?;
let mut file = sftp.create("/tmp/hello.txt").await?;
Open an SFTP client session over this SSH connection. Requests the sftp subsystem and returns a high-level SFTP session for reading, writing, and listing files inside the guest.
async fn close(self) -> MicrosandboxResult<()>
client.close().await?;
Close this native SSH client session. Sends a disconnect and aborts the internal server task. Consumes the client.
Reusable SSH server endpoint for a sandbox.
async fn serve<S>(&self, stream: S) -> MicrosandboxResult<()>
where
S: AsyncRead + AsyncWrite + Unpin + Send + 'static,
let server = sb.ssh().server().await?;
let (client_io, server_io) = tokio::io::duplex(64 * 1024);
tokio::spawn(async move { server.serve(server_io).await });
Serve one SSH connection over an ordered duplex stream. Runs the SSH handshake and session loop to completion. Returns when the connection closes.
<p className="msb-label">Parameters</p> <div className="msb-params"> <div className="msb-param"> <div className="msb-param-key"><code>stream</code><span className="msb-type">S: AsyncRead + AsyncWrite</span></div> <div className="msb-param-desc">Ordered duplex SSH transport.</div> </div> </div>async fn serve_connection<S>(&self, stream: S) -> MicrosandboxResult<()>
where
S: AsyncRead + AsyncWrite + Unpin + Send + 'static,
Alias for serve.
Ordered duplex stream backed by this process's stdin and stdout. Implements AsyncRead and AsyncWrite.
fn new() -> Self
use microsandbox::SshStdioStream;
let server = sb.ssh().server().await?;
server.serve(SshStdioStream::new()).await?;
Create a stdio SSH transport stream backed by this process's stdin and stdout. Implements AsyncRead and AsyncWrite, so it can be passed straight to serve to bridge an SSH connection over the parent process's standard streams. Also available via Default.
pub const DEFAULT_SSH_HOST: &str = "127.0.0.1";
Default SSH listener host used by the CLI adapter when binding a sandbox SSH endpoint.
pub const DEFAULT_SSH_PORT: u16 = 2222;
Default SSH listener port used by the CLI adapter when binding a sandbox SSH endpoint.
Builder for SSH client options. Defaults: user root, terminal from $TERM (falling back to xterm), SFTP enabled.
user()
SSH login user. Default root.
term()
Terminal name for interactive sessions.
sftp()
Enable or disable SFTP on the internal server. Default true.
build()
Finalize the options.
Builder for SSH exec options.
tty()
Request a PTY for the exec channel. Default false.
build()
Finalize the options.
Builder for interactive SSH attach options. Default terminal comes from $TERM (falling back to xterm); detach keys default to the standard sequence.
term()
Terminal name for the shell.
detach_keys()
Detach key sequence.
build()
Finalize the options.
Builder for SSH server options. SFTP is enabled by default; when no authorized keys are provided, the default authorized-keys file is loaded.
host_key_path()
Override the host private key path.
host_key()
Use an in-memory host private key.
authorized_keys_path()
Override the authorized-keys path.
authorized_key()
Add one in-memory authorized public key.
user()
Override the guest user used for exec requests.
sftp()
Enable or disable SFTP. Default true.
build()
Finalize the options.
High-level SFTP client session.
pub type SftpClient = russh_sftp::client::SftpSession;
Output from an SSH exec request.
| Field | Type | Description |
|---|---|---|
status | i32 | Exit status code. |
stdout | Bytes | Captured stdout bytes. |
stderr | Bytes | Captured stderr bytes (folded into stdout when a PTY is allocated). |