Some database hosting methods are far more secure than others.
In this post, I want to delve into one of the more secure methods leveraging Virtual Private Clouds (VPCs), subnets, security groups, and bastion hosts to protect your PostgreSQL instance from public exposure.
At work, we’ve been investigating the migration of some of our data from DynamoDB to Amazon RDS for PostgreSQL. While Dynam oDB has served us well, we encountered certain limitations that make RDS a better fit for our current project. As part of this migration, I needed to set up a PostgreSQL instance in RDS and ensure it was securely isolated from public internet access.
A Virtual Private Cloud (VPC) is a foundational element in AWS that allows you to isolate resources in your AWS environment. When you place your PostgreSQL instance within a VPC, it’s no longer accessible to the public internet by default. This isolation is crucial in preventing unauthorized access and potential attacks.
In AWS, a VPC is tied to a specific region, so the first step is to create a VPC in the region where your database will reside. Once you have your VPC, you can then start building out the network architecture within it.
Within a VPC, subnets are used to allocate specific IP address ranges to different sections of your network. These IP ranges are defined using CIDR (Classless Inter-Domain Routing) blocks. For example, you might create a private subnet with a CIDR block of 10.0.6.0/24, which allows for up to 256 IP addresses. Subnets can be public or private. A private subnet is crucial for security because it ensures that instances within it, such as your PostgreSQL database, are not directly accessible from the internet. Instead, they can only be accessed by other resources within the VPC or via controlled access points like bastion hosts.
Security Groups: Controlling Access at the Instance Level :
Security groups act as virtual firewalls for your AWS resources, allowing you to specify which traffic is permitted to reach your PostgreSQL instance. For instance, you might configure a security group to only allow incoming connections from specific IP addresses or from other security groups within your VPC.
For example, if you have a Lambda function that needs to access your PostgreSQL instance, you would create a security group for the Lambda and configure the database’s security group to allow inbound traffic from the Lambda’s security group. This setup ensures that only authorized services within your VPC can communicate with your database.
Bastion Hosts: Securely Accessing Your Private Resources
One challenge with placing your database in a private subnet is how to access it for administrative tasks, such as running migration scripts or performing maintenance. This is where a bastion host comes into play. A bastion host is an EC2 instance in a public subnet that serves as a secure entry point to your private network. By setting up an SSH tunnel through the bastion host, you can securely connect to your PostgreSQL instance without exposing it to the internet. You can further secure this setup by configuring the bastion host’s security group to only allow SSH access from specific IP addresses, such as your office or CI/CD pipeline.
Implementing Multi-Region Failover with VPC Peering
In many enterprise environments, high availability and disaster recovery are critical. To achieve this, you might need to deploy your database across multiple regions. AWS makes this possible with VPC peering, which allows you to connect VPCs in different regions as if they were part of a single network. With VPC peering, you can replicate your PostgreSQL database across regions, ensuring that your application can fail over to a backup region in the event of an outage. Each region would have its own VPC, subnets, security groups, and bastion hosts, but the peering connection allows seamless communication between them.
Logging and Monitoring: Ensuring Ongoing Security:
Security doesn’t end with setting up your VPC, subnets, and bastion hosts. Ongoing logging and monitoring are essential to detect and respond to potential threats. For instance, you should enable logging on your Bastion host to track all access attempts and commands executed. Additionally, consider setting up AWS CloudWatch and AWS Config to monitor the state of your VPC and its resources continuously. By logging all interactions with your PostgreSQL instance and other critical infrastructure, you can quickly identify and respond to any suspicious activity.
Wrapping Up:
Locking down your PostgreSQL database in AWS isn’t just a checkbox—it’s critical. Using VPCs, subnets, security groups, and bastion hosts, you create a strong defense that keeps your data safe.
As cloud setups get more complex, knowing these basics is a must for anyone in DevOps, cloud engineering, or IT security. I hope this helps you tackle similar challenges with confidence.
This blog post was inspired by the insights shared in the AWS Online Tech Talk on securing PostgreSQL databases by https://x.com/webdevcody I’ve expanded on the concepts discussed in the video and provided additional details for a deeper understanding.
Want to be the first to know about new courses release dates? Subscribe and we'll make sure it happens!
We make great coffee! Visit our HQ, and let’s chat over a cup.