DEV Community

Cover image for Connect to a PostgreSQL Server via SSH Tunnel
Ben Force
Ben Force

Posted on • Originally published at justwriteapps.com

Connect to a PostgreSQL Server via SSH Tunnel

If you use a bastion server to access a postgresql, or any other sql database for that matter, you'll need
to create an ssh tunnel to access it. Some DB clients handle this automatically for you, but if you want to
interact with the database through the shell you'll need to create it yourself.

What is a SSH Tunnel?

Put simply, a ssh tunnel is a way to redirect requests to a port on localhost to a remote server.

SSH Tunnel Graph

Creating the Tunnel

Before creating the tunnel, you will need to know three things: the bastion server's hostname, your username on the bastion server, and the sql server's hostname. You should also verify that you can ssh into the bastion server. To do this, run the follwing command and enter your password when prompted.

ssh <username>@<bastion_server>
Enter fullscreen mode Exit fullscreen mode

Adding your Profile (Optional)

You can add your ssh key to the bastion server so that you don't have to type in your password every time you connect. To do so, use the following command:

ssh-copy-id <username>@<bastion_server>
Enter fullscreen mode Exit fullscreen mode

Open the Tunnel

Now that you know you can connect to the bastion server, open the tunnel like this:

ssh -L localhost:5433:<sql_server>:5432 <username>@<bastion_server>
Enter fullscreen mode Exit fullscreen mode

You should see the standard bash prompt that came up when you directly logged into the bastion server.
Leave this window open to keep the tunnel open. Now when you connect to the port 5433 on localhost,
you'll actually be talking to the sql server on port 5432!

To verify that your connection works, open a new terminal and execute:

psql --port=5433 --host=localhost -c "SELECT * FROM pg_catalog.pg_tables"
Enter fullscreen mode Exit fullscreen mode

You should see a list of tables returned.

Create SSH Config (Optional)

Okay, I forget the command to open a tunnel all the time. Plus it's a pain to have to look up the hostname of two servers every time you want to connect to the database. To simplify things, you can create a ssh config with all of the tunnel settings. Edit your ~/.ssh/config file and add the following entry:

Host bastion-production
  HostName <bastion_server>
  User <username>
  LocalForward localhost:5433 <sql_server>:5432
Enter fullscreen mode Exit fullscreen mode

Now to create the tunnel, just run ssh bastion-production and it will behave the same as the previous command.

Artwork

Photo by Daniel von Appen on Unsplash

Top comments (3)

Collapse
 
semlak profile image
Joseph • Edited

Thanks for this. I've been using ssh tunnels for over 20 years, but I've always struggled with configuring them.
This was the first time I set one up for a db connection with a bastion server in between, and I could not get it correct. These steps saved me.

Collapse
 
masihjahangiri profile image
Masih Jahangiri

This repo help you to automate Postgres backup from a remote server via SSH tunnel in a docker container (dockerized):
github.com/masihjahangiri/dcoker-p...

Collapse
 
thebenforce profile image
Ben Force

Thanks for sharing!