ecure Database Access in AWS Using SSH Tunneling
Accessing databases located in private subnets within AWS Virtual Private Clouds (VPCs) is a common requirement in enterprise architectures. To ensure secure connectivity without exposing the database to the public internet, developers and operations engineers often employ SSH tunneling via a bastion host.
Background
Databases in a private subnet cannot be accessed directly from external networks for security reasons. However, there are situations where engineers need to connect from a local development environment to such a database instance for debugging, data verification, or administrative purposes. SSH tunneling offers a secure and controlled mechanism to achieve this.
Architecture
The typical setup includes:
- A database instance (e.g., PostgreSQL or MySQL) within a private subnet.
- A bastion host (EC2 instance) in a public subnet with SSH access enabled.
- Security groups configured to allow:
- SSH access to the bastion from the developer’s IP.
- Database access from the bastion host only.
SSH Tunnel Command
To create an SSH tunnel from the local machine to the private database through the bastion, the following command is used:
ssh -i /path/to/key.pem -L local_port:db_internal_endpoint:db_port ec2-user@bastion_public_ip
For example, to forward the local port 5432 to a PostgreSQL instance accessible to the bastion on port 5432:
ssh -i ~/.ssh/my-key.pem -L 5432:db.internal.local:5432 ec2-user@13.45.67.89
This command creates a tunnel from localhost:5432 on the developer’s machine to the internal address db.internal.local:5432, routed through the bastion host.
Usage
Once the tunnel is established, the database can be accessed as if it were local:
psql -h localhost -p 5432 -U db_user -d db_name
Any client software (such as DBeaver, pgAdmin, or CLI tools) can connect to localhost on the forwarded port.
Notes
- The SSH key used must match the key pair configured for the EC2 instance.
- The SSH user must match the AMI; for Amazon Linux, it is typically
ec2-user. - For long-running sessions or background use,
-f(background) and-N(no command) can be added:
ssh -f -N -i ~/.ssh/my-key.pem -L 5432:db.internal.local:5432 ec2-user@13.45.67.89
Security Considerations
- Ensure the bastion host only accepts connections from known IP ranges.
- Use firewall rules and security groups to limit access to the database to the bastion host only.
- Rotate SSH keys regularly and enforce the use of strong key pairs.
- Audit SSH access and database queries periodically.
Alternatives
While SSH tunneling is effective for ad hoc access, it is not recommended for production workloads. Alternative approaches include:
- AWS Systems Manager Session Manager, which enables tunnel-less secure access to private resources without needing an open SSH port.
- VPN or AWS Direct Connect, for more stable and scalable network access.
- PrivateLink or Transit Gateway, for managed, private, inter-service communication within AWS.
Conclusion
SSH tunneling remains a valuable technique for secure, temporary access to private infrastructure in AWS. It should be used judiciously, following best practices and supplemented by more robust networking solutions for long-term or automated access.