Color Mode


    Language

Accessing AWS RDS databases remotely with no exposed ports

August 18, 2022

Ok, I admit it. The title might sounds weird because, how it is supposed to connect to an SQL service without a port, right? Well the catch is that there IS a port, but it is not an inbound port, therefore nothing is exposed. And it is fully managed by AWS. Interesting, right? Keep reading to know more.

What scenario do we have?

Following best practices, database must always be inside the private subnet, i.e. no access to/from the internet by default, and the only allowed inbound access is from the deployed application in the same VPC. However, you can think of many scenarios/use cases, where developer needs to access the databases from outside the VPC, for example: for development/debug purposes, the access from the local developer machine is needed... etc

If we add some fences, it looks more like this.

It means the database is inside a private subnet that can be accessed only by the backend. The way the backend is connected with the frontend would vary a lot, so to simplify it, lets just put an arrow from users.

The daily basis tasks requires to get connected to the database to tweak some data, so how do we do that?

The most common scenario is something like this:

  • A bastion host instance is added into the same subnet like the backend instances but with a very small instance size. It can even be turned on and off to save some money.
  • This bastion has an Ubuntu or an Amazon Linux, and the 22 port open to an SSH server.
  • The SSH server requires public keys of the users that will connect to it.
  • The user uses some database client software that can manage tunneling, or creates the tunnel manually right before the SQL connection and engage the task.
  • Besides the host, the user and the database password; she needs to have the private keys that matches the public keys of the bastion already configured.
  • We know every key must be rotated periodically and the comply of this security measure depends on humans; therefore, it is very common that you find very old keys which are still in use. I am sure you've seen such keys before.

What happens when that user finishes her services with the company? Those keys need to be removed from every bastion host and any other key she had contact with its correspondent private key must be rotated. It could be lot of work. And if it fails, the person will still have access to the database instance. It is a huge risk.

A better approach

A respected company must have SSO access to authorize users into AWS accounts with very specific roles. And every user must have MFA. We can use that.

It is very important to do not use IAM users. To bring temporary access key id and its correspondent secret access key from the SSO service we use SAML2AWS. And needless to say that IAM creation permissions should not be granted to anyone.

Also, we will use the SSM console access feature provided by the AWS System Manager Session Manager tool. This tool has CLI connection capabilities similar to those already provided by SSH, but without the downsides of requiring inbounds ports open nor maintenance of key pairs. Can you see where are we going with it? It just requires to have the SSM Agent installed into the bastion host and all inbound ports closed by the security group.

The most powerful components of the tool are the System Management Documents which describe actions that can be performed inside the managed system. In this case, we will use AWS-StartPortForwardingSessionToRemoteHost which reflects exactly the action we need.

Let's see it in action! With a command like the following, we create a tunnel from your computer passing through the bastion host, directly to the RDS instance into the correct port.

aws ssm start-session \
  --region eu-west-2 \
  --target i-fafafafafafafa \
  --document-name AWS-StartPortForwardingSessionToRemoteHost \
  --parameters host="${RDS_HOST}",portNumber="3306",localPortNumber="3306"

It is something like this:

This is an example that assumes i-fafafafafafafa is the bastion host's instance ID located in the London region and the database port is 3306 because we are using MySQL engines. But you will adjust it accordingly depending on your resources.

Extra tip to get the INSTANCE's Id if you have a bastion host with tags; and the RDS_HOST from a Bash command line interface. Useful for scripting and automation:

INSTANCE=$(aws ec2 describe-instances \
  --query "Reservations[].Instances[].InstanceId" \
  --filters "Name=tag-value,Values=bastion" \
  --output text \
)
RDS_HOST=$(aws rds describe-db-cluster-endpoints \
  --query="DBClusterEndpoints[?EndpointType=='WRITER'].Endpoint" \
   --output=text \
)

Now you can:

mysql -u your_rds_user -p -h 127.0.0.1 --ssl-mode=disabled

If the administrator needs to revoke the user's access for any reason, they can do so with the attached roles in SSO. No need for RSA key files, IP addresses or ports, access_key/secret_id rotation, ... nothing.

Conclusion

By using the AWS SSM session manager, we create a temporary tunnel directly to the database instance while keeping all inbound ports closed and centralizing user access via SSO. This creates a secure environment without personal credentials and therefore does not need to be maintained in the face of an employee termination or similar event.

Article Photo by Dan Christie

awsrdssqldbadatabasesmysqlssmportportsmaintenanceinfrainfrastructure

Author

Juan Eduardo Castaño Nestares

Juan Eduardo Castaño Nestares

Engineer

Bash evangelist

You may also like

November 7, 2024

Introducing Shorebird, code push service for Flutter apps

Update Flutter apps without store review What is Shorebird? Shorebird is a service that allows Flutter apps to be updated directly at runtime. Removing the need to build and submit a new app version to Apple Store Connect or Play Console for review for ev...

Christofer Henriksson

Christofer Henriksson

Flutter

May 27, 2024

Introducing UCL Max AltPlay, a turn-by-turn real-time Football simulation

At this year's MonstarHacks, our goal was to elevate the sports experience to the next level with cutting-edge AI and machine learning technologies. With that in mind, we designed a unique solution for football fans that will open up new dimensions for wa...

Rayhan NabiRokon UddinArman Morshed

Rayhan Nabi, Rokon Uddin, Arman Morshed

MonstarHacks

ServicesCasesAbout Us
CareersThought LeadershipContact
© 2022 Monstarlab
Information Security PolicyPrivacy PolicyTerms of Service