CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/npm-ssh2

SSH2 client and server modules written in pure JavaScript for node.js

Pending
Overview
Eval results
Files

ssh-client.mddocs/

SSH Client

Complete SSH client functionality for connecting to remote SSH servers with comprehensive authentication, command execution, shell access, and tunneling capabilities.

Capabilities

Client Class

Creates and manages SSH client connections with full protocol support.

/**
 * SSH client for connecting to remote servers
 * Extends EventEmitter for connection lifecycle events
 */
class Client extends EventEmitter {
  constructor();
  connect(config: ClientConfig): Client;
  end(): Client;
  destroy(): Client;
  setNoDelay(noDelay?: boolean): Client;
}

interface ClientConfig {
  // Connection settings
  host?: string;
  hostname?: string;
  port?: number;
  localAddress?: string;
  localPort?: number;
  forceIPv4?: boolean;
  forceIPv6?: boolean;
  keepaliveInterval?: number;
  keepaliveCountMax?: number;
  readyTimeout?: number;
  
  // Identification
  ident?: string;
  
  // Authentication
  username?: string;
  password?: string;
  privateKey?: Buffer | string;
  passphrase?: string;
  tryKeyboard?: boolean;
  agent?: string | BaseAgent;
  agentForward?: boolean;
  allowAgentFwd?: boolean;
  authHandler?: AuthMethod[] | AuthHandlerMiddleware;
  
  // Security
  hostVerifier?: HostVerifier;
  hostHash?: string;
  strictVendor?: boolean;
  
  // Protocol settings
  algorithms?: AlgorithmList;
  
  // Advanced
  debug?: DebugFunction;
  sock?: Duplex;
  timeout?: number;
}

Usage Examples:

const { Client } = require('ssh2');

// Basic password authentication
const conn = new Client();
conn.connect({
  host: '192.168.1.100',
  username: 'ubuntu',
  password: 'mypassword'
});

// Key-based authentication
conn.connect({
  host: 'example.com',
  username: 'user',
  privateKey: require('fs').readFileSync('/path/to/key'),
  passphrase: 'keypassword'
});

// Agent-based authentication
conn.connect({
  host: 'server.com',
  username: 'user',
  agent: process.env.SSH_AUTH_SOCK,
  agentForward: true
});

Command Execution

Execute commands on the remote server with comprehensive options and stream handling.

/**
 * Execute a command on the remote server
 * @param command - Command string to execute
 * @param options - Execution options
 * @param callback - Callback receiving stream for command I/O
 * @returns false if connection not ready, true otherwise
 */
exec(command: string, options?: ExecOptions, callback?: ExecCallback): boolean;
exec(command: string, callback: ExecCallback): boolean;

interface ExecOptions {
  env?: { [key: string]: string };
  pty?: boolean | PseudoTtyOptions;
  x11?: boolean | X11Options;
}

interface PseudoTtyOptions {
  rows?: number;
  cols?: number;
  height?: number;
  width?: number;
  term?: string;
}

interface X11Options {
  single?: boolean;
  screen?: number;
  protocol?: string;
  cookie?: string;
}

type ExecCallback = (err: Error | null, stream?: ClientChannel) => void;

Usage Examples:

// Simple command execution
conn.exec('ls -la', (err, stream) => {
  if (err) throw err;
  
  stream.on('close', (code, signal) => {
    console.log('Command finished with code:', code);
    conn.end();
  }).on('data', (data) => {
    console.log('STDOUT:', data.toString());
  }).stderr.on('data', (data) => {
    console.log('STDERR:', data.toString());
  });
});

// Command with environment variables
conn.exec('echo $CUSTOM_VAR', {
  env: { CUSTOM_VAR: 'hello world' }
}, (err, stream) => {
  // Handle stream...
});

// Command with pseudo-TTY
conn.exec('top', {
  pty: {
    rows: 24,
    cols: 80,
    term: 'xterm'
  }
}, (err, stream) => {
  // Handle interactive command...
});

Interactive Shell

Request an interactive shell session with optional windowing and pseudo-TTY options.

/**
 * Request an interactive shell session
 * @param window - Terminal window settings
 * @param options - Shell options
 * @param callback - Callback receiving shell stream
 * @returns false if connection not ready, true otherwise
 */
shell(window?: WindowOptions, options?: ShellOptions, callback?: ShellCallback): boolean;
shell(options: ShellOptions, callback: ShellCallback): boolean;
shell(callback: ShellCallback): boolean;

interface WindowOptions {
  rows?: number;
  cols?: number;
  height?: number;
  width?: number;
  term?: string;
}

interface ShellOptions {
  env?: { [key: string]: string };
  x11?: boolean | X11Options;
}

type ShellCallback = (err: Error | null, stream?: ClientChannel) => void;

Usage Examples:

// Basic shell
conn.shell((err, stream) => {
  if (err) throw err;
  
  stream.on('close', () => {
    console.log('Shell closed');
    conn.end();
  }).on('data', (data) => {
    process.stdout.write(data);
  });
  
  process.stdin.pipe(stream);
});

// Shell with specific terminal settings
conn.shell({
  rows: 30,
  cols: 120,
  term: 'xterm-color'
}, (err, stream) => {
  // Handle shell stream...
});

Subsystem Access

Access SSH subsystems like SFTP or custom subsystems.

/**
 * Request a subsystem (like SFTP)
 * @param name - Subsystem name
 * @param callback - Callback receiving subsystem stream
 * @returns false if connection not ready, true otherwise
 */
subsys(name: string, callback: SubsysCallback): boolean;

type SubsysCallback = (err: Error | null, stream?: ClientChannel) => void;

SFTP Access

Get an SFTP client instance for file operations.

/**
 * Request SFTP subsystem
 * @param callback - Callback receiving SFTP instance
 * @returns false if connection not ready, true otherwise
 */
sftp(callback: SFTPCallback): boolean;

type SFTPCallback = (err: Error | null, sftp?: SFTP) => void;

Usage Example:

conn.sftp((err, sftp) => {
  if (err) throw err;
  
  sftp.readdir('/home/user', (err, list) => {
    if (err) throw err;
    console.log('Directory listing:', list);
    conn.end();
  });
});

Port Forwarding

Set up local and remote port forwarding for tunneling connections.

/**
 * Request remote port forwarding (server binds port and forwards to client)
 * @param bindAddr - Address to bind on remote server
 * @param bindPort - Port to bind on remote server
 * @param callback - Callback with forwarding result
 * @returns false if connection not ready, true otherwise
 */
forwardIn(bindAddr: string, bindPort: number, callback: ForwardCallback): boolean;

/**
 * Cancel remote port forwarding 
 * @param bindAddr - Address that was bound
 * @param bindPort - Port that was bound
 * @param callback - Callback with cancellation result
 * @returns false if connection not ready, true otherwise
 */
unforwardIn(bindAddr: string, bindPort: number, callback: UnforwardCallback): boolean;

/**
 * Request local port forwarding (client connects through server to destination)
 * @param srcIP - Source IP address
 * @param srcPort - Source port
 * @param dstIP - Destination IP address  
 * @param dstPort - Destination port
 * @param callback - Callback receiving connection stream
 * @returns false if connection not ready, true otherwise
 */
forwardOut(srcIP: string, srcPort: number, dstIP: string, dstPort: number, callback: ChannelCallback): boolean;

type ForwardCallback = (err: Error | null, bindPort?: number) => void;
type UnforwardCallback = (err: Error | null) => void;
type ChannelCallback = (err: Error | null, stream?: ClientChannel) => void;

OpenSSH Extensions

Extended functionality specific to OpenSSH servers.

/**
 * Disable new session creation (OpenSSH extension)
 * @param callback - Callback with operation result
 * @returns false if connection not ready, true otherwise
 */
openssh_noMoreSessions(callback: StatusCallback): boolean;

/**
 * Request Unix domain socket forwarding (OpenSSH extension)
 * @param socketPath - Unix socket path to bind
 * @param callback - Callback with forwarding result
 * @returns false if connection not ready, true otherwise
 */
openssh_forwardInStreamLocal(socketPath: string, callback: ForwardCallback): boolean;

/**
 * Cancel Unix domain socket forwarding (OpenSSH extension)
 * @param socketPath - Unix socket path to unbind
 * @param callback - Callback with cancellation result
 * @returns false if connection not ready, true otherwise
 */
openssh_unforwardInStreamLocal(socketPath: string, callback: UnforwardCallback): boolean;

/**
 * Connect to Unix domain socket through server (OpenSSH extension)
 * @param socketPath - Unix socket path to connect to
 * @param callback - Callback receiving connection stream
 * @returns false if connection not ready, true otherwise
 */
openssh_forwardOutStreamLocal(socketPath: string, callback: ChannelCallback): boolean;

type StatusCallback = (err: Error | null) => void;

Events

Connection Events

interface ClientEvents {
  /**
   * Emitted when socket connection is established
   */
  'connect': () => void;
  
  /**
   * Emitted when authentication is successful and client is ready
   */
  'ready': () => void;
  
  /**
   * Emitted when an error occurs
   */
  'error': (err: Error) => void;
  
  /**
   * Emitted when the client connection is ending
   */
  'end': () => void;
  
  /**
   * Emitted when the client connection is closed
   */
  'close': () => void;
  
  /**
   * Emitted when server identification is received
   */
  'greeting': (name: string, version: string) => void;
  
  /**
   * Emitted when SSH handshake is completed
   */
  'handshake': (negotiated: NegotiatedAlgorithms) => void;
}

Authentication Events

interface AuthenticationEvents {
  /**
   * Emitted when server sends authentication banner
   */
  'banner': (message: string, language: string) => void;
  
  /**
   * Emitted for keyboard-interactive authentication prompts
   */
  'keyboard-interactive': (
    name: string,
    instructions: string,
    lang: string,
    prompts: KeyboardPrompt[],
    finish: KeyboardFinishCallback
  ) => void;
  
  /**
   * Emitted when server requests password change
   */
  'change password': (
    message: string,
    language: string,
    callback: PasswordChangeCallback
  ) => void;
}

Connection Request Events

interface ConnectionRequestEvents {
  /**
   * Emitted for incoming TCP connection requests (from remote forwarding)
   */
  'tcp connection': (
    details: TcpConnectionDetails,
    accept: AcceptConnection<ClientChannel>,
    reject: RejectConnection
  ) => void;
  
  /**
   * Emitted for incoming Unix connection requests (OpenSSH extension)
   */
  'unix connection': (
    info: UnixConnectionInfo,
    accept: AcceptConnection<ClientChannel>,
    reject: RejectConnection
  ) => void;
  
  /**
   * Emitted for incoming X11 connection requests
   */
  'x11': (
    info: X11Info,
    accept: AcceptConnection<ClientChannel>,
    reject: RejectConnection
  ) => void;
  
  /**
   * Emitted when server provides updated host keys
   */
  'hostkeys': (keys: ParsedKey[]) => void;
}

Type Definitions

Connection and Stream Types

interface ClientChannel extends Duplex {
  stderr: Duplex;
  setWindow(rows: number, cols: number, height?: number, width?: number): boolean;
  signal(signalName: string): boolean;
  exit(status: number): boolean;
}

interface NegotiatedAlgorithms {
  kex: string;
  srvHostKey: string;
  cs: {
    cipher: string;
    mac: string;
    compress: string;
    lang: string;
  };
  sc: {
    cipher: string;
    mac: string;
    compress: string;
    lang: string;
  };
}

interface TcpConnectionDetails {
  srcIP: string;
  srcPort: number;
  destIP: string;
  destPort: number;
}

interface UnixConnectionInfo {
  socketPath: string;
}

interface X11Info {
  srcIP: string;
  srcPort: number;
}

Authentication Types

interface KeyboardPrompt {
  prompt: string;
  echo: boolean;
}

type KeyboardFinishCallback = (responses: string[]) => void;
type PasswordChangeCallback = (newPassword: string) => void;

type AcceptConnection<T = ClientChannel> = () => T;
type RejectConnection = () => boolean;

// Authentication methods
type AuthMethod = 
  | 'none' 
  | 'password' 
  | 'publickey' 
  | 'hostbased' 
  | 'keyboard-interactive';

type AuthHandlerMiddleware = (
  methodsLeft: AuthMethod[],
  partialSuccess: boolean,
  callback: AuthHandlerCallback
) => void;

type AuthHandlerCallback = (authMethod: AuthMethod | false) => void;

type HostVerifier = (
  hashedKey: Buffer,
  callback: HostVerifyCallback
) => void;

type HostVerifyCallback = (valid: boolean) => void;

type DebugFunction = (message: string) => void;

Install with Tessl CLI

npx tessl i tessl/npm-ssh2

docs

http-tunneling.md

index.md

key-management.md

port-forwarding.md

sftp-operations.md

ssh-agents.md

ssh-client.md

ssh-server.md

tile.json