DEV Community

loading...
Cover image for AWS Session Manager Port Forwarding to RDS (without SSH)
AWS Community Builders

AWS Session Manager Port Forwarding to RDS (without SSH)

glnds profile image Gert Leenders Originally published at element7.io Updated on ・2 min read

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>
Enter fullscreen mode Exit fullscreen mode

Install socat on the jump host:

sudo yum install -y socat
Enter fullscreen mode Exit fullscreen mode

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
Enter fullscreen mode Exit fullscreen mode

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"]}'
Enter fullscreen mode Exit fullscreen mode

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  
Enter fullscreen mode Exit fullscreen mode

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!

Discussion (3)

pic
Editor guide
Collapse
dineshrathee12 profile image
Dinesh Rathee

Nice one :)

Collapse
atoonk profile image
Andree Toonk

you may also like mysocket.io which provides this as a service, in a CDN type fashion

Collapse
glnds profile image
Gert Leenders Author

Although it seems a nice service and easy to set up, using mysocket.io targets public endpoints. The nice things about AWS Session manager is that it allows me to keep my endpoints secure (in this case RDS).