Back to Microsandbox

SSH

docs/sdk/go/ssh.mdx

0.6.1018.1 KB
Original Source

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. See SSH for usage flows.

Sandbox

<span className="msb-recv">sb.</span><span className="msb-hn">SSH()</span>

go
func (s *Sandbox) SSH() *SandboxSSHOps
<Accordion title="Example">
go
ssh := sb.SSH()
client, err := ssh.OpenClient(ctx)
</Accordion>

Return the SSH operations namespace for this sandbox. The namespace groups the client and server helpers; it holds no resources of its own.

<p className="msb-label">Returns</p> <div className="msb-params"> <div className="msb-param"> <div className="msb-param-key"><a className="msb-type" href="#sandboxsshops">*SandboxSSHOps</a></div> <div className="msb-param-desc">SSH client and server helpers for this sandbox.</div> </div> </div>

SandboxSSHOps

<p className="msb-backref">Returned by <a href="#sb-ssh">SSH()</a></p>

SSH operations namespace for a sandbox. Obtained via sb.SSH(). Holds no resources; it groups the client and server entry points.

<span className="msb-recv">ssh.</span><span className="msb-hn">OpenClient()</span>

go
func (ssh *SandboxSSHOps) OpenClient(ctx context.Context, opts ...SSHClientOption) (*SSHClient, error)
<Accordion title="Example">
go
client, err := sb.SSH().OpenClient(ctx,
    m.WithSSHUser("app"),
    m.WithSSHTerm("xterm-256color"),
)
if err != nil {
    return err
}
defer client.Close(ctx)
</Accordion>

Open 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. With no options it uses login user root, terminal from $TERM (falling back to xterm), and SFTP enabled.

<p className="msb-label">Parameters</p> <div className="msb-params"> <div className="msb-param"> <div className="msb-param-key"><code>ctx</code><span className="msb-type">context.Context</span></div> <div className="msb-param-desc">Cancels the connection attempt.</div> </div> <div className="msb-param"> <div className="msb-param-key"><code>opts</code><a className="msb-type" href="#sshclientoption">...SSHClientOption</a></div> <div className="msb-param-desc">Login user, terminal name, SFTP toggle, and inactivity timeout.</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">Native SSH client session.</div> </div> <div className="msb-param"> <div className="msb-param-key"><span className="msb-type">error</span></div> <div className="msb-param-desc">Typed microsandbox error.</div> </div> </div>

<span className="msb-recv">ssh.</span><span className="msb-hn">PrepareServer()</span>

<Tooltip tip="On microsandbox cloud, the reusable server 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>

go
func (ssh *SandboxSSHOps) PrepareServer(ctx context.Context, opts ...SSHServerOption) (*SSHServer, error)
<Accordion title="Example">
go
srv, err := sb.SSH().PrepareServer(ctx,
    m.WithSSHAuthorizedKeysPath("/etc/msb/authorized_keys"),
)
if err != nil {
    return err
}
defer srv.Close(ctx)
</Accordion>

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 unless overridden. The returned SSHServer can serve connections one at a time over the process's standard streams.

<p className="msb-label">Parameters</p> <div className="msb-params"> <div className="msb-param"> <div className="msb-param-key"><code>ctx</code><span className="msb-type">context.Context</span></div> <div className="msb-param-desc">Cancels server preparation.</div> </div> <div className="msb-param"> <div className="msb-param-key"><code>opts</code><a className="msb-type" href="#sshserveroption">...SSHServerOption</a></div> <div className="msb-param-desc">Host key, authorized keys, guest user, SFTP toggle, and inactivity timeout.</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">Prepared server endpoint.</div> </div> <div className="msb-param"> <div className="msb-param-key"><span className="msb-type">error</span></div> <div className="msb-param-desc">Typed microsandbox error.</div> </div> </div>

SSHClient

<p className="msb-backref">Returned by <a href="#ssh-openclient">OpenClient()</a></p>

A native in-process SSH client session. Obtained via OpenClient().

<span className="msb-recv">c.</span><span className="msb-hn">Exec()</span>

go
func (c *SSHClient) Exec(ctx context.Context, command string, opts ...SSHExecOption) (*SSHOutput, error)
<Accordion title="Example">
go
out, err := client.Exec(ctx, "python -V")
if err != nil {
    return err
}
if !out.Success() {
    return fmt.Errorf("exit %d: %s", out.Status, out.Stderr)
}
fmt.Printf("%s", out.Stdout)
</Accordion>

Run an SSH exec request and collect stdout, stderr, and the exit status. The command is run through the sandbox's configured shell. No PTY is requested unless WithSSHTTY is passed.

<p className="msb-label">Parameters</p> <div className="msb-params"> <div className="msb-param"> <div className="msb-param-key"><code>ctx</code><span className="msb-type">context.Context</span></div> <div className="msb-param-desc">Cancels the exec request.</div> </div> <div className="msb-param"> <div className="msb-param-key"><code>command</code><span className="msb-type">string</span></div> <div className="msb-param-desc">Command string sent through SSH.</div> </div> <div className="msb-param"> <div className="msb-param-key"><code>opts</code><a className="msb-type" href="#sshexecoption">...SSHExecOption</a></div> <div className="msb-param-desc">PTY toggle for the exec channel.</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="#sshoutput">*SSHOutput</a></div> <div className="msb-param-desc">Captured stdout, stderr, and exit status.</div> </div> <div className="msb-param"> <div className="msb-param-key"><span className="msb-type">error</span></div> <div className="msb-param-desc">Typed microsandbox error.</div> </div> </div>

<span className="msb-recv">c.</span><span className="msb-hn">Attach()</span>

go
func (c *SSHClient) Attach(ctx context.Context, opts ...SSHAttachOption) (int, error)
<Accordion title="Example">
go
code, err := client.Attach(ctx,
    m.WithSSHAttachTerm("xterm-256color"),
    m.WithSSHDetachKeys("ctrl-p,ctrl-q"),
)
if err != nil {
    return err
}
fmt.Printf("shell exited with %d\n", code)
</Accordion>

Bridge 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 detach key sequence is typed.

<p className="msb-label">Parameters</p> <div className="msb-params"> <div className="msb-param"> <div className="msb-param-key"><code>ctx</code><span className="msb-type">context.Context</span></div> <div className="msb-param-desc">Cancels the attach session.</div> </div> <div className="msb-param"> <div className="msb-param-key"><code>opts</code><a className="msb-type" href="#sshattachoption">...SSHAttachOption</a></div> <div className="msb-param-desc">Terminal name and detach key sequence.</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">int</span></div> <div className="msb-param-desc">Shell exit code (128 if terminated by signal).</div> </div> <div className="msb-param"> <div className="msb-param-key"><span className="msb-type">error</span></div> <div className="msb-param-desc">Typed microsandbox error.</div> </div> </div>

<span className="msb-recv">c.</span><span className="msb-hn">SFTP()</span>

go
func (c *SSHClient) SFTP(ctx context.Context) (*SFTPClient, error)
<Accordion title="Example">
go
sftp, err := client.SFTP(ctx)
if err != nil {
    return err
}
defer sftp.Close(ctx)

if err := sftp.Write(ctx, "/tmp/hello.txt", []byte("hi")); err != nil {
    return err
}
</Accordion>

Open an SFTP session over this SSH connection. Returns a high-level SFTP client for reading, writing, and managing files inside the guest. Requires SFTP enabled on the client (the default).

<p className="msb-label">Parameters</p> <div className="msb-params"> <div className="msb-param"> <div className="msb-param-key"><code>ctx</code><span className="msb-type">context.Context</span></div> <div className="msb-param-desc">Cancels opening the SFTP session.</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="#sftpclient">*SFTPClient</a></div> <div className="msb-param-desc">SFTP client session.</div> </div> <div className="msb-param"> <div className="msb-param-key"><span className="msb-type">error</span></div> <div className="msb-param-desc">Typed microsandbox error.</div> </div> </div>

<span className="msb-recv">c.</span><span className="msb-hn">Close()</span>

go
func (c *SSHClient) Close(ctx context.Context) error
<Accordion title="Example">
go
defer client.Close(ctx)
</Accordion>

Close this SSH client session. The handle is consumed; do not use it after closing.

<p className="msb-label">Parameters</p> <div className="msb-params"> <div className="msb-param"> <div className="msb-param-key"><code>ctx</code><span className="msb-type">context.Context</span></div> <div className="msb-param-desc">Cancels the close.</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">error</span></div> <div className="msb-param-desc">Typed microsandbox error.</div> </div> </div>

SSHServer

<p className="msb-backref">Returned by <a href="#ssh-prepareserver">PrepareServer()</a></p>

A prepared SSH server endpoint for a sandbox. Obtained via PrepareServer().

<span className="msb-recv">srv.</span><span className="msb-hn">ServeConnection()</span>

go
func (srv *SSHServer) ServeConnection(ctx context.Context) error
<Accordion title="Example">
go
srv, err := sb.SSH().PrepareServer(ctx)
if err != nil {
    return err
}
defer srv.Close(ctx)

if err := srv.ServeConnection(ctx); err != nil {
    return err
}
</Accordion>

Serve one SSH transport over this process's stdin and stdout. Returns when the connection ends. Call again on the same SSHServer to serve another connection.

<p className="msb-label">Parameters</p> <div className="msb-params"> <div className="msb-param"> <div className="msb-param-key"><code>ctx</code><span className="msb-type">context.Context</span></div> <div className="msb-param-desc">Cancels serving the connection.</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">error</span></div> <div className="msb-param-desc">Typed microsandbox error.</div> </div> </div>

<span className="msb-recv">srv.</span><span className="msb-hn">Close()</span>

go
func (srv *SSHServer) Close(ctx context.Context) error
<Accordion title="Example">
go
defer srv.Close(ctx)
</Accordion>

Release this prepared server endpoint. The handle is consumed; do not use it after closing.

<p className="msb-label">Parameters</p> <div className="msb-params"> <div className="msb-param"> <div className="msb-param-key"><code>ctx</code><span className="msb-type">context.Context</span></div> <div className="msb-param-desc">Cancels the close.</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">error</span></div> <div className="msb-param-desc">Typed microsandbox error.</div> </div> </div>

SSHOutput

<p className="msb-backref">Returned by <a href="#c-exec">Exec()</a></p>

The output from an SSH exec request.

<span className="msb-recv">o.</span><span className="msb-hn">Status</span>

int

Exit status code

<span className="msb-recv">o.</span><span className="msb-hn">Stdout</span>

[]byte

Captured stdout bytes

<span className="msb-recv">o.</span><span className="msb-hn">Stderr</span>

[]byte

Captured stderr bytes

<span className="msb-recv">o.</span><span className="msb-hn">Success()</span>

go
func (o SSHOutput) Success() bool
<Accordion title="Example">
go
out, err := client.Exec(ctx, "test -f /etc/passwd")
if err != nil {
    return err
}
fmt.Println("present:", out.Success())
</Accordion>

Report whether the command exited with status 0.

<p className="msb-label">Returns</p> <div className="msb-params"> <div className="msb-param"> <div className="msb-param-key"><span className="msb-type">bool</span></div> <div className="msb-param-desc"><code>true</code> when <code>Status</code> is <code>0</code>.</div> </div> </div>

SFTPClient

<p className="msb-backref">Returned by <a href="#c-sftp">SFTP()</a></p>

A high-level SFTP client session over an SSH connection. Obtained via SFTP().

<span className="msb-recv">sftp.</span><span className="msb-hn">Read()</span>

go
Read(ctx, path)

Read a file into memory

<p className="msb-label">Returns</p>

([]byte, error)

<span className="msb-recv">sftp.</span><span className="msb-hn">Write()</span>

go
Write(ctx, path, data)

Write a file, creating or truncating it

<p className="msb-label">Returns</p>

error

<span className="msb-recv">sftp.</span><span className="msb-hn">Mkdir()</span>

go
Mkdir(ctx, path)

Create a directory

<p className="msb-label">Returns</p>

error

<span className="msb-recv">sftp.</span><span className="msb-hn">RemoveFile()</span>

go
RemoveFile(ctx, path)

Remove a file

<p className="msb-label">Returns</p>

error

<span className="msb-recv">sftp.</span><span className="msb-hn">RemoveDir()</span>

go
RemoveDir(ctx, path)

Remove an empty directory

<p className="msb-label">Returns</p>

error

<span className="msb-recv">sftp.</span><span className="msb-hn">Rename()</span>

go
Rename(ctx, oldPath, newPath)

Rename a file or directory

<p className="msb-label">Returns</p>

error

<span className="msb-recv">sftp.</span><span className="msb-hn">RealPath()</span>

go
RealPath(ctx, path)

Resolve a path to its canonical absolute form

<p className="msb-label">Returns</p>

(string, error)

<span className="msb-recv">sftp.</span><span className="msb-hn">ReadLink()</span>

go
ReadLink(ctx, path)

Read a symlink target

<p className="msb-label">Returns</p>

(string, error)

<span className="msb-recv">sftp.</span><span className="msb-hn">Symlink()</span>

go
Symlink(ctx, target, linkPath)

Create a symlink

<p className="msb-label">Returns</p>

error

<span className="msb-recv">sftp.</span><span className="msb-hn">Close()</span>

go
Close(ctx)

Close the session (consumes the handle)

<p className="msb-label">Returns</p>

error

Types

SSHClientOption

<p className="msb-backref">Used by <a href="#ssh-openclient">OpenClient()</a></p>

Functional option for OpenClient(). Defaults: user root, terminal from $TERM (falling back to xterm), SFTP enabled, and the global SSH inactivity timeout.

OptionDescription
WithSSHUser(user)SSH login user. Default root
WithSSHTerm(term)Terminal name for interactive sessions
WithSSHClientSFTP(enabled)Enable or disable SFTP on the internal server. Default true
WithSSHClientInactivityTimeout(timeout)Override the internal server inactivity timeout. A zero duration disables it

SSHExecOption

<p className="msb-backref">Used by <a href="#c-exec">Exec()</a></p>

Functional option for Exec().

OptionDescription
WithSSHTTY(enabled)Request a PTY for the exec channel

SSHAttachOption

<p className="msb-backref">Used by <a href="#c-attach">Attach()</a></p>

Functional option for Attach(). The default terminal comes from $TERM (falling back to xterm); detach keys default to the standard sequence.

OptionDescription
WithSSHAttachTerm(term)Terminal name for the interactive shell
WithSSHDetachKeys(keys)Detach key sequence

SSHServerOption

<p className="msb-backref">Used by <a href="#ssh-prepareserver">PrepareServer()</a></p>

Functional option for PrepareServer(). SFTP is enabled by default, the inactivity timeout inherits the global SSH setting, and the default authorized-keys file is loaded when no path is provided.

OptionDescription
WithSSHHostKeyPath(path)Override the host private key path
WithSSHAuthorizedKeysPath(path)Override the authorized-keys path
WithSSHServerUser(user)Override the guest user used for SSH exec requests
WithSSHServerSFTP(enabled)Enable or disable SFTP on the server endpoint. Default true
WithSSHServerInactivityTimeout(timeout)Override the SSH inactivity timeout. A zero duration disables it