16

I have a network bastion which is publicly accessible at example.compute-1.amazonaws.com and a private postgres database instance at postgres.example.us-east-1.rds.amazonaws.com:5432

I can ssh into the bastion using

$ ssh -i key.pem ec2-user@example.compute-1.amazonaws.com

Then once I'm in the bastion I create a ssh tunnel with:

$ ssh -i key.pem -L 5432:postgres.example.us-east-1.rds.amazonaws.com:5432 ec2-user@example.compute-1.amazonaws.com

I can then verify that the tunnel works by connecting to the database from the bastion using localhost:

$ psql -p 5432 -h localhost -U postgres

However, I am unable to connect to the database remotely (without being in the bastion).

$ psql -p 5432 -h example.compute-1.amazonaws.com -U postgres
psql: could not connect to server: Connection refused
Is the server running on host "example.compute-1.amazonaws.com" () and accepting
TCP/IP connections on port 5432?

I've configured the security group of the bastion to accept inbound traffic on port 5432.

Am I using ssh -L correctly? Should I be using it outside the bastion? Any advice would be much appreciated.

Snubber
  • 323
  • 1
  • 2
  • 6

2 Answers2

22

When you create an SSH tunnel, it does not expose the opened port to the outside world. The opened port, is only available as localhost. So effectively what you've done is to create a tunnel from your bastion, to your bastion.

Instead, what you want to do is create a tunnel from your local computer through your bastion.

So, you create your tunnel as part of your connection from your local computer to your bastion. You do not need to create another SSH connection.

So, locally, you would execute:

$ ssh -i key.pem -L 5432:postgres.example.us-east-1.rds.amazonaws.com:5432 ec2-user@example.compute-1.amazonaws.com

Assuming postgres.example.us-east-1.rds.amazonaws.com resolves to the private IP address.

Then to connect to your server, still locally, connect as if the server was local:

$ psql -p 5432 -h localhost -U postgres

Doing this, there's no need to use a prompt on your bastion.

Matt Houser
  • 10,053
  • 1
  • 28
  • 28
  • This worked for me, thanks! The one thing I did forget for anyone who's psql command just hangs there: Make sure that your db security group allows access from the bastion. – Goran Apr 13 '18 at 05:31
-1

This worked for me. Make sure you have psql client installed locally.

psql --host=myAwsDbEndpointUrl.ciqykqusf0nv.us-west-1.rds.amazonaws.com --port=5432 --username=myUserName --password --dbname=myDbName

When creating your db instance on aws, make sure to define the following:

  1. username
  2. password
  3. database name
  4. port number

I also had to create a security group for the VPC that the database was located in. After creating it make sure your db instance uses this for its security group. The security group has the following rules:

inbound--> type:PostgreSQL, protocol:TCP port range:5432, source:0.0.0.0/0

outbound--> type:All Traffic, protocol:All, port range:all, destination:0.0.0.0/0
Tim Siwula
  • 107
  • 3
  • That is not going via a bastion though, right? You are just connecting directly to RDS – RhysC Jan 27 '17 at 02:27
  • It goes through a vpc that the rds instance is exposed through. You attach the vpc to the rds instance upon creation. – Tim Siwula Jan 27 '17 at 03:36
  • Yeah i think the original question was with regard to going via a bastion server in the VPC so the RDS instance is not publicly exposed (well thats how i read it) – RhysC Jan 27 '17 at 05:59
  • That was not the question and your answer doesn't help solving the problem at all. – Radko Dinev Sep 21 '18 at 08:08