# How to Configure SSH Tunnel Connections in DBX: A Complete Guide

> Learn how to configure SSH tunnel connections in DBX for secure database access. Our guide explains how DBX automatically establishes tunnels for local port forwarding.

- Repository: [skyler/dbx](https://github.com/t8y2/dbx)
- Tags: how-to-guide
- Published: 2026-07-10

---

**DBX enables secure database access through firewalls and private networks by automatically establishing SSH tunnels defined in the Tunnel/Proxy tab, which the core runtime translates into local port forwarding.**

The open-source **t8y2/dbx** repository provides a database client that supports SSH tunneling to reach databases behind bastion hosts or restricted networks. Understanding how to configure SSH tunnel connections in DBX allows you to securely bridge local applications to remote database servers without exposing them to the public internet.

## How SSH Tunnels Work in DBX

DBX implements SSH tunneling through a layered architecture that converts configuration objects into active transport processes. According to the t8y2/dbx source code, the system handles tunnel creation through three primary components.

### Connection Model and Configuration

The foundation of SSH tunneling resides in the `SshTunnelConfig` struct defined in [`crates/dbx-core/src/models/connection.rs`](https://github.com/t8y2/dbx/blob/main/crates/dbx-core/src/models/connection.rs). Each connection record can contain an `ssh_tunnels` array describing one or more hops. The model parses JSON configuration into structured data that includes host, port, authentication credentials, and timeout settings.

### Transport Layer Builder

When a connection initializes, [`packages/node-core/src/connections.ts`](https://github.com/t8y2/dbx/blob/main/packages/node-core/src/connections.ts) inspects the `config.ssh_enabled` flag. If the configuration contains an `ssh_tunnels` array, the builder adds a transport layer of type `"ssh"` for each defined hop. This layer instructs the runtime to establish port forwarding before attempting database authentication.

### SSH Tunnel Manager

The core implementation in [`crates/dbx-core/src/db/transport_layer_tunnel.rs`](https://github.com/t8y2/dbx/blob/main/crates/dbx-core/src/db/transport_layer_tunnel.rs) receives the tunnel specifications and spawns a local SSH process. This process forwards traffic from a dynamically assigned local port (e.g., `127.0.0.1:54321`) to the remote database server through the SSH host. The manager stores sensitive credentials—such as key passphrases and passwords—under the `ssh_tunnels.*` prefix in the secret store located in [`crates/dbx-core/src/connection_secrets.rs`](https://github.com/t8y2/dbx/blob/main/crates/dbx-core/src/connection_secrets.rs).

## SSH Tunnel Configuration Options

DBX supports comprehensive SSH tunnel configuration through both the UI and programmatic APIs. The desktop interface component [`apps/desktop/src/components/connection/ConnectionDialog.vue`](https://github.com/t8y2/dbx/blob/main/apps/desktop/src/components/connection/ConnectionDialog.vue) renders input fields for the following parameters:

- **SSH Host** – Hostname or IP address of the SSH server (bastion or database host).
- **SSH Port** – TCP port for SSH service, defaulting to `22`.
- **SSH User** – Username for SSH authentication.
- **Connect Timeout** – Maximum seconds to wait when establishing the SSH session (default 5s).
- **Key Path** – Filesystem path to a private key file (e.g., `~/.ssh/id_rsa`).
- **Key Passphrase** – Passphrase for encrypted private keys.
- **Password** – Fallback authentication when key-based auth is unavailable.
- **LAN Exposure** – When enabled, binds the tunnel to `0.0.0.0` instead of localhost, allowing other devices on the local network to access the forwarded port.

## Step-by-Step Configuration Guide

To configure SSH tunnel connections in DBX using the desktop interface:

1. Open the **Connection Dialog** and navigate to the **Tunnel / Proxy** tab.
2. Click the **"+"** button to add an SSH tunnel hop.
3. Enter the **SSH Host**, **Port**, and **User** credentials.
4. Provide authentication via **Key Path** and optional **Key Passphrase**, or use **Password** authentication.
5. Enable **LAN Exposure** only if other local machines require access to the tunnel.
6. Click **Connect** – DBX automatically creates the local listener, spawns the SSH process, and routes database traffic through the tunnel.

## Programmatic Configuration Examples

### JSON Configuration Structure

The following JSON represents the internal storage format for SSH tunnel configurations as defined by the `SshTunnelConfig` struct:

```json
{
  "ssh_enabled": true,
  "ssh_tunnels": [
    {
      "id": "hop-1",
      "host": "bastion.example.com",
      "port": 22,
      "user": "dbadmin",
      "key_path": "~/.ssh/id_rsa",
      "key_passphrase": "my-secret-phrase",
      "connect_timeout_secs": 5
    }
  ]
}

```

This schema is parsed by [`crates/dbx-core/src/models/connection.rs`](https://github.com/t8y2/dbx/blob/main/crates/dbx-core/src/models/connection.rs) and consumed by the transport layer builder.

### Node-Core API Usage

You can programmatically open connections with SSH tunnels using the `@dbx/core` package:

```typescript
import { openConnection } from '@dbx/core';

const conn = await openConnection('prod-postgres', {
  ssh_enabled: true,
  ssh_tunnels: [
    {
      host: 'bastion.example.com',
      port: 22,
      user: 'dbadmin',
      key_path: '/home/user/.ssh/id_rsa',
      // key_passphrase is optional; omit if the key is not encrypted
    },
  ],
});

await conn.query('SELECT now()');
await conn.close();

```

The `ssh_tunnels` array is processed by [`packages/node-core/src/connections.ts`](https://github.com/t8y2/dbx/blob/main/packages/node-core/src/connections.ts), which constructs the appropriate transport layer stack.

### Accessing Local Port Information

For debugging or custom driver integration, retrieve the underlying local port:

```typescript
const { localPort } = await conn.getTransportInfo();
console.log(`Database driver connected through local port: ${localPort}`);
// Output: Database driver connected through local port: 127.0.0.1:54321

```

## Summary

- **Architecture**: DBX uses `SshTunnelConfig` structs, transport layer builders in [`connections.ts`](https://github.com/t8y2/dbx/blob/main/connections.ts), and the tunnel manager in [`transport_layer_tunnel.rs`](https://github.com/t8y2/dbx/blob/main/transport_layer_tunnel.rs) to establish SSH connections.
- **Security**: Credentials are stored securely under the `ssh_tunnels.*` prefix in [`connection_secrets.rs`](https://github.com/t8y2/dbx/blob/main/connection_secrets.rs).
- **Configuration**: Tunnels support key-based or password authentication, custom timeouts, and optional LAN exposure.
- **Implementation**: Both JSON configuration files and the Node-core API accept `ssh_enabled` and `ssh_tunnels` parameters to programmatically define tunnel hops.

## Frequently Asked Questions

### Where does DBX store SSH tunnel credentials?

DBX stores sensitive SSH credentials—including private key passphrases and passwords—in an encrypted secret store managed by [`crates/dbx-core/src/connection_secrets.rs`](https://github.com/t8y2/dbx/blob/main/crates/dbx-core/src/connection_secrets.rs). These values are keyed under the `ssh_tunnels.*` namespace and are never persisted in plain-text configuration files.

### Can I chain multiple SSH hops or bastion hosts?

Yes. The `ssh_tunnels` array in the connection configuration supports multiple hop objects. DBX processes each hop sequentially, creating a chain of forwarded ports that route traffic through intermediate bastion hosts before reaching the final database server.

### How does DBX handle encrypted SSH keys?

When you provide a `key_path` to an encrypted private key, DBX prompts for or accepts the `key_passphrase` parameter. The tunnel manager passes this passphrase to the underlying SSH process to decrypt the key during connection establishment, without exposing the secret in process logs.

### What is LAN Exposure and when should I use it?

**LAN Exposure** configures the local tunnel endpoint to bind to `0.0.0.0` rather than `127.0.0.1`, making the forwarded port accessible to other devices on your local network. Enable this only when other machines require database access through your DBX instance, and ensure your local firewall rules restrict unauthorized access.