Setup SSH Tunneling To Access AWS EC2 & RDS Resources With PuTTY
Accessing AWS resources, such as a Linux EC2 machine or a PostgreSQL database hosted on RDS, from your local development machine can be a little bit tricky, since these resources are generally recommended not to be exposed to the Internet and involves a technique called SSH tunneling.
In this post, I will quickly walk through the steps necessary to create the SSH tunnels necessary to access an EC2 machine and a RDS database sitting on internal subnets in AWS from a Windows terminal using the PuTTY tool (henceforth referred to simply as “Putty”).
Not only will this article show you how to create a SSH terminal connection to an EC2 machine, but it will also show you how you can setup pgAdmin to connect and administer a RDS hosted PostgreSQL database without having to expose the RDS instance on a public subnet!
- You will need the .PEM/.PPK file used to connect to the AWS resources.
- A EC2 machine configured as a Bastion host in a public subnet along with the public IP address of the Bastion.
- The internal IP address for the EC2 machine, running in a private subnet, you want to connect to.
- An RDS instance of PostgreSQL, running on a internal subnet and not publicly accessible. You will also need the RDS endpoint/user/password that you want to connect to (in our case we are using a PostgreSQL DB running on port 5432)
- A Windows machine running the PuTTY client and the pgAdmin client.
What is SSH Tunneling?
To connect to EC2/RDS machines, you will use a concept called SSH tunneling.
An SSH tunnel is a way to create a secure connection from a local computer to a remote one over a SSH connection done by mapping a local port on your machine to a remote IP address/port combination.
The SSH tunnel created by PuTTY will forward data sent to these local ports to the remote IP/port and then return back the response.
In our example, we will connect to the Bastion host over SSH and then through that Bastion host we will create a SSH tunnel from our local ports to the remote EC2/RDS machines.
The Bastion serves a jump box that intercepts the forwarded data and then pushes it on to the downstream system.
Steps to Creating SSH Tunnels with Putty
Create Putty Connection #1 from the Host to the Bastion
- Open Putty, under Host Name, put the public IP address of your Bastion host, and specify Port 22.
- Under SSH->Auth:
- Select the .PPK file as the private key for authentication
- Check the box marked “Allow Agent Forwarding”
- Under SSH->Tunnels
- Source port: Choose a local port which is not being used on your machine, for example 6000.
- Destination port: Input <Internal IP Address of EC2 Machine>:22 and click Add.In the above, I have mapped the local port 6000 to the EC2 at 172.31.25.107 at remote port 22.
- Save the connection so you can use it for future use, name it “Bastion-EC2”
- Click “Open” and you should be connected to the Bastion host machine, login with “ec2-user” (if the Bastion host is running Amazon Linux)
- Leave this connection open while you move on to configure the next connection.
Create Putty Connection #2 from the Host to the EC2 machine
This second connection will sit on top of Putty Connection #2 and leverage the SSH tunnel setup within it to connect to the EC2 machine.
This connection itself will then setup another SSH tunnel that will run through the EC2 connection and map a local port on the Host to the RDS server endpoint and port.
- Under Host Name, set IP Address: 127.0.0.1 and Port: to be the same port configured as the local port in the SSH tunnel from the previous step (in our example that would be 6000)
- Under SSH->Auth
- Select the PPK file as the private key for authentication
- Check the box marked “Allow Agent Forwarding”
- Under SSH->Tunnels, you will now create a tunnel through the EC2 machine to the RDS machine:
- Source port. Choose an open port on your local machine (ie. 60000)
- Destination: <RDS endpoint>:5432 (assuming you are connecting to a Postgres DB listening on 5432, if SQL server this should be 1433)
- Save the connection for future use, name it “Bastion-EC2”
- Click Open, you should be prompted to login to the EC2 machine using “ec2-user”. Once logged in do an “ifconfig” to verify the internal IP address shown is that of the Ec2 machine.
- Leave this connection open.
Connect pgAdmin to Remote RDS Endpoint
With both connections left open, you can then access the remote PostgreSQL database using pgAdmin running on your host.
To setup the connection in PGAdmin:
- Create a new Server
- Under Connection, input:
- Host: 127.0.0.1
- Port: the local port specified in Putty Connection #2 (ie. 60000)
- Input the username,password to connect to PostgreSQL
- Click Save and then Connect.
Note that in order for this to work, you need to always make sure Putty Connection #1 is up and running before starting Putty Connection #2.
Once Putty Connection #2 is running, then you should be able to use PGAdmin to access the remote RDS database.
While in this article I have shown how to connect to a PostgreSQL database using SSH tunneling, the same steps can be used to setup a connection from a local instance of SQL Server Management Studio to access a remote SQL Server running on RDS, the only difference is the destination port changes from 5432 to 1433.
Blue Label Labs Is Hiring
We are looking for exceptional people to join our exceptional team and build great things together.See Our Current Open Positions