# External Connections (execonnect)


An **External Connection** lets your VMs reach a service on a private network,
like an internal API or a staging server behind a firewall. You run
`execonnect` on a machine in that network. It dials out to exe.dev, so you
don't need inbound ports, a public IP, or a VPN.

VMs use the service through an [HTTP Proxy integration](integrations-http-proxy):

```
VM ──► NAME.int.exe.xyz ──► exe.dev ══ tunnel ══► execonnect ──► your service
```

VMs can only reach endpoints you publish, and `execonnect` can't reach your VMs.

## Quick start

**1. Create a connection.** On the [Integrations page](/integrations), add an
External Connection, or run:

```
exe.dev ▶ integrations setup execonnect --name=office
```

Add `--team` to share it with your team. Copy the `execonnect enroll …`
command it shows; the token is single-use and isn't shown again.

**2. Install and start `execonnect`** on a machine in your network:

```sh
curl -fsSL https://exe.dev/execonnect/install.sh | sh
sudo systemctl enable --now execonnect
```

On macOS, or without systemd, run `execonnect serve` instead.

**3. Enroll** by pasting the command from step 1:

```sh
execonnect enroll ect_…
```

The connection shows as **Online** on the Integrations page.

**4. Publish an endpoint:**

```sh
execonnect endpoint add --tls-server-name api.internal api https://10.0.0.15:8443
```

**5. Use it from a VM.** Click **Add HTTP proxy** next to the endpoint on the
Integrations page, or run:

```
exe.dev ▶ integrations add http-proxy --name=internal-api --external-connection=office --endpoint=api --no-auth --attach=vm:my-vm
exe.dev ▶ ssh my-vm curl https://internal-api.int.exe.xyz/health
```

All other [HTTP Proxy](integrations-http-proxy) options work as usual;
`--external-connection` and `--endpoint` take the place of `--target`.

## Endpoints

```sh
execonnect endpoint add    [--tls-server-name NAME] NAME URL
execonnect endpoint update [--tls-server-name NAME] NAME URL
execonnect endpoint remove NAME
execonnect endpoint list
```

- `NAME` is a lowercase DNS label and can't be renamed.
- `URL` is `http://` or `https://` with no path. It's resolved on the
  `execonnect` machine.
- `--tls-server-name` sets the name used to verify TLS. It defaults to the URL
  host; set it when the URL is an IP address.

## Status and troubleshooting

`execonnect status` shows enrollment, tunnel, and endpoint state. Logs are in
`journalctl -u execonnect`.

| Status | Meaning |
|---|---|
| **Awaiting enrollment** | `execonnect enroll` hasn't run yet. |
| **Online** | Connected. |
| **Degraded** | Partly connected; reconnecting. |
| **Offline** | `execonnect` isn't running or can't reach exe.dev. |

- **`invalid enrollment token`**: the token was already used or the connection
  was deleted. Create a new connection.
- **Online, but requests fail**: check that the service is reachable from the
  `execonnect` machine itself, e.g. with `curl`.

## Managing the service

The installer adds an `execonnect` user and group, the binary at
`/usr/local/bin/execonnect`, and a systemd unit. State is kept in
`/var/lib/execonnect`. To let another user run `execonnect` commands, add them
to the `execonnect` group. Anyone in it can change what's published.

To delete a connection and the integrations it backs, use the Integrations
page or run `integrations setup execonnect -d --name=office`.

To upgrade, rerun the install script. To uninstall:

```sh
sudo systemctl disable --now execonnect
sudo rm /etc/systemd/system/execonnect.service /usr/local/bin/execonnect
sudo rm -r /var/lib/execonnect   # forgets enrollment and endpoints
```

Releases are on [GitHub](https://github.com/boldsoftware/exe.dev/releases);
the source is in
[`execonnect/`](https://github.com/boldsoftware/exe.dev/tree/main/execonnect).
