AWS Security Groups: The Firewall I Had to Learn to Think About Differently
When I first started looking at AWS networking, Security Groups seemed pretty straightforward: allow some traffic, block some traffic, and move on.
When networking meets security
When you start learning networking, one of the first things you learn is that not every device should be able to communicate with every other device.
The same idea applies to cloud environments.
An EC2 instance might need to receive HTTPS traffic from the internet.
But does it really need SSH access from the entire internet?
Does a database need to be publicly reachable?
Should an application server be able to communicate with every resource in the network?
These questions are where AWS Security Groups become really interesting.
Security Groups are not just about opening and closing ports.
They are part of the architecture.
What exactly is a Security Group?
A Security Group acts as a virtual firewall for AWS resources such as EC2 instances.
It controls inbound and outbound traffic using rules based on protocol, port, and source or destination.
A simple example looks like this:
Internet
↓
Security Group
↓
EC2 Instance
↓
Application
↓
Security Group
↓
EC2 Instance
↓
Application
But the important part isn't just the port.
We also need to think about the source.
For example:
Port: 443
Protocol: TCP
Source: 0.0.0.0/0
Protocol: TCP
Source: 0.0.0.0/0
This allows HTTPS traffic from anywhere on the IPv4 internet.
For a public web server, that can be completely reasonable.
Now consider this:
Port: 22
Protocol: TCP
Source: 0.0.0.0/0
Protocol: TCP
Source: 0.0.0.0/0
Now SSH is open to the entire internet.
That doesn't automatically mean the server is compromised, but it does mean we should stop and ask:
Does SSH really need to be accessible from everywhere?
In many environments, the answer will be no.
The problem with “just open the port”
One of the easiest mistakes to make when setting up an environment is opening a port simply because something isn't working.
The thought process can become:
“The application can't connect.”
Open the port.
“Still doesn't work.”
Open another port.
“Now it works.”
Done.
The problem is that we solved the connectivity problem without necessarily solving the security problem.
This is something I think is important for anyone learning cloud security:
A connection working doesn't automatically mean the configuration is secure.
We should understand why that traffic is necessary.
A better approach is to start with the requirement.
For example:
- The web server needs HTTPS access from the internet.
- The application server needs to receive traffic from the web server.
- The database needs to receive traffic from the application server.
That gives us a much clearer architecture:
Internet
↓
Web Server
↓
Application Server
↓
Database
↓
Web Server
↓
Application Server
↓
Database
Now each layer has a specific reason to communicate with the next one.
Security Groups can reference other Security Groups
This is one of the concepts I find particularly useful.
Instead of allowing an application server to access a database from a large IP range, we can create a rule based on the Security Group associated with the application servers.
For example:
Database Security Group
Allow: TCP 3306
Source: Application Server Security Group
Source: Application Server Security Group
Now the rule expresses something much closer to the actual architecture:
“The database accepts MySQL traffic from the application servers.”
That's very different from allowing database traffic from an entire network.
It also makes the rule easier to understand later.
Public doesn't always mean wrong
Another thing I've learned is that not every public-facing resource is a security problem.
A web server is expected to receive traffic from the internet.
For example:
HTTPS
Port: 443
Source: 0.0.0.0/0
Port: 443
Source: 0.0.0.0/0
That can be completely normal.
The important question is what happens after the traffic reaches the resource.
A public web server might be expected.
A public database usually deserves a very different conversation.
So instead of asking:
“Is this resource public?”
I think a better question is:
“Does this resource need to be public?”
That small change in thinking can make a big difference.
Thinking in layers
Imagine a simple application:
Internet
↓
Web Server
↓
Application Server
↓
Database
↓
Web Server
↓
Application Server
↓
Database
We can think about access like this:
Web Server
HTTPS traffic from the internet.
Application Server
Traffic only from the Web Server.
Database
Database traffic only from the Application Server.
So the communication becomes:
Internet
↓ HTTPS
Web Server
↓ Application Traffic
Application Server
↓ Database Traffic
Database
↓ HTTPS
Web Server
↓ Application Traffic
Application Server
↓ Database Traffic
Database
Each layer has a reason to communicate with the next one.
This is much better than putting everything into one large network and allowing broad communication between resources.
What about outbound traffic?
It's also important to remember that Security Groups control outbound traffic.
A lot of people focus mainly on inbound rules.
But outbound communication matters too.
If a compromised instance can communicate freely with almost anything, that may increase the potential impact of an incident.
This is where network architecture and egress controls become important.
Again, the goal isn't necessarily to block everything.
The goal is to understand what communication is actually required.
A simple security mindset
When I review a Security Group, I try to think through a few questions:
Who needs to communicate with this resource?
What protocol do they need?
Which port is actually required?
Where is the traffic coming from?
Does the source need to be the entire internet?
Could the source be another Security Group instead?
Is the rule still necessary?
These questions are often more valuable than simply memorizing which ports are commonly used.
Security is about reducing unnecessary access
When I think about Security Groups now, I try to follow a simple process:
1. Identify the resource.
2. Identify who needs to communicate with it.
3. Identify the required protocol and port.
4. Restrict the source as much as possible.
5. Review whether the rule still makes sense.
It sounds simple, but this mindset can prevent a lot of unnecessary exposure.
Final thoughts
Security Groups are a good example of how cloud security connects directly with networking.
It's not just about memorizing ports.
It's about understanding communication between systems.
A secure rule isn't necessarily the one with the most restrictions.
It's the one that allows the required communication while avoiding unnecessary access.
When I look at a Security Group now, I don't just ask:
“What port is open?”
I ask:
“Who can reach this resource, why do they need to reach it, and what happens if that access is abused?”
That's the kind of thinking I want to keep developing as I continue learning AWS and Cloud Security.
Enjoyed reading this content? Let the author know!
Your likes, comments, shares, and saves help creators reach more builders.
Loading recommendations
Loading article