Securely Connect to Private AWS RDS Using Bastion Proxy and SSM — No Public Access Needed
Keeping AWS resources like RDS private is crucial for security, but connecting to those private database instances can be a bit of a hassle. Typically, you’d need to set up a bastion server to act as a proxy to your private resources. However, each time you want to connect, you often have to go through the extra step of adding a rule to the bastion’s security group to allow SSH access from your IP. This is what enables your database client to connect through the bastion.
Today, I’m here to offer a simpler solution: using AWS Systems Manager (SSM) to connect through a bastion server without needing public access. With this method, you can skip the repetitive task of updating security group rules to allow your IP. Let’s dive in and explore how this can save you time and effort.
But first, let’s take a quick look at what AWS Systems Manager (SSM) is. SSM is a service that provides browser-based interactive shell access, a command-line interface (CLI), and remote desktop access for managing instances in your cloud environment, as well as on-premises or edge devices.
Prerequisites:
- A nano EC2 instance.
- AWS CLI and Session Manager plugin installed locally.
- Proper IAM permissions for SSM and session access.
First, create a bastion ec2 instance and install the SSM agent on your bastion server by following the instructions in this documentation. This instance is configured with no inbound rules in its security group and has no key pairs attached, making it essentially a “dumb” EC2 instance that runs only the SSM agent. Its sole purpose is to proxy connections, requiring minimal compute resources. As such, t4g.nano
the smallest available instance type can be used for this purpose.
Now coming back to your local machine, run the following command after updating the placeholders with your specific configurations:
aws ssm start-session \
--target <bastion_instance_id> \
--document-name AWS-StartPortForwardingSession \
--parameters '{"host":["<rds_endpoint>"],"portNumber":["5432"], "localPortNumber":["5434"]}' \
--profile <aws_profile_name>
Let’s break down the command step by step:
<bastion_instance_id>
: Replace with the actual instance ID of your bastion EC2.AWS-StartPortForwardingSession
: Use the correct SSM document for port forwarding (change it if you’re using a different SSM document).<rds_endpoint>
: Replace this with the actual endpoint of your RDS instance.<aws_profile_name>
: Replace with the actual profile name you’re using in your AWS CLI config (if necessary)."localPortNumber": ["5434"]
: The local port on your machine where the connection will be forwarded (you'll connect tolocalhost:5434
instead of the direct RDS endpoint).
This command will allow you to set up a port forwarding session between your local machine and an RDS instance in a private VPC, using the bastion instance as a proxy. Once the session is established, you can connect to your RDS via localhost:5434
, which is forwarded to the actual RDS endpoint on the port 5432
.
Now using your database client of choice, set up your connection information as shown below with username, password, and database should all match the target RDS database.
By using AWS Systems Manager and a jump server, you can securely access your private RDS instance without exposing it to the public internet. This method eliminates the need for repetitive tasks like adjusting security group rules and allows for a more streamlined connection process. Not only does this enhance security, but it also simplifies the management of your AWS resources, saving you valuable time. With SSM, you can maintain strong security practices while keeping things efficient and easy to manage.