# Remote access

Sometimes the integration is not a protocol the device speaks on your behalf — it is you, on the device,
running commands. OpenGate opens these connections from a [connector function](../connector_functions/), so
the device must be reachable at an IP address, directly or through a [gateway](../topology/).

## SSH and Telnet

Both follow the same three-step shape, and the object properties are set before connecting:

```javascript
ssh.ip = "10.0.0.7";
ssh.user = "admin";
ssh.identity = "-----BEGIN RSA PRIVATE KEY-----...";
ssh.connect(["$"]);
var out = ssh.send("show version", "#", ["#"]);
ssh.disconnect();
```

| Property | SSH | Telnet |
|---|---|---|
| `ip` | Address of the server | Address of the server |
| `port` | Port of the server | Port of the server, default `23` |
| `retries` | Default `3` | Default `3` |
| `timeout` | Milliseconds, default `5000` | Milliseconds, default `5000` |
| `user`, `password` | Credentials | — |
| `identity` | RSA key content, as an alternative to a password | — |

{{% notice style="warning" title="Set the SSH port explicitly" icon="triangle-exclamation" %}}
The SSH reference documents a default `port` of `23`, which is Telnet's port rather than SSH's `22`. Until
that is clarified, set `ssh.port` explicitly in your script instead of relying on the default.
{{% /notice %}}

`connect` and `send` both take a `waitFor` list: the strings that tell the client the device has finished
talking. Getting those right is most of the work with a shell integration, because there is no framing to
rely on — a prompt is the only end-of-message marker you have.

Prefer `identity` over `password` where the device supports it, and read either from the provisioned
`entity` rather than hardcoding it in the script.

**References**: [SSH](../connector_functions/protocol_apis/ssh/) ·
[Telnet](../connector_functions/protocol_apis/telnet/)

## ICMP

A ping, which answers the one question every other integration depends on: is this device reachable at all?

| Property | Meaning |
|---|---|
| `ip` | Address to ping |
| `retries` | Delivery retries, default `5` |
| `timeout` | Milliseconds per retry, default `2500` |
| `async` | `true` by default: the request does not block the function |

Because `async` defaults to `true`, the result usually does **not** come back in the same execution. It
arrives at a separate `RESPONSE` connector function, which receives the outcome as its `payload` — that is
what the [ICMP Response](../connector_functions/protocol_apis/icmp_response/) reference documents.

Set `async` to `false` when you want the answer inline and are prepared to wait for it.

**References**: [ICMP](../connector_functions/protocol_apis/icmp/) ·
[ICMP Response](../connector_functions/protocol_apis/icmp_response/)

## Where to go next

| To | Read |
|---|---|
| See every protocol OpenGate speaks | [Supported protocols](../supported_protocols/) |
| Write the function | [Connector Functions](../connector_functions/) |
| Launch this across a fleet | [Jobs and tasks](../../operations/) |
| Debug a session that hangs | [Debugging](../../debugging/) |
