4.6 KiB
bare-ssh2
This is a Bare-native port of the excellent ssh2 library by Brian White (mscdex). It exposes the same public API (Client, Server, agents, utils, SFTP helpers, etc.) so code written for ssh2 can switch the import to bare-ssh2 and run on the Bare / Pear runtime.
On Node.js, builtin modules are still used (via the default branch of this package’s imports map), so the same package can be tried on Node for comparison; primary support targets Bare.
Installation
npm install bare-ssh2
Drop-in usage
Replace ssh2 with bare-ssh2:
const { readFileSync } = require('fs')
const { Client } = require('bare-ssh2')
const conn = new Client()
conn
.on('ready', () => {
conn.exec('uptime', (err, stream) => {
if (err) throw err
stream
.on('close', (code, signal) => {
console.log('close', code, signal)
conn.end()
})
.on('data', (data) => console.log('STDOUT:', data.toString()))
stream.stderr.on('data', (data) => console.log('STDERR:', data.toString()))
})
})
.connect({
host: 'example.com',
port: 22,
username: 'you',
privateKey: readFileSync('/path/to/key')
})
ESM interop follows your bundler/runtime rules for loading this CommonJS package.
How it maps Node builtins on Bare
Inside this package, require('net'), require('dns'), and other Node core names are resolved using package.json imports with the bare condition to bare-node-* wrappers. You do not need to change those specifiers in application code that only imports bare-ssh2.
crypto: Bare’s module resolver does not apply this package’s imports map to dependencies such as tweetnacl (used by bcrypt-pbkdf). This package therefore depends on a small local shims/crypto package (published as the crypto dependency) built on bare-crypto, with **getCiphers()** / **getHashes()** lists implemented in shims/crypto/lists.js. The bare imports entry for crypto points at the same shim so library code and transitive deps share one implementation.
assert / buffer: Declared as npm:bare-node-* aliases so asn1 and safer-buffer resolve them on Bare.
Buffer: lib/buffer-polyfill.js adds Node’s utf8Write / latin1Write / *Slice helpers when missing (loaded from lib/index.js, client.js, server.js, keygen.js, and protocol/keyParser.js).
The optional ssh2 native crypto binding and cpu-features optional dependency from upstream are not used here. For ChaCha20 packet encryption without OpenSSL, the chacha20 npm package is used when createCipheriv('chacha20', …) is unsupported.
API documentation
See the upstream ssh2 README for the full API (client/server events, SFTP, forwarding, HTTP(S) agents, key utilities).
Testing
From this package directory after npm install:
npm test
This runs Prettier, then bare test/test-protocol-crypto.js, then node test/test-protocol-keyparser.js (key parser sign/verify checks currently match Node’s OpenSSL more closely than Bare’s crypto for some ECDSA/OpenSSH fixtures).
Other useful commands:
bare test/test-protocol-crypto.js
npm run test:all
npm run test:all runs Prettier and bare test/test.js, which spawns every test-*.js (needs OpenSSH, keys, etc. where applicable).
npm run test:node
runs the same driver under Node.
Known gaps on Bare
- RC4 (
arcfour) and some legacy ciphers are not implemented in bare-crypto; they are omitted from negotiation when unsupported. - ECDSA signing for some OpenSSH private key paths may differ between Bare and Node; report issues with minimal key fixtures if you hit this in production.
- Tests that shell out to OpenSSH or need a full worker_threads stack may fail unless the matching bare-node-* test dependencies are installed.
- Default cipher/MAC lists follow
getCiphers()/getHashes()from the crypto shim (subset of OpenSSL’s names). - SSH agent helpers that use
child_processdepend on bare-subprocess; Windows-specific paths (Pageant, Cygwin) may differ from Node.
TypeScript
Upstream ssh2 does not ship types. You can use @types/ssh2 for typings against this API.
License
MIT — same as the original ssh2 code. See LICENSE and NOTICE.