Surfus.Shell
2.0.0
dotnet add package Surfus.Shell --version 2.0.0
NuGet\Install-Package Surfus.Shell -Version 2.0.0
This command is intended to be used within the Package Manager Console in Visual Studio, as it uses the NuGet module's version of Install-Package.
<PackageReference Include="Surfus.Shell" Version="2.0.0" />
For projects that support PackageReference, copy this XML node into the project file to reference the package.
<PackageVersion Include="Surfus.Shell" Version="2.0.0" />
<PackageReference Include="Surfus.Shell" />
For projects that support Central Package Management (CPM), copy this XML node into the solution Directory.Packages.props file to version the package.
paket add Surfus.Shell --version 2.0.0
The NuGet Team does not provide support for this client. Please contact its maintainers for support.
#r "nuget: Surfus.Shell, 2.0.0"
#r directive can be used in F# Interactive and Polyglot Notebooks. Copy this into the interactive tool or source code of the script to reference the package.
#:package Surfus.Shell@2.0.0
#:package directive can be used in C# file-based apps starting in .NET 10 preview 4. Copy this into a .cs file before any lines of code to reference the package.
#addin nuget:?package=Surfus.Shell&version=2.0.0
#tool nuget:?package=Surfus.Shell&version=2.0.0
The NuGet Team does not provide support for this client. Please contact its maintainers for support.
Surfus.Shell
Surfus.Shell is an SSH client library for .NET.
Features
- Fully asynchronous API
- Terminal sessions, command execution, and SCP file transfers
- Local port forwarding (direct-tcpip)
- SSH agent authentication
- Private key authentication
- Keyboard-interactive authentication
- Host key verification callback
- Low-level channel API for custom SSH extensions
Installation
dotnet add package Surfus.Shell
Quick Start
await using var client = new SshClient("192.168.1.1");
await client.ConnectAsync(cancellationToken);
await client.AuthenticateAsync("admin", "password", cancellationToken);
var terminal = await client.CreateTerminalAsync(cancellationToken);
await terminal.StandardInput.WriteAsync("show version\n"u8.ToArray(), cancellationToken);
Examples
Connect and Authenticate
await using var client = new SshClient("host", 22);
await client.ConnectAsync(ct);
// Password authentication
await client.AuthenticateAsync("user", "pass", ct);
// Keyboard-interactive
await client.AuthenticateAsync("user", (prompt, ct) => Task.FromResult("password"), ct);
// SSH agent (via SSH_AUTH_SOCK)
var agent = await SshAgentClient.ConnectAsync(ct);
await client.AuthenticateAsync("user", agent, ct);
// SSH agent over a custom stream
using var agent2 = new SshAgentClient(myAgentStream);
await client.AuthenticateAsync("user", agent2, ct);
// Private key
var key = PrivateKeyAuth.FromFile("/path/to/key");
await client.AuthenticateAsync("user", key, ct);
Terminal Session
var terminal = await client.CreateTerminalAsync(ct);
// Write to stdin
await terminal.StandardInput.WriteAsync("ls -la\n"u8.ToArray(), ct);
// Read from stdout
var buf = new byte[4096];
var n = await terminal.StandardOutput.ReadAsync(buf, ct);
var output = Encoding.UTF8.GetString(buf, 0, n);
Execute a Command
var command = await client.CreateCommandAsync(ct);
await command.StartAsync("echo hello", ct);
var result = new MemoryStream();
await command.StandardOutput.CopyToAsync(result, ct);
// result contains "hello\n"
// Exit code is available after the channel closes
var exitCode = command.ExitCode;
Local Port Forwarding
// Forward local port 8080 through SSH to remote-db:5432
await client.ForwardLocalPortAsync(8080, "remote-db", 5432, ct);
Direct TCP/IP Channel
// Open a single forwarded connection
await using var channel = await client.CreateDirectTcpIpChannelAsync("10.0.0.5", 80, ct);
await channel.StandardInput.WriteAsync("GET / HTTP/1.0\r\n\r\n"u8.ToArray(), ct);
var response = new MemoryStream();
await channel.StandardOutput.CopyToAsync(response, ct);
SCP File Transfer
var scp = new ScpClient(client);
// Upload
await scp.UploadAsync("/local/file.txt", "/remote/file.txt", cancellationToken: ct);
// Download
await scp.DownloadAsync("/remote/file.txt", "/local/file.txt", ct);
Host Key Verification
var client = new SshClient("host")
{
HostKeyCallback = async (hostKey, ct) =>
{
// Verify the host key and return true to accept
return true;
}
};
Banner Callbacks
var client = new SshClient("host")
{
// Called for each line the server sends before its version string (RFC 4253 §4.2)
OnConnectionBanner = line => Console.WriteLine($"Connection: {line}"),
// Called when the server sends a banner during authentication (RFC 4252)
OnAuthenticationBanner = banner => Console.WriteLine($"Auth: {banner}")
};
Low-Level Channel API
For custom channel types or advanced use cases:
// Open a raw session channel
var channel = await client.OpenChannelAsync(new ChannelOpenSession(), ct);
// Send custom requests
await channel.RequestAsync(new ChannelRequestSubsystem(channel.ServerId, true, "sftp"), ct);
// Use the channel streams
await channel.StandardInput.WriteAsync(data, ct);
// Or construct higher-level wrappers manually
var terminal = new SshTerminal(channel, new TerminalOptions { Columns = 120, Rows = 40 });
await terminal.RequestAsync(ct);
Custom Stream Transport
// Use an existing stream (e.g., over a proxy)
await using var client = new SshClient(myStream);
// Or use a factory for reconnectable transports
await using var client = new SshClient(async ct =>
{
var tcp = new TcpClient();
await tcp.ConnectAsync("host", 22, ct);
return (tcp.GetStream(), () => { tcp.Dispose(); return ValueTask.CompletedTask; });
});
| Product | Versions Compatible and additional computed target framework versions. |
|---|---|
| .NET | net9.0 is compatible. net9.0-android was computed. net9.0-browser was computed. net9.0-ios was computed. net9.0-maccatalyst was computed. net9.0-macos was computed. net9.0-tvos was computed. net9.0-windows was computed. net10.0 was computed. net10.0-android was computed. net10.0-browser was computed. net10.0-ios was computed. net10.0-maccatalyst was computed. net10.0-macos was computed. net10.0-tvos was computed. net10.0-windows was computed. |
Compatible target framework(s)
Included target framework(s) (in package)
Learn more about Target Frameworks and .NET Standard.
-
net9.0
- No dependencies.
NuGet packages (1)
Showing the top 1 NuGet packages that depend on Surfus.Shell:
| Package | Downloads |
|---|---|
|
Surfus.Shell.Cisco
Surfus.Shell.Cisco provides Cisco Router/Switch/Firewall extensions to Surfus.Shell. |
GitHub repositories
This package is not used by any popular GitHub repositories.