Skip to content
Matt Magoffin edited this page Jun 28, 2017 · 7 revisions

SolarSSH API

The SolarSSH server acts as an intermediary between SolarNodes and an administrator, allowing an administrator access to nodes that are not directly accessible over the internet because of network configuration details (such as firewalls). It exposes two main features for a given SolarNode:

  1. a URL for accessing the node web server (and thus, the setup GUI)
  2. a websocket connection to a SSH terminal shell on the node

To provide these features, SolarSSH exposes a RESTful API that a browser can use to control the entire process of authenticating the administrator, getting SolarNode to SSH to SolarSSH, and exposing the features listed above to the browser.

Overview

The general process of using SolarSSH follows these steps:

  1. Create a new SolarSSH session, which contains a unique session ID and other details needed in subsequent steps. A SolarNet security token is required to authenticate the administrator.
  2. Enqueue a StartRemoteSsh instruction with SolarNet, passing in details from the session details returned in step 1. The ID of the instruction is added to the session details for use in subsequent steps.
  3. Using the instruction ID returned in step 2, wait for the instruction to reach the Completed state, which signals that the SolarNode has established the SSH connection with SolarSSH.
  4. At this stage, feature #1 from above is available, and the browser can access the node web server via a URL on the SolarSSH server.
  5. To access the node via SSH, the browser can open a websocket connection to the SolarSSH server and then pass SSH credentials to SolarSSH. SolarSSH will then establish a SSH terminal shell on the node, and connect the shell to the websocket.
  6. At this stage, all text sent over the websocket will be passed to the node's terminal shell, and any text emitted by the shell will be passed back over the websocket to the browser. By using a JavaScript terminal emulator like xterm.js (with that project's attach addon) a full interactive shell can be created right in the browser.

Many of the REST API methods require a SNWSv2 header value be passed on a X-SN-PreSignedAuthorization HTTP header that SolarSSH can use to make requests to specific API methods on SolarNetwork. Passing pre-computed authorization serves a few purposes:

  1. The security token secret is never passed to SolarSSH, so SolarSSH never has any knowledge of it.
  2. SolarSSH can only make the specific requests to SolarNetwork that are explicitly encoded in the pre-computed authorization. As the authorization is unique to each request and includes the details of the request, SolarSSH cannot access anything other than what the authorization allows.
  3. SolarSSH can authenticate the API request when it invokes the HTTP request on SolarNetwork using the pre-computed authorization. If the request is authorized by SolarNetwork, then SolarSSH knows the API request is valid.

REST API

All REST responses are encoded as a JSON object, with a minimum of a success boolean property. For example:

{ "success": true }

If there is additional information, it will be provided on a data property, for example:

{ "success": true, "data": { "foo": "bar" } }

If an error occurs, a message and error code will be included, for example:

{ "success": true, "code": 5000, "message": "Bad credentials." }

Create session

This method will start a new SolarSSH session and is the required first step for interacting with SolarSSH.

Create session request

GET /api/v1/ssh/session/new
nodeId A query parameter containing the ID of the SolarNode to use the session with.
X-SN-PreSignedAuthorization A HTTP header containing a SNWSv2 authorization header value for making a request to the SolarUser view pending instructions API for the given nodeId.
X-SN-Date A HTTP header containing the the date used in the X-SN-PreSignedAuthorization value.

Create session response

The response includes a session object. A typical response looks like this:

{
  "success": true,
  "code": null,
  "message": null,
  "data": {
    "sessionId": "8d0b329c-4845-49df-a7d9-c952fb395a8a",
    "created": 1498590980179,
    "nodeId": 246,
    "host": "ssh.solarnetwork.net",
    "port": 8022,
    "reversePort": 43332,
    "startInstructionId": null,
    "stopInstructionId": null,
    "established": false
  }
}

Session object

A session object contains the following properties:

sessionId A unique ID for the session, as a string. This is also the username the node must use when connecting to SolarSSH.
created The date the session was created, as milliseconds since the epoch.
nodeId The SolarNode ID associated with the session.
host The SSH hostname for the SolarNode to connect to. Typically this will be the same hostname SolarSSH is running on, but it could differ.
port The SSH port for the SolarNode to connect to (on host).
reversePort A reverse listen port for the SolarNode to establish when it connects via SSH, for forwarding to port 22 on localhost, for tunneling SSH traffic back to the node. This would be like the node passing -R 127.0.0.1:reversePort:localhost:22 via OpenSSH. The node is then expected to also request reversePort + 1 for reverse forwarding to port 8080 on localhost, for tunneling HTTP traffic back tothe node. This would be like the node passing -R 127.0.0.1:reversePort+1:localhost:8080 via OpenSSH.
startInstructionId The SolarNetwork instruction ID for the StartRemoteSsh instruction queued for the node. This ID can be used to query on the status of this instruction, and know if the node successfully connected to SolarSSH or not.
stopInstructionId The SolarNetwork instruction ID for the StopRemoteSsh instruction queued for the node. This ID can be used to query on the status of this instruction, and know if the node successfully disconnected to SolarSSH or not.
established A boolean that gets set to true when the node successfully connects and authenticates to SolarSSH.

TODO

Clone this wiki locally