SSH, port forwarding and when to use it?
So you’ve just finished working on your little shiny app which will be a part of huge distributed system.
Today is the day! It goes onto production! But hey! You can’t connect to database. It’s behind thick firewall.
But no worries, you have access to prod bastion server. Simple ssh’ing into it should do the work. Nope!
It’s still inaccessible! Turns out you have to jump onto second bastion from the first, but… The second bastion does
not have DB client installed, and you have only one SSH configuration dialog in your pgAdmin. Where to put the second ssh config?!

Local port forwarding to the rescue!
Local port forwarding is a neat tool created just for such cases. It will forward port from remote service App through
a second host B2 onto first host B1. Then the services port will act like port local to first host. Thus you will be
able to ssh into your postgres from your local network into first host!
Ok, theory aside and let’s practice a lil’bit.
Lets say that our hosts are under following IPs/domains:
B1 - 192.0.0.1
B2 - 172.0.0.1
App - rds.xyz.amazon.com:5432
then to access the App (if you had a DB client on bastions) you could simple ssh to the B1 and hop onto B2 and voila!
grizwold@home:~$ ssh username@192.0.0.1
username@192.0.0.1's password:
Last login: Fri Aug 21 14:34:09 2020 from 127.0.0.1
[syscnt5u@ip-192-0-0-1 ~]$ ssh 172.0.0.1
username@172.0.0.1's password:
Last login: Fri Aug 21 14:34:34 2020 from 192.0.0.1
[syscnt5u@ip-172-0-0-1 ~]$ psql -h localhost -U my-apps-db-user -d my-apps-db
Password for user my-apps-db-user:
psql (9.6.6, server 10.7)
my-apps-db=> SELECT * FROM user
my-apps-db-> ;
name | role | pass
-----------+-------+------
grizwold | ADMIN | dupa
but! You don’t have psql on B2 bastion! So let’s use local port forwarding, shall we?
First you need to open a connection to B2 which will forward the port from our App. To do this login to B1 and forward a port
by utilizing this command: ssh -L 5432:rds.xyz.amazon.com:5432 172.0.0.1
grizwold@home:~$ ssh username@192.0.0.1
username@192.0.0.1's password:
Last login: Fri Aug 21 14:34:09 2020 from 127.0.0.1
[syscnt5u@ip-192-0-0-1 ~]$ ssh -L 5432:rds.xyz.amazon.com:5432 172.0.0.1
username@172.0.0.1's password:
Last login: Fri Aug 21 14:34:34 2020 from 192.0.0.1
[syscnt5u@ip-172-0-0-1 ~]$
and leave it as is. Then open second terminal and simply connect to the App on B1 just like it were running there on localhost
grizwold@home:~$ ssh username@192.0.0.1
username@192.0.0.1's password:
Last login: Fri Aug 21 14:34:09 2020 from 127.0.0.1
[syscnt5u@ip-192-0-0-1 ~]$ psql -h localhost -U my-apps-db-user -d my-apps-db
Password for user my-apps-db-user:
psql (9.6.6, server 10.7)
my-apps-db=> SELECT * FROM user
my-apps-db-> ;
name | role | pass
-----------+-------+------
grizwold | ADMIN | dupa
What’s more! You can even forward the local forwarded port further onto you local machine and use the App on your local machine.
Or just simply configure your local pgAdmin to ssh into B1 and use it like the App were there and not behind B2.
Yet more details on the command used? Let’s slice it:

ssh -L 5432:rds.xyz.amazon.com:5432 172.0.0.1
-
-Lmeans you want to open local port on which traffic will be directed to specified host behind next bastion. -
first
5432means that this local port will be open and directed to specified external port. That is if I had this local port already open I can specify any other port to be used as myAppentry point, so you are not forced to use same port as external service. -
rds.xyz.amazon.com:5432is the host behindB2which will be attached to our newly open local port. It can belocalhostif you wanted to attach something which is local toB2. -
Finally, last but not least:
172.0.0.1is an address of ourB2obviously.
Our job just started to be easier, and it really surprised me that many people forgot about this little, useful feature.