SSH2 client and server modules written in pure JavaScript for node.js
—
Complete SSH client functionality for connecting to remote SSH servers with comprehensive authentication, command execution, shell access, and tunneling capabilities.
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
});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...
});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...
});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;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();
});
});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;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;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;
}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;
}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;
}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;
}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