In the previous article, we answered a fundamental question:
How does one server find another server?
We explored DNS, Private DNS, and Service Discovery the mechanisms that turn something like:
postgres.internal.company
into a reachable destination inside a network.
But finding a server is only half of the story.
Knowing where a server is doesn't automatically mean you're allowed to connect to it.
That leads us to a more interesting question.
Most developers eventually learn this architecture:
User
β
Application
β
Database
But how does this actually work at the network level?
If the application can connect to PostgreSQL, why can't someone on the Internet connect to the same database?
This sounds like a simple networking question.
It isn't.
The answer involves:
- Network routing
- Public and private subnets
- VPCs
- Security groups
- Firewall rules
- Network isolation
- Access boundaries
- Defense in depth
And these concepts ultimately determine something much bigger:
Which systems are allowed to talk to which other systems?
That's one of the most important questions in production infrastructure.
Because there is a critical difference between:
Can I find the server?
and:
Can I reach the server?
And an even more important difference between:
Can I reach the server?
and:
Am I allowed to connect?
In the previous article, we focused on finding the destination.
In this article, we'll focus on controlling access to that destination.
Let's break it down.
The Architecture We Usually See
Imagine a typical SaaS application:
Internet
β
βΌ
Load Balancer
β
βΌ
Application
β
βΌ
PostgreSQL
The application needs the database.
Customers don't.
That distinction is extremely important.
The customer needs:
Internet
β
Application
The application needs:
Application
β
Database
But there should usually be no direct path like this:
Internet
β
Database
This is where cloud networking starts becoming interesting.
The First Principle: Not Everything Needs to Be Reachable
A common mistake in infrastructure design is thinking:
If a service needs to work,
it should be reachable.
Modern infrastructure follows almost the opposite principle:
Make only what needs to be reachable,
reachable.
For example:
Public
β
βββ Load Balancer
β
βββ API Gateway
Private
β
βββ Application Servers
βββ Background Workers
βββ Redis
βββ PostgreSQL
The database doesn't need to accept connections from the public Internet.
So why expose it?
You don't.
This simple decision dramatically reduces the attack surface.
Public Subnet vs Private Subnet
Inside a cloud network such as a VPC, resources are commonly organized into different network boundaries.
Two of the most important concepts are:
Public Subnet
Private Subnet
Think about a building.
There might be:
Public Area
β
Reception
Meeting Room
Waiting Area
And deeper inside:
Restricted Area
β
Operations
Finance
Infrastructure
Records
Not everyone who can enter the building should be able to enter every room.
Cloud networks work with a similar principle.
What Is a Public Subnet?
A public subnet is a subnet whose routing configuration provides a path toward an Internet Gateway.
Resources placed there can be Internet-facing when their own network configuration also permits it for example, when they have a public IP or are exposed through a public load balancer.
Typical examples include:
Load Balancers
Reverse Proxies
Internet-facing Web Servers
Bastion Hosts
A simplified architecture might look like:
Internet
β
βΌ
Internet Gateway
β
βΌ
Public Subnet
β
βΌ
Load Balancer
This is where Internet-facing traffic enters the system.
What Is a Private Subnet?
A private subnet is designed for resources that should not be directly reachable from the public Internet.
Typical resources include:
Application Servers
PostgreSQL
MySQL
Redis
RabbitMQ
Kafka
Background Workers
Internal Services
A simplified architecture:
Internet
β
β
βΌ
Private Subnet
β
βββ Application
βββ Redis
βββ PostgreSQL
The important idea is not:
"Nobody can access these machines."
It is:
"They are not directly reachable from the public Internet."
That distinction matters.
Private Does Not Mean Isolated
This is one of the most common misunderstandings.
Many developers hear:
Private Subnet
and think:
Nothing can connect to it.
Not true.
A private subnet can communicate with other resources inside the same VPC.
For example:
Application Server
10.0.1.10
β
βΌ
PostgreSQL
10.0.2.20
Both resources may exist inside:
VPC
10.0.0.0/16
The traffic can remain inside the cloud network.
It doesn't need to travel across the public Internet.
So How Does the App Reach the Database?
Suppose:
Application Server
10.0.1.10
needs to connect to:
PostgreSQL
10.0.2.20:5432
The application creates a TCP connection:
10.0.1.10
β
β TCP :5432
βΌ
10.0.2.20
The VPC routing system determines how packets should move between those network destinations.
If the route exists and the relevant security controls permit the traffic, the connection succeeds.
There is no requirement for the database to have a public IP.
In fact, keeping the database private is usually the safer design.
Then What Stops Everyone Else?
This is where Security Groups become important.
Routing answers:
Where should this packet go?
Security controls answer:
Is this traffic allowed?
These are different questions.
Security Groups: The Access Control Layer
In AWS, a Security Group acts as a stateful virtual firewall associated with resources such as EC2 instances and certain managed services.
Imagine a building.
The subnet is the area of the building.
The security group is the access control at the door.
The database exists.
The network path may exist.
But access can still be restricted.
For PostgreSQL, the standard port is:
5432
A dangerous rule might look like:
Inbound
Port: 5432
Source: 0.0.0.0/0
That effectively allows connection attempts from anywhere that can reach the database.
That is rarely what you want for a production database.
The Better Rule
Instead of:
Allow everyone
define:
Allow application servers
For example:
Database Security Group
β
βββ Inbound
β
βββ Protocol: TCP
βββ Port: 5432
βββ Source: App Security Group
Now the access relationship becomes:
Internet User
β
Random Server
β
Unrelated Service
β
Application Server
β
This is much more meaningful than simply allowing a large IP range.
Why Security Group References Matter
Consider an application running on multiple servers.
Initially:
10.0.1.10
So someone might configure:
Allow 10.0.1.10 β PostgreSQL:5432
Then autoscaling happens.
Now there are:
10.0.1.10
10.0.1.11
10.0.1.12
10.0.1.13
Tomorrow there may be twenty.
The infrastructure is dynamic.
Hardcoding individual IP addresses creates unnecessary operational complexity.
Instead, define an application security group:
app-sg
Attach it to application servers.
Then configure the database:
db-sg
Inbound:
5432
Source:
app-sg
Now the rule expresses the actual architectural relationship:
Application Layer
β
β allowed
βΌ
Database Layer
The exact server IP becomes less important.
Network Access Is a Chain of Decisions
A database connection isn't simply:
Can I ping the database?
Multiple layers can influence whether traffic succeeds.
Conceptually:
Application
β
βΌ
DNS Resolution
β
βΌ
Route
β
βΌ
Network ACL
β
βΌ
Security Group
β
βΌ
Database Listener
β
βΌ
PostgreSQL
If any required layer is incorrectly configured, the connection can fail.
This is why production networking can feel confusing.
There isn't always one single "firewall."
There are multiple boundaries.
A Production-Style Architecture
A more realistic architecture might look like this:
Internet
β
βΌ
βββββββββββββββββββ
β Load Balancer β
β Public β
ββββββββββ¬βββββββββ
β
βΌ
βββββββββββββββββββ
β Application β
β Servers β
β Private β
ββββββββββ¬βββββββββ
β
ββββββββββββ΄βββββββββββ
β β
βΌ βΌ
ββββββββββββββββ ββββββββββββββββ
β Redis β β PostgreSQL β
β Private β β Private β
ββββββββββββββββ ββββββββββββββββ
Notice the boundaries.
The Internet can reach the load balancer.
The load balancer can reach the application.
The application can reach PostgreSQL.
But the Internet does not get a direct path to PostgreSQL.
This Is Defense in Depth
Now imagine the application itself contains a vulnerability.
An attacker manages to compromise a public-facing component.
A poorly designed network might look like:
Compromised Server
β
βββ Database β
βββ Redis β
βββ Internal APIs β
βββ Everything Else β
The blast radius becomes enormous.
A better architecture might look like:
Compromised Server
β
βββ Database β
βββ Redis β
βββ Internal Service β
βββ Other Systems β
The attacker may still have compromised one component.
But the compromise doesn't automatically become a compromise of the entire environment.
That is the value of segmentation.
Security Is About Blast Radius
One of the most useful ways to think about infrastructure security is:
What happens if one component is compromised?
Not:
Can anything ever be hacked?
That second question is unrealistic.
Production systems should be designed with the assumption that individual components can fail or become compromised.
The goal is to limit the damage.
For example:
Internet
β
βΌ
Public Service
β
βΌ
Private Application
β
βΌ
Private Database
Each layer has a limited set of allowed relationships.
This creates smaller blast radiuses.
Why This Matters Beyond Security
Network isolation isn't only about preventing attackers.
It also improves operational control.
Suppose a database is publicly accessible.
Then many different systems can potentially attempt to connect:
Internet
β
βββ Bots
βββ Scanners
βββ Attackers
βββ Unknown Services
βββ Legitimate Clients
Now the database must deal with traffic it never needed in the first place.
A private database changes the model:
Application Layer
β
βΌ
Database
The allowed communication becomes explicit.
That improves:
- Security
- Reliability
- Troubleshooting
- Operational visibility
- Compliance
- Change management
The Business Impact Is Hidden in the Architecture
A network diagram may look purely technical.
But every boundary represents a business decision.
Consider a database containing:
Customer Accounts
Payment Records
Orders
Personal Information
Internal Business Data
If that database is accidentally exposed, the consequences can extend far beyond engineering:
Misconfiguration
β
Unauthorized Access
β
Data Exposure
β
Incident Response
β
Downtime / Investigation
β
Customer Impact
β
Financial & Reputation Cost
The infrastructure decision happened at the technical layer.
The consequences don't stay there.
This is why architecture is ultimately connected to business continuity.
"Nobody Knows the Database IP" Is Not Security
Another common assumption is:
Nobody knows my database IP.
Therefore:
I'm safe.
That's security through obscurity.
A better assumption is:
Assume the attacker knows the address.
Then ask:
Can they establish a connection?
If the answer is:
No route
+
No public exposure
+
Security group denies access
then knowing the address doesn't help much.
The important boundary is not secrecy.
It is reachability and authorization.
Public Exposure vs Private Access
Let's compare the two models.
Public Database
Internet
β
βΌ
Public IP
β
βΌ
PostgreSQL:5432
The database is directly exposed to Internet traffic.
Even if authentication is strong, the attack surface is unnecessarily large.
Private Database
Internet
β
β
β
βΌ
Private Network
β
βΌ
PostgreSQL:5432
And:
Application
β
β
βΌ
PostgreSQL:5432
The database only needs to serve the application.
So the network should reflect that requirement.
A Simple Mental Model
Think of your infrastructure as a building.
STREET
β
βΌ
Public Lobby
β
βΌ
Employee Area
β
βΌ
Vault
The public can enter the lobby.
Employees can enter restricted areas.
Only authorized systems can reach the vault.
Now translate that into cloud architecture:
Internet
β
βΌ
Public Subnet
β
βΌ
Private Application Layer
β
βΌ
Private Database Layer
And Security Groups define:
Who can move between the layers.
That's the mental model worth remembering.
The Bigger Engineering Principle
A strong production architecture doesn't ask:
How do we make everything communicate?
It asks:
What actually needs to communicate?
Then it creates the smallest set of allowed paths.
For example:
Load Balancer
β
βΌ
Application
β
ββββββββΊ PostgreSQL
β
ββββββββΊ Redis
But:
Internet βββββXβββββΊ PostgreSQL
Internet βββββXβββββΊ Redis
Redis βββββββββXβββββΊ PostgreSQL
unless those connections are explicitly required.
This is the principle of least privilege applied to networking.
Key Takeaways
- Public subnets are designed for Internet-facing resources.
- Private subnets are used for resources that should not be directly reachable from the public Internet.
- A private subnet does not mean the resources inside it cannot communicate.
- VPC routing enables communication between private resources when routes exist.
- Security Groups control which traffic is allowed.
- Databases generally should not be directly exposed to the public Internet.
- Security Group references can express application-to-database relationships more effectively than hardcoded IP addresses.
- Network segmentation limits blast radius when a component is compromised.
- Security is not about making systems unreachable.
- Security is about making only the necessary systems reachable by the necessary systems.
- Infrastructure decisions can directly affect security, reliability, compliance, operational cost, and customer trust.
The most important idea is simple:
Great infrastructure is not about
making everything reachable.
Great infrastructure is about
making only the right things reachable.
Top comments (0)