SSH2 client and server modules written in pure JavaScript for node.js
npx @tessl/cli install tessl/npm-ssh2@1.17.0SSH2 is a comprehensive SSH implementation providing both client and server functionality written in pure JavaScript for Node.js. It offers complete SSH protocol support including authentication methods, command execution, shell access, SFTP file operations, port forwarding, X11 forwarding, and SSH agent integration.
npm install ssh2const { Client, Server } = require('ssh2');For ES modules:
import { Client, Server } from 'ssh2';Import specific components:
const {
Client,
Server,
utils,
HTTPAgent,
HTTPSAgent
} = require('ssh2');const { Client } = require('ssh2');
const conn = new Client();
conn.on('ready', () => {
console.log('Client :: ready');
// Execute a command
conn.exec('uptime', (err, stream) => {
if (err) throw err;
stream.on('close', (code, signal) => {
console.log('Stream :: close :: code: ' + code + ', signal: ' + signal);
conn.end();
}).on('data', (data) => {
console.log('STDOUT: ' + data);
}).stderr.on('data', (data) => {
console.log('STDERR: ' + data);
});
});
}).connect({
host: '192.168.100.100',
username: 'frylock',
privateKey: require('fs').readFileSync('/path/to/my/key')
});const { Server } = require('ssh2');
new Server({
hostKeys: [hostKey]
}, (client) => {
console.log('Client connected!');
client.on('authentication', (ctx) => {
if (ctx.method === 'password' && ctx.username === 'foo' && ctx.password === 'bar') {
ctx.accept();
} else {
ctx.reject();
}
}).on('ready', () => {
console.log('Client authenticated!');
});
}).listen(0, '127.0.0.1', function() {
console.log('Listening on port ' + this.address().port);
});SSH2 is organized around several key components:
Complete SSH client functionality including connection management, authentication, and remote operations.
class Client extends EventEmitter {
connect(config: ClientConfig): Client;
end(): Client;
destroy(): Client;
exec(command: string, options: ExecOptions, callback: ExecCallback): boolean;
shell(windowOptions: WindowOptions, options: ShellOptions, callback: ShellCallback): boolean;
sftp(callback: SFTPCallback): boolean;
}
interface ClientConfig {
host?: string;
hostname?: string;
port?: number;
localAddress?: string;
localPort?: number;
forceIPv4?: boolean;
forceIPv6?: boolean;
keepaliveInterval?: number;
keepaliveCountMax?: number;
readyTimeout?: number;
ident?: string;
username?: string;
password?: string;
privateKey?: Buffer | string;
passphrase?: string;
tryKeyboard?: boolean;
agent?: string | BaseAgent;
agentForward?: boolean;
allowAgentFwd?: boolean;
authHandler?: AuthMethod[];
hostVerifier?: HostVerifier;
algorithms?: AlgorithmList;
debug?: DebugFunction;
}Full SSH server implementation with authentication handling and session management.
class Server extends net.Server {
constructor(config: ServerConfig, connectionListener?: ConnectionListener);
}
interface ServerConfig {
hostKeys: Array<Buffer | string | ParsedKey>;
algorithms?: AlgorithmList;
ident?: string;
banner?: string;
greeting?: string;
debug?: DebugFunction;
keepaliveInterval?: number;
keepaliveCountMax?: number;
}
class IncomingClient extends EventEmitter {
authenticated: boolean;
noMoreSessions: boolean;
end(): boolean;
x11(originAddr: string, originPort: number, callback: X11Callback): boolean;
forwardOut(boundAddr: string, boundPort: number, remoteAddr: string, remotePort: number, callback: ForwardCallback): boolean;
}Comprehensive SFTP implementation supporting both client and server operations with OpenSSH extensions.
class SFTP extends EventEmitter {
// File operations
open(path: string, flags: string | number, attrs?: Attributes, callback?: OpenCallback): boolean;
close(handle: Buffer, callback?: StatusCallback): boolean;
read(handle: Buffer, buffer: Buffer, offset: number, length: number, position: number, callback?: ReadCallback): boolean;
write(handle: Buffer, buffer: Buffer, offset: number, length: number, position: number, callback?: WriteCallback): boolean;
// Directory operations
readdir(path: string, callback?: ReaddirCallback): boolean;
mkdir(path: string, attrs?: Attributes, callback?: StatusCallback): boolean;
rmdir(path: string, callback?: StatusCallback): boolean;
// File system operations
stat(path: string, callback?: AttrsCallback): boolean;
unlink(path: string, callback?: StatusCallback): boolean;
rename(oldPath: string, newPath: string, callback?: StatusCallback): boolean;
}Support for SSH agents including OpenSSH, Windows Pageant, and Cygwin agents.
class BaseAgent {
getIdentities(callback: IdentitiesCallback): void;
sign(pubKey: ParsedKey, data: Buffer, options?: SignOptions, callback: SignCallback): void;
}
class OpenSSHAgent extends BaseAgent {
constructor(socketPath?: string);
getStream(callback: StreamCallback): void;
}
function createAgent(agent: string | BaseAgent): BaseAgent;Local and remote port forwarding capabilities including TCP and Unix domain sockets.
// Client methods
forwardIn(bindAddr: string, bindPort: number, callback: ForwardCallback): boolean;
unforwardIn(bindAddr: string, bindPort: number, callback: UnforwardCallback): boolean;
forwardOut(srcIP: string, srcPort: number, dstIP: string, dstPort: number, callback: ChannelCallback): boolean;
// OpenSSH extensions
openssh_forwardInStreamLocal(socketPath: string, callback: ForwardCallback): boolean;
openssh_unforwardInStreamLocal(socketPath: string, callback: UnforwardCallback): boolean;
openssh_forwardOutStreamLocal(socketPath: string, callback: ChannelCallback): boolean;HTTP and HTTPS agents for tunneling web traffic through SSH connections.
class HTTPAgent extends http.Agent {
constructor(connectCfg: ClientConfig, agentOptions?: http.AgentOptions);
createConnection(options: http.RequestOptions, callback: ConnectCallback): void;
}
class HTTPSAgent extends https.Agent {
constructor(connectCfg: ClientConfig, agentOptions?: https.AgentOptions);
createConnection(options: https.RequestOptions, callback: ConnectCallback): void;
}SSH key parsing and generation utilities supporting RSA, ECDSA, and Ed25519 keys.
// Key parsing
function parseKey(keyData: string | Buffer, passphrase?: string): ParsedKey | Error;
// Key generation
function generateKeyPair(keyType: string, options: KeyGenOptions, callback: KeyGenCallback): void;
function generateKeyPairSync(keyType: string, options: KeyGenOptions): KeyPair;
interface KeyGenOptions {
bits?: number;
comment?: string;
format?: string;
passphrase?: string;
cipher?: string;
rounds?: number;
}interface ParsedKey {
type: string;
comment?: string;
public: Buffer;
private?: Buffer;
getPrivatePEM(): string;
getPublicPEM(): string;
getPublicSSH(): Buffer;
sign(data: Buffer, hashAlgo?: string): Buffer | Error;
verify(data: Buffer, signature: Buffer, hashAlgo?: string): boolean | Error;
}
interface AlgorithmList {
kex?: string[];
cipher?: string[];
serverHostKey?: string[];
hmac?: string[];
compress?: string[];
}
interface Attributes {
mode?: number;
uid?: number;
gid?: number;
size?: number;
atime?: number | Date;
mtime?: number | Date;
}
interface Stats extends Attributes {
isFile(): boolean;
isDirectory(): boolean;
isBlockDevice(): boolean;
isCharacterDevice(): boolean;
isSymbolicLink(): boolean;
isFIFO(): boolean;
isSocket(): boolean;
}// Client events
interface ClientEvents {
'connect': () => void;
'ready': () => void;
'error': (err: Error) => void;
'end': () => void;
'close': () => void;
'greeting': (name: string, version: string) => void;
'handshake': (negotiated: NegotiatedAlgorithms) => void;
'banner': (message: string, language: string) => void;
'keyboard-interactive': (prompts: KeyboardPrompt[]) => void;
'change password': (message: string, language: string, callback: PasswordChangeCallback) => void;
'tcp connection': (details: ConnectionDetails, accept: AcceptConnection, reject: RejectConnection) => void;
'unix connection': (info: UnixConnectionInfo, accept: AcceptConnection, reject: RejectConnection) => void;
'x11': (info: X11Info, accept: AcceptConnection, reject: RejectConnection) => void;
}
// Server events
interface ServerEvents {
'connection': (client: IncomingClient, info: ClientInfo) => void;
'error': (err: Error) => void;
'listening': () => void;
'close': () => void;
}const STATUS_CODE = {
OK: 0,
EOF: 1,
NO_SUCH_FILE: 2,
PERMISSION_DENIED: 3,
FAILURE: 4,
BAD_MESSAGE: 5,
NO_CONNECTION: 6,
CONNECTION_LOST: 7,
OP_UNSUPPORTED: 8
};
const OPEN_MODE = {
READ: 0x00000001,
WRITE: 0x00000002,
APPEND: 0x00000004,
CREAT: 0x00000008,
TRUNC: 0x00000010,
EXCL: 0x00000020
};
// Utility functions
function flagsToString(flags: number): string;
function stringToFlags(flagsStr: string): number;Access via:
const { utils } = require('ssh2');
console.log(utils.sftp.STATUS_CODE.OK); // 0
console.log(utils.sftp.OPEN_MODE.READ); // 1
// Convert numeric flags to string representation
const flags = utils.sftp.OPEN_MODE.READ | utils.sftp.OPEN_MODE.WRITE;
console.log(utils.sftp.flagsToString(flags)); // "r+"
// Convert string flags to numeric representation
const numFlags = utils.sftp.stringToFlags("w");
console.log(numFlags); // 0x00000002