ssh2-shell-server
v2.2.3
Published
A wrapper for ssh2 with an eye toward interactive shells.
Downloads
16
Maintainers
Readme
SSH2 Shell Server
Get an interactive ssh2 server up-and-running in minutes.
Install
npm install ssh2-shell-server
Generate Keys
Generate the host key. For this example, the following will work:
ssh-keygen -f test_key -C ""
This will generate a key pair in the current directory.
Implement
The following example creates a shell server listening on port 5151, using the private key at ./test_keys/test_key
as the host key. You can replace this with the location of your own generated key.
When a user connects using a client like ssh, the server accepts their authentication.
After the user has authenticated, it sends a friendly message to the user's client, then disconnects.
const { ShellServer, Authenticators } = require('ssh2-shell-server');
const fs = require('fs');
const PORT = 5151;
const keyFile = fs.readFileSync('./test_keys/test_key');
const server = new ShellServer({
hostKeys: [ keyFile ],
port: PORT,
});
server.registerAuthenticator(new Authenticators.AuthenticateAny());
server.on('session-created', ({client, session}) => {
session.on('stream-initialized', (stream) => {
stream.write('Welcome to the server!\r\n');
stream.write('Good talk, see you later.\r\n');
stream.close();
});
});
server.listen().then(() => {
console.log(`Listening on port ${PORT}...`);
});
See examples for more working source code.
Shell Server
The ShellServer
class manages the ssh2 Server
. Its primary responsibilities are listening for session events from individual clients, and forwarding them to the ShellServer
's own listeners.
ShellServer
is also responsible for registering authenticators, and cloning them to newly connected clients for authentication.
Constructor
new ShellServer({
hostKeys: Array<string>,
port: number,
});
hostKeys
is an array of raw private key data.
port
is the port that this server will listen on.
registerAuthenticator(authenticator)
Add a new Authenticator
to the set of authenticators available to connecting clients.
Returns this ShellServer
to allow chaining.
listen()
Listen on the configured port for client connections.
Returns a promise that resolves when the server begins listening.
Events
session-created
When a client is authenticated and a session is created, the ShellServer
will emit a 'session-created'
event with the following payload:
{
client: ShellClient,
session: ShellSession,
}
session-ended
When a client connection is closed by the client or the server, ShellServer
will emit a 'session-ended'
event with the following payload:
{
client: ShellClient,
session: ShellSession,
}
ShellClient
The ShellClient
is generally an internal class used to manage the authentication of a single client.
A ShellClient
may be passed out of the ShellServer
as part of the event payload when sessions are created or ended, or when an error occurs.
ShellSession
ShellSession
manages the stream communicating with a single client. Its primary responsibilities are to accept pty
requests and prepare stream between the server and client. It will emit an event when the stream has been initialized.
ShellSession
is also responsible for managing changes to the client's viewing window, updating the stream's rows
and columns
fields.
Fields
username
Contains the username that the client authenticated under.
authentication
Contains a value from the last Authenticator that succeeded, leading to this session's creation.
Events
stream-initialized
After a client connection is established, once a stream has been initialized to manage data-flow between the client and server, the ShellSession
will emit a 'stream-initialized'
event with the newly initialized stream as the payload.
Authenticators
For a good primer on ssh authentication, see this post.
AuthenticateAny
AuthenticateAny
listens for clients connecting with the authentication method 'none'.
Any client connecting with the method 'none' will be accepted automatically.
AuthenticateByPassword
AuthenticateByPassword
listens for clients connecting with the authentication method 'password'.
Any client connecting with the method 'password' will be authenticated using the provided checkPassword
method.
Constructor
new AuthenticateByPassword(checkPassword);
AuthenticateByPassword
's constructor accepts the checkPassword
method (described below) as a parameter.
checkPassword(username, password, ctx)
CheckPassword
method accepts username
, password
, and ctx
as parameters when a client attempts to authenticate.
These are the authentication parameters provided by the client attempting to authenticate.
The result of checkPassword
will be checked for truthiness (If it is a promise, it will resolve first).
A truthy value will successfully authenticate the client.
A falsey value will will reject this authentication attempt.
A truthy value will also be passed to the resulting ShellSession
.
AuthenticateByPublicKey
AuthenticateByPassword
listens for clients connecting with the authentication method 'password'.
Any client connecting with the method 'publickey' will be authenticated using the provided validate
and verify
methods. Validation and Verification must both succeed for the client to be authenticated.
AuthenticateByPublicKey provides hooks to drive the authorized_keys
process.
Constructor
new AuthenticateByPassword(validate, verify)
AuthenticateByPublicKey
's constructor accepts the validate
and verify
methods (described below) as parameters.
validate(keyAlgorithm, keyData, ctx)
Validate
method accepts keyAlgorithm
, keyData
, and ctx
as parameters.
This provides a chance to accept or reject the public key based on the key's contents.
The result of validate
will be evaluated for truthiness (If it is a promise, it will resolve first).
A truthy value indicates that the client has succeeded at this step.
A falsey value indicates that the client has failed this step.
This is the first step, so a truthy value will lead to the client attemptint to verify.
This will be handled by the verify
method.
verify(verifier, signature, ctx)
Verify
method accepts verifier
, signature
, and ctx
as parameters.
This provides a chance to accept or reject the public key based on its signature.
The result of verify
will be evaluated for truthiness (If it is a promise, it will resolve first).
A truthy value indicates that the client has succeeded at this step.
A falsey value indicates that the client has failed this step.
As this is the last step, a truthy value will indicate that the user has successfully authenticated.
The returned value will be passed to the resulting ShellSession
.
A simple implementation of verify would be:
function verify(verifier, signature) {
return verifier.verify(pk, signature);
}
Where pk
is the connecting connecting user's raw public key (as a Buffer).
Copyright 2017, Kyle Stafford (MIT License).