In some AWS setups, you may have an RDS (Relational Database Service) instance located within a private subnet, making it inaccessible from the public internet. To access this RDS instance remotely without installing a bastion server or relying on public-facing EC2 instances, you can use AWS Systems Manager Session Manager along with SSH port forwarding. This article guides you through the process.
Assumptions
Before we dive into the steps, let's establish a few assumptions:
- There is no bastion instance serving as a gateway for external access.
- No security groups are configured to provide external access.
- You have an EC2 instance running within the same private subnet as the RDS instance.
- This EC2 instance is running on an Ubuntu-based operating system.
Prerequisites
Install ec2-instance-connect
on EC2 instance
- You can install
ec2-instance-connect
by connecting to an existing EC2 instance using AWS Session Manager and running the following command:
apt-get install ec2-instance-connect
Note: If you use autoscaling groups or blue/green deployments, you can include this installation in the EC2 user data to ensure ec2-instance-connect is installed when a new server is created.
- Install
session-manager-plugin
locally (https://docs.aws.amazon.com/systems-manager/latest/userguide/session-manager-working-with-install-plugin.html)
Create an SSH Key
You will need an SSH key to connect to the EC2 instance. If you already have one, you can skip this step. To create an SSH key, run:
ssh-keygen -f my_rsa
This will generate SSH private and public keys named my_rsa and my_rsa.pub.
Push Your SSH Key to the Target Instance
To connect to the EC2 instance, send the SSH public key to the desired EC2 instance using the following command:
aws ec2-instance-connect send-ssh-public-key \
--instance-id i-0c6e3bd52bbb2373c \
--availability-zone eu-west-1a \
--instance-os-user ubuntu \
--ssh-public-key file:///my_rsa.pub
Note: The SSH public keys are available for one-time use for 60 seconds in the instance metadata. To connect successfully, use SSH within this time window. There is no need to track or manage these keys directly.
Start an AWS System Manager Session
Start an AWS System Manager session and enable port forwarding. In this case, forward port 9999 on your local machine to port 22 on the target EC2 instance:
aws ssm start-session \
--target i-0c6e3bd52bbb2373c \
--document-name AWS-StartPortForwardingSession \
--parameters '{"portNumber":"22", "localPortNumber":"9999"}'
Open a Tunnel to RDS (in Another Terminal)
To open a tunnel to your RDS instance via the AWS System Manager session you created above, use the following command:
ssh ubuntu@localhost \
-p 9999 \
-N \
-L 3388:production-database.inzy2e1e4v6s.eu-west-1.rds.amazonaws.com:3306
Note: This command may appear to hang because it maintains a tunnelling connection between port 3388 on localhost and port 3306 on production-database.inzy2e1e4v6s.eu-west-1.rds.amazonaws.com via the EC2 instance i-07edf50160ab3172.
Connect to Your RDS Instance
With the above steps complete, you can now use your favourite database client (e.g., SequelPro, HeidiSQL) to connect to your RDS database. The connection details will be as follows:
- Host: localhost
- Port: 3388
- Username / Password: As per the live database you are trying to access
You should now have access to your RDS instance.
Originally published at https://chrisshennan.com/blog/using-aws-systems-manager-and-ssh-to-access-an-rds-instance