21 January 2021

AWS SSM Session Manager Port Forwarding to RDS without SSH

While port forwarding using AWS System Manager Session Manager is trivial if you need to forward traffic to a service running on the remote host you connect to, things become more complicated as soon as you need to take an extra hop.

A good example where you need an extra hop is when you start an SSM Session Manager tunnel on your local machine to access an RDS database running privately on AWS. To achieve this, you will need something to forward traffic from the remote EC2 instance to the managed service. To take this extra hurdle I use socat.

Use socat (SOcket CAT) for port forwarding on the remote host

To install and run socat on the remote EC2 instance you need to establish a secure connection with the host first. I highly recommend AWS Session Manager for remote shell access instead of SSH. If you’re not familiar with that approach I can highly recommend reading: Keep up with the times: forget SSH, welcome AWS Session Manager

Login into the remote host using Session Manager:

aws ssm start-session --target <id-of-an-instance>

Install socat on the jump host:

sudo yum install -y socat

Create a bidirectional byte stream from the EC2 instance to RDS:

sudo socat TCP-LISTEN:3306,reuseaddr,fork TCP4:mysql-database.rds.amazonaws.com:3306

BTW: All the examples in this article are for MySQL, for other database types change the port numbers.

Create a tunnel to RDS using Session Manager

In another window you can now start a second SSM Session Manger session for port forwarding:

aws ssm start-session --target <id-of-an-instance> --document-name AWS-StartPortForwardingSession --parameters '{"portNumber":["3306"], "localPortNumber":["3306"]}'

You’re ready to locally connect to a privately running RDS on AWS.

mysql --port=3306 --host=127.0.0.1 -psome_password -u some_user

Limitations

Once you close a local MySQL connection, it seems necessary to close the Session Manager forwarding session as well. I was unable to reuse the same port forwarding session to establish another MySQL connection.

A little note on SSL errors

My first attempts to start a local MySQL connection failed due to SSL connection errors. To fix this, I had to import the RDS certificates into my local trust store and reboot my system.

In case that wouldn’t help I recommend reading Updating applications to connect to MySQL DB instances using new SSL/TLS certificates

Enjoy and until next time!