Let's say you need to connect to an AWS RDS Postgres database in a private subnet. If you have an EC2 instance or ECS task with execute command enabled, you can create a reverse tunnel to it and connect to the database through that.
# For EC2 instance
TARGET=$(aws ec2 describe-instances \
--filters "Name=tag:Name,Values=my-ec2-name" \
--query "Reservations[0].Instances[0].InstanceId" \
--output text)
# For ECS task
TARGET=$(aws ecs list-tasks \
--cluster my-cluster \
--service-name my-service \
--query "taskArns[0]" \
--output text)
aws ssm start-session \
--target "$TARGET" \
--document-name AWS-StartPortForwardingSessionToRemoteHost \
--parameters '{"portNumber":["5432"], "localPortNumber": ["5432"], "host": ["yourdb.cluster-ro-xxxxxxxxxxxx.us-west-2.rds.amazonaws.com"]}'
Now let's say you want to connect to that database from a virtual machine or Docker container that doesn't have access to the host's localhost
. You can use socat
to forward the port to 0.0.0.0
and connect to that.
socat TCP-LISTEN:25432,fork,reuseaddr TCP:localhost:5432
In this example, you could connect to the database at yourhost:25432
.