> ## Documentation Index
> Fetch the complete documentation index at: https://www.integrate.io/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# Reverse SSH tunnel for ELT & CDC

> Configure a reverse SSH tunnel in Integrate.io ELT & CDC to securely connect to private databases behind a firewall without opening inbound network ports.

Reverse SSH tunneling allows customers behind strict firewalls to connect their databases to [Integrate.io](http://integrate.io/) without exposing any inbound ports. Instead of [Integrate.io](http://integrate.io/) connecting to your server, **you** initiate an outbound SSH connection to our public jumphost, which creates a port forward that our pipeline containers connect through.

## How It Works

1. You generate an SSH key pair on your machine
2. You provide the **public key** when creating the tunnel in [Integrate.io](http://integrate.io/)
3. [Integrate.io](http://integrate.io/) allocates a port and provides connection details
4. You run `autossh` to establish the reverse tunnel from your network to our jumphost
5. [Integrate.io](http://integrate.io/) pipelines connect through the tunnel to reach your database

## Prerequisites: Generate SSH Key

You need to generate an SSH key pair on the machine that will run `autossh`. The **private key** stays on your machine, the **public key** is pasted into [Integrate.io](http://integrate.io/).

Supported key type: `ssh-ed25519`

```
ssh-keygen -t ed25519 -f ~/.ssh/integrateio_reverse -N "" -C "integrateio-reverse-tunnel"
cat ~/.ssh/integrateio_reverse.pub
```

Copy the output of `cat` (starts with `ssh-ed25519`) and paste it into the **Your SSH Public Key** field in the next step.

## Setting Up a Reverse SSH Tunnel

### Step 1: Create a new Reverse SSH Tunnel

On the **Connection options** section of Source or Destination creation:

1. Select **Connect via secure tunnel**
2. Choose **Create a new tunnel**
3. Select **Reverse SSH Tunnel** from the tunnel type dropdown
4. Choose your **Region** (e.g. US East / us-east-1)
5. Enter a **Tunnel name**
6. Paste your **SSH public key** (generated in the prerequisites above)
7. Click **Create Reverse SSH Tunnel**

<Frame>
  <img src="https://mintcdn.com/integrateio/1q-uk8QqfVw7-nyh/images/cdc/security/reverse-ssh-tunnel/image-1.webp?fit=max&auto=format&n=1q-uk8QqfVw7-nyh&q=85&s=66c9ed9b5067b477f8b211029c869923" alt="Creating a new reverse SSH tunnel in Integrate.io" width="1200" height="1221" data-path="images/cdc/security/reverse-ssh-tunnel/image-1.webp" />
</Frame>

### Step 2: Copy the Tunnel Endpoint

After creation, you will see the **Tunnel Endpoint** (e.g. `virginia-tunnel.flydata.app:12345`). The status will show **Setup Complete** and **Inactive** until you establish the tunnel from your side.

<Frame>
  <img src="https://mintcdn.com/integrateio/1q-uk8QqfVw7-nyh/images/cdc/security/reverse-ssh-tunnel/image-2.webp?fit=max&auto=format&n=1q-uk8QqfVw7-nyh&q=85&s=f58f51447d7ee0d9ada8235f3c373062" alt="Tunnel endpoint details after creation" width="1196" height="310" data-path="images/cdc/security/reverse-ssh-tunnel/image-2.webp" />
</Frame>

### Step 3: Establish the Tunnel

The UI provides step-by-step setup instructions with pre-filled commands. All commands include your tunnel's endpoint, port, and hostname. Click **Copy** to copy each one.

<Frame>
  <img src="https://mintcdn.com/integrateio/1q-uk8QqfVw7-nyh/images/cdc/security/reverse-ssh-tunnel/image-3.webp?fit=max&auto=format&n=1q-uk8QqfVw7-nyh&q=85&s=92684285dfbb17241dc7fff52ee86974" alt="Establishing the reverse SSH tunnel connection" width="1200" height="803" data-path="images/cdc/security/reverse-ssh-tunnel/image-3.webp" />
</Frame>

**3a. Install autossh** on your server (or a server that has access to your database):

```
# Ubuntu/Debian
sudo apt-get install autossh

# CentOS/RHEL
sudo yum install autossh

# macOS
brew install autossh
```

**3b. Add Integrate.io's server to your known\_hosts:**

```
ssh-keyscan -p 50683 <jumphost> >> ~/.ssh/known_hosts
```

Example:

```
ssh-keyscan -p 50683 virginia-tunnel.flydata.app >> ~/.ssh/known_hosts
```

**3c. Test the connection:**

```
ssh -NR <allocated_port>:<your-db-host>:<your-db-port> sshtunnel@<jumphost> -i <path-to-private-key> -p 50683 -o "ExitOnForwardFailure yes" -o ServerAliveInterval=10 -o ServerAliveCountMax=1 -v
```

Example (MySQL on [localhost:3306](http://localhost:3306/), tunnel port 58115):

```
ssh -NR 58115:localhost:3306 sshtunnel@virginia-tunnel.flydata.app -i ~/.ssh/integrateio_reverse -p 50683 -o "ExitOnForwardFailure yes" -o ServerAliveInterval=10 -o ServerAliveCountMax=1 -v
```

You should see `remote forward success`. Press Ctrl+C to stop the test.

**3d. Run autossh for a persistent connection:**

```
AUTOSSH_GATETIME=0 autossh -M 0 -f -N -R <allocated_port>:<your-db-host>:<your-db-port> sshtunnel@<jumphost> -i <path-to-private-key> -p 50683 -o "ExitOnForwardFailure yes" -o ServerAliveInterval=10 -o ServerAliveCountMax=1
```

Example:

```
AUTOSSH_GATETIME=0 autossh -M 0 -f -N -R 58115:localhost:3306 sshtunnel@virginia-tunnel.flydata.app -i ~/.ssh/integrateio_reverse -p 50683 -o "ExitOnForwardFailure yes" -o ServerAliveInterval=10 -o ServerAliveCountMax=1
```

`AUTOSSH_GATETIME=0` prevents autossh from exiting if the first connection attempt takes longer than 30 seconds.

**3e. Add to crontab for automatic reconnect on reboot:**

Run `crontab -e` and add:

```
@reboot AUTOSSH_GATETIME=0 autossh -M 0 -f -N -R <allocated_port>:<your-db-host>:<your-db-port> sshtunnel@<jumphost> -i <path-to-private-key> -p 50683 -o "ExitOnForwardFailure yes" -o ServerAliveInterval=10 -o ServerAliveCountMax=1
```

### Step 4: Test the Tunnel Connection

Once your autossh is running, click **Test Tunnel Connection** in the [Integrate.io](http://integrate.io/) UI. A successful test shows three green checks:

* **Tunnel configuration.** Tunnel configured correctly
* **[Integrate.io](http://integrate.io/) Tunnel is Open.** Tunnel on [Integrate.io](http://integrate.io/) side is open
* **Connect to User Tunnel.** Successfully established connection with the user's tunnel

<Frame>
  <img src="https://mintcdn.com/integrateio/1q-uk8QqfVw7-nyh/images/cdc/security/reverse-ssh-tunnel/image-4.webp?fit=max&auto=format&n=1q-uk8QqfVw7-nyh&q=85&s=07aa7974b7314ab179111fcfbcfacb62" alt="Testing the tunnel connection with three green checks" width="1200" height="477" data-path="images/cdc/security/reverse-ssh-tunnel/image-4.webp" />
</Frame>

## Alternative: Run as a systemd service

For production environments, a systemd service is more robust than crontab:

Create `/etc/systemd/system/integrateio-reverse-tunnel.service`:

```
[Unit]
Description=Integrate.io Reverse SSH Tunnel
After=network-online.target
Wants=network-online.target

[Service]
Type=simple
User=<your_user>
ExecStart=/usr/bin/autossh -M 0 -N -R <allocated_port>:<your-db-host>:<your-db-port> sshtunnel@<jumphost> -i /home/<your_user>/.ssh/integrateio_reverse -p 50683 -o "ExitOnForwardFailure yes" -o ServerAliveInterval=10 -o ServerAliveCountMax=1
Environment="AUTOSSH_GATETIME=0"
Restart=always
RestartSec=5

[Install]
WantedBy=multi-user.target
```

Enable and start:

```
sudo systemctl daemon-reload
sudo systemctl enable integrateio-reverse-tunnel
sudo systemctl start integrateio-reverse-tunnel
sudo systemctl status integrateio-reverse-tunnel
```

## Related

<CardGroup cols={2}>
  <Card title="IP Allowlist" icon="arrow-right" href="/cdc/ip-list" horizontal />

  <Card title="PrivateLink for MySQL" icon="arrow-right" href="/cdc/privatelink-set-up" horizontal />

  <Card title="PrivateLink for PostgreSQL" icon="arrow-right" href="/cdc/postgresql-privatelink-set-up" horizontal />

  <Card title="SSH Tunnel" icon="arrow-right" href="/cdc/ssh-tunnel" horizontal />
</CardGroup>
