AlfredBr.SshServer.Core 1.3.0

dotnet add package AlfredBr.SshServer.Core --version 1.3.0
                    
NuGet\Install-Package AlfredBr.SshServer.Core -Version 1.3.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="AlfredBr.SshServer.Core" Version="1.3.0" />
                    
For projects that support PackageReference, copy this XML node into the project file to reference the package.
<PackageVersion Include="AlfredBr.SshServer.Core" Version="1.3.0" />
                    
Directory.Packages.props
<PackageReference Include="AlfredBr.SshServer.Core" />
                    
Project file
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 AlfredBr.SshServer.Core --version 1.3.0
                    
#r "nuget: AlfredBr.SshServer.Core, 1.3.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 AlfredBr.SshServer.Core@1.3.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=AlfredBr.SshServer.Core&version=1.3.0
                    
Install as a Cake Addin
#tool nuget:?package=AlfredBr.SshServer.Core&version=1.3.0
                    
Install as a Cake Tool

.NET SSH Server

NuGet NuGet Downloads Build

A lightweight SSH server library in C# (.NET 10) that allows terminal clients to connect via SSH and interact with a TUI application. Inspired by charmbracelet's wish package in Go.

Quick Start

Install the Package

dotnet add package AlfredBr.SshServer.Core

View on NuGet: AlfredBr.SshServer.Core

Create Your Application

using AlfredBr.SshServer.Core;

public class MyApp : SshShellApplication
{
    protected override string Prompt => "myapp> ";

    protected override IEnumerable<string> Completions => ["help", "quit"];

    protected override bool OnCommand(string command)
    {
        if (command == "quit") return false;
        WriteLine($"You said: {Escape(command)}");
        return true;
    }
}

Run the Server

await SshServerHost.CreateBuilder()
    .UsePort(2222)
    .AllowAnonymous()
    .UseMaxConnections(100)
    .UseConnectionRateLimit(10, TimeSpan.FromSeconds(30))
    .UseApplication<MyApp>()
    .Build()
    .RunAsync();

Connect

ssh -p 2222 localhost

See the API Manual for the complete API reference, or DEVELOPERS.md for the contributor guide.

Project Structure

Project Description
AlfredBr.SshServer.Core The SSH server library — includes SSH protocol, TUI infrastructure, and builder API.
SshServer.Demo Demo application showcasing Spectre.Console features.

Key Classes

Class Description
SshServerHost Main server host with fluent builder API.
SshServerBuilder Fluent builder for configuring the server.
SshShellApplication Abstract base class for SSH applications.

Builder API

await SshServerHost.CreateBuilder()
    .UsePort(2222)                              // TCP port (default: 2222)
    .UseBanner("SSH-2.0-MyApp")                 // SSH protocol banner
    .UseHostKeyPath("mykey.pem")                // Host key file path
    .AllowAnonymous()                           // Enable anonymous auth
    .UseAuthorizedKeysFile("authorized_keys")   // Public key auth file
    .UseSessionTimeout(TimeSpan.FromMinutes(30)) // Idle timeout
    .UseTransportOperationTimeout(TimeSpan.FromSeconds(30)) // Active SSH transport timeout
    .UseMaxConnections(100)                     // Connection limit
    .UseConnectionRateLimit(10, TimeSpan.FromSeconds(30)) // Per-IP connection-attempt limit
    .UseLogLevel(LogLevel.Information)          // Minimum log level
    .UseApplication<MyApp>()                    // Your application class
    .ConfigureLogging(builder => { ... })       // Custom logging config
    .UseDefaultConfiguration(args)              // Load from appsettings.json
    .Build()
    .RunAsync();

Multi-Application Support

Host multiple applications with username-based routing or an interactive menu:

await SshServerHost.CreateBuilder()
    // Map usernames directly to apps
    .MapUser<DemoApp>("demo")       // ssh demo@host → DemoApp
    .MapUser<AdminApp>("admin")     // ssh admin@host → AdminApp

    // Unmapped users see a selection menu
    .UseApplicationMenu(menu => menu
        .Add<DemoApp>("Demo", "Spectre.Console showcase")
        .Add<AdminApp>("Admin", "Server administration")
        .Add<MonitoringApp>("Monitor", "Live metrics dashboard")
        .SetDefaultForExec("Demo")
        .ReturnToMenuOnExit(true))

    .Build()
    .RunAsync();

Usage:

ssh demo@localhost -p 2222       # Direct to DemoApp
ssh admin@localhost -p 2222      # Direct to AdminApp
ssh localhost -p 2222            # Shows app selection menu
ssh guest@localhost "admin:logs" # Exec 'logs' in AdminApp

Features

Authentication

  • Public key authentication — supports ssh-rsa, ssh-ed25519, ecdsa-sha2-nistp256/384/521
  • Anonymous access — configurable via AllowAnonymous() builder method
  • Authorized keys — standard OpenSSH authorized_keys file format

Host Keys

  • ECDSA — auto-generated nistp256 key on first run
  • Ed25519 — client key verification (via NSec.Cryptography)
  • RSA — sha2-256/512 support

Terminal Emulation

  • PTY support — full pseudo-terminal with resize handling
  • Emacs-style line editing:
    • Ctrl-A/E: beginning/end of line
    • Ctrl-B/F: back/forward character
    • Ctrl-P/N: previous/next history
    • Ctrl-D: delete char or disconnect
    • Ctrl-K/U: kill to end/beginning
    • Ctrl-Y: yank (paste) from kill ring
    • Ctrl-L: clear screen
    • Alt-B/F: back/forward word
    • Alt-D: delete word forward
    • Home/End, Delete, Arrow keys
  • Tab completion — command name auto-completion
  • Command history — per-connection with navigation

TUI Integration (Spectre.Console)

  • Rich output — tables, panels, rules, trees, bar charts
  • Interactive prompts — selection, multi-select, confirmation, text input
  • Live displays — progress bars, spinners, live-updating tables
SshShellApplication Helper Methods
Method Description
WriteLine(text) Write a line of text (supports Spectre markup).
Ask(prompt) Text input prompt (returns string).
Ask<T>(prompt) Typed input prompt (e.g., int, double).
AskBox(prompt, width) Show a bordered box input prompt (returns string). Width 0 = full console width.
AskBox<T>(prompt, width) Show a bordered box prompt collecting a typed value.
Confirm(prompt) Yes/No confirmation prompt.
Select(prompt, items) Single-item selection list.
MultiSelect(prompt, items) Multi-item selection list.
Status(message, action) Status spinner while running an action.
Progress(action) Progress bar for tracked tasks.
Escape(text) Escape a string for safe use in Spectre markup.

Run the Demo

dotnet run --project src/SshServer.Demo/SshServer.Demo.csproj
ssh -p 2222 localhost

Demo Commands

Command Description
help Show available commands
status Server status with process ID
whoami Connection info, auth method, key fingerprint
config Server configuration (hostname, IPs, settings)
clear Clear the screen
menu Interactive menu selection
select Choose from a list
multi Multi-select from a list
confirm Yes/No confirmation
ask Text input with validation
askbox Bordered box input prompt demo
demo Run all interactive demos
progress Progress bar demo
spinner Status spinner demo
live Live-updating table demo
tree Hierarchical tree display
chart Bar chart visualization
quit Disconnect

With Public Key Authentication

  1. Add your public key to authorized_keys:
    cat ~/.ssh/id_ed25519.pub >> src/SshServer.Demo/authorized_keys
    
  2. Set AllowAnonymous to false in appsettings.json
  3. Connect: ssh -p 2222 localhost

Scripted Commands (Exec Channel)

# Run a single command without entering interactive mode
ssh -p 2222 localhost status
ssh -p 2222 localhost whoami
ssh -p 2222 localhost config

# Use in scripts
result=$(ssh -p 2222 localhost status)
echo "Server says: $result"

Configuration

Settings can be configured via appsettings.json:

{
  "SshServer": {
    "Port": 2222,
    "Banner": "SSH-2.0-SshServer",
    "HostKeyPath": "hostkey_ecdsa_nistp256.pem",
    "MaxConnections": 100,
    "ConnectionRateLimitCount": 10,
    "ConnectionRateLimitWindowSeconds": 30,
    "LogLevel": "Debug",
    "AllowAnonymous": true,
    "AuthorizedKeysPath": "./authorized_keys",
    "SessionTimeoutMinutes": 0,
    "TransportOperationTimeoutSeconds": 30
  }
}

Load configuration in your app:

await SshServerHost.CreateBuilder()
    .UseDefaultConfiguration(args)  // Loads appsettings.json + env vars + CLI args
    .UseMaxConnections(100)         // Optional explicit code default
    .UseConnectionRateLimit(10, TimeSpan.FromSeconds(30))
    .UseApplication<MyApp>()
    .Build()
    .RunAsync();
Setting Description
Port TCP port to listen on (default: 2222)
Banner SSH protocol banner
HostKeyPath Path to host key PEM file
MaxConnections Max concurrent connections (0 = unlimited)
ConnectionRateLimitCount Max connection attempts per client IP in the active rate-limit window (0 = disabled)
ConnectionRateLimitWindowSeconds Sliding window length for connection-attempt rate limiting in seconds (0 = disabled)
LogLevel Minimum log level (Trace, Debug, Information, Warning, Error)
AllowAnonymous Allow connections without authentication
AuthorizedKeysPath Path to OpenSSH authorized_keys file
SessionTimeoutMinutes Idle timeout in minutes (0 = disabled)
TransportOperationTimeoutSeconds Timeout for active SSH transport operations; idle established sessions use SessionTimeoutMinutes

Override via environment variables (SSHSERVER_ prefix) or command-line arguments.

When MaxConnections is reached, new SSH sessions are rejected until an existing session closes. When ConnectionRateLimitCount and ConnectionRateLimitWindowSeconds are both positive, connection attempts are rate-limited per client IP using a sliding window.

Architecture

┌─────────────────────────────┐
│  Your Application           │  extends SshShellApplication
├─────────────────────────────┤
│  SshServerHost + Builder    │  Fluent API, lifecycle management
├─────────────────────────────┤
│  SshShellApplication        │  Base class with helpers
├─────────────────────────────┤
│  TUI Infrastructure         │  Spectre.Console, LineEditor
├─────────────────────────────┤
│  SSH Server Library         │  FxSsh (modernised)
├─────────────────────────────┤
│  TCP Listener               │  System.Net.Sockets
└─────────────────────────────┘

Dependencies

Package Purpose
FxSsh Core SSH server (vendored source)
Microsoft.Extensions.Hosting Configuration and DI
Microsoft.Extensions.Logging Structured logging
Spectre.Console TUI rendering and prompts
NSec.Cryptography Ed25519 key support

Project Status

Completed

  • SSH transport (key exchange, encryption, MAC)
  • Anonymous and public key authentication
  • Connection limits
  • Connection-attempt rate limiting
  • PTY requests and window resize
  • Emacs-style line editing with history
  • Tab completion
  • Spectre.Console integration (rendering + interactive prompts)
  • Configuration via appsettings.json
  • Graceful shutdown (Ctrl+C)
  • Structured logging with connection IDs
  • Ed25519 client key support
  • Session timeout
  • SshShellApplication base class for easy app development
  • Fluent builder API
  • NuGet package structure

Roadmap

  • Password authentication
  • Unit tests

Key RFCs

RFC Topic
4251 SSH Protocol Architecture
4252 SSH Authentication Protocol
4253 SSH Transport Layer Protocol
4254 SSH Connection Protocol (channels, PTY)
5656 ECDH key exchange
8032 Ed25519 signing

Acknowledgements

This project builds upon the work of several excellent open source projects:

Project Author Site License Role
FxSsh Aimeast MIT Core SSH protocol implementation (vendored and extended)
Spectre.Console Patrik Svensson et al. https://spectreconsole.net/ MIT TUI rendering, interactive prompts, and live displays
NSec.Cryptography Nicholas Walther nsec.rocks MIT Ed25519 client key verification
Microsoft.Extensions.* Microsoft / .NET Foundation MIT Hosting, configuration, dependency injection, and logging
charmbracelet/wish Charmbracelet https://charm.land/ MIT Original inspiration — SSH app framework for Go

License

MIT — Copyright (c) 2026 Alfred Broderick

Product Compatible and additional computed target framework versions.
.NET net10.0 is compatible.  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.

NuGet packages

This package is not used by any NuGet packages.

GitHub repositories

This package is not used by any popular GitHub repositories.

Version Downloads Last Updated
1.3.0 58 5/28/2026
1.2.0 109 3/22/2026
1.1.2 115 2/28/2026
1.1.1 110 2/25/2026