Get an interactive ssh2 server up-and-running in minutes.
npm install ssh2-shell-server
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.
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.
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.
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.
Add a new Authenticator
to the set of authenticators available to connecting clients.
Returns this ShellServer
to allow chaining.
Listen on the configured port for client connections.
Returns a promise that resolves when the server begins listening.
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,
}
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,
}
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
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.
Contains the username that the client authenticated under.
Contains a value from the last Authenticator that succeeded, leading to this session's creation.
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.
For a good primer on ssh authentication, see this post.
AuthenticateAny
listens for clients connecting with the authentication method 'none'.
Any client connecting with the method 'none' will be accepted automatically.
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.
new AuthenticateByPassword(checkPassword);
AuthenticateByPassword
's constructor accepts the checkPassword
method (described below) as a parameter.
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
.
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.
new AuthenticateByPassword(validate, verify)
AuthenticateByPublicKey
's constructor accepts the validate
and verify
methods (described below) as parameters.
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
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).