> For the complete documentation index, see [llms.txt](https://engine.place.technology/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://engine.place.technology/developer-guide/drivers/ssh.md).

# SSH Drivers

SSH modules interface with devices or servers that communicate using the SSH 1.99/2.0 protocol. SSH 1 is considered obsolete due to inherent security flaws and not supported.

SSH modules are similar to Device Drivers with an additional `exec` function, where supported by the remote. Unfortunately most AV devices seem to only support interactive shell, which is akin to telnet.

## Authentication

Supports the following authentication methods:

* none
* public key
* password

These settings must be defined in the JSON settings (dependency or driver instance) and would typically look like:

```javascript
{
    "ssh": {
        "username":  "account_name",
        "$password": "password", // $ sign will encrypt the password and/or private key
        "$key_data": "-----BEGIN RSA PRIVATE KEY-----\nMIIEogIBAAKCAQEAqccvUza8FCinI4X8HSiXwIqQN6TGvcNBJnjPqGJxlstq1IfU\nkFa3S9eJl+CBkyjfvJ5ggdLN0S2EuGWwc/bdE3LKOWX8F15tFP0=\n-----END RSA PRIVATE KEY-----"
    }
}
```

## Sending an exec request

If supported requests can be sent using the `exec` function. There are two modes of operation, depending on how much response data is required and requests can be performed in parallel.

```ruby
# =================
# Request semantics
# =================
# Simple request. (these are equivalent)
exec('command –a')
exec('command', '-a')

# Simple request. Complex arguments
exec('setname -full Stephen von Takach') # This will fail
exec('setname', '-full', 'Stephen von Takach') # Will succeed, escaped properly


# ==============================
# Accessing responses (promises)
# ==============================

# .value pauses execution and waits for the response before continuing
exec('command', '-a').value  # => return all output as a string or raise error

# .then provides callbacks so execution is not paused
exec('command', '-a').then { |response|
    # Process response
}.catch { |error|
    # Handle error
}

# Commands are queued by default as many devices can only handle a single request at a time.
# However you can perform requests in parallel
tasks = []
tasks << exec('command1', '-a', wait: false)
tasks << exec('command2', '-a', wait: false)
tasks << exec('command3', '-a', wait: false)

# Wait until all commands have completed (optional)
response_array = thread.all(tasks).value
```

There is a more complicated request form that provides access to exit codes and individual data streams.

```ruby
status = exec('uname', '-a') do |channel, stream, data|
    logger.debug { data } if stream == :stdout
    logger.error { data } if stream == :stderr
end
status.value # => {exit_code: 137, exit_signal: 9}
```

### Exec request options

| Option             | Default Value | Description                                                                          |
| ------------------ | ------------- | ------------------------------------------------------------------------------------ |
| `wait`             | true          | do we want to wait for a response before we continue processing                      |
| `delay`            | 0             | minimum delay time between sends (milliseconds)                                      |
| `delay_on_receive` | 0             | time to delay the next transmit after receiving data (milliseconds)                  |
| `retries`          | 2             | number of times we’ll retry a command if it has timed out                            |
| `timeout`          | 5000          | amount of time we’ll wait for a response to a command before retrying (milliseconds) |
| `priority`         | 50            | so we can perform commands in preference to others                                   |


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter, and the optional `goal` query parameter:

```
GET https://engine.place.technology/developer-guide/drivers/ssh.md?ask=<question>&goal=<endgoal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is optional and describes the broader end goal you are ultimately trying to accomplish on behalf of the user. GitBook uses it to tailor the answer towards what is most useful for that goal.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
