Network Security
Session 4.7 · ~5 min read
The Network as Attack Surface
Every network packet that enters your system is a potential attack vector. Network security is the practice of controlling which packets are allowed in, which are allowed out, and what happens to the ones that break the rules. In cloud environments, this means layering multiple controls so that no single misconfiguration exposes your entire system.
Defense in depth means every layer assumes every other layer has been compromised.
This is not paranoia. It is engineering discipline. A security group misconfiguration should not expose your database to the internet. A compromised web server should not give an attacker free movement through your private network. Each layer of defense operates independently, so a failure at one layer does not cascade into a total breach.
Security Groups vs. Network ACLs
AWS provides two distinct mechanisms for controlling network traffic: Security Groups and Network Access Control Lists (NACLs). They operate at different levels, follow different rules, and serve different purposes. Understanding the distinction is essential for designing secure VPC architectures.
Security Groups: Stateful, Instance-Level
A Security Group acts as a virtual firewall attached to an elastic network interface (ENI). It operates at the instance level. When you allow inbound traffic on port 443, the return traffic is automatically allowed. This is what "stateful" means: the firewall remembers the connection and permits its response without an explicit outbound rule.
Security Groups evaluate all rules before deciding. There is no rule ordering. If any rule permits the traffic, it passes. The default behavior is deny-all inbound and allow-all outbound.
NACLs: Stateless, Subnet-Level
A Network ACL is attached to a subnet. Every instance in that subnet is automatically subject to its rules. NACLs are stateless: if you allow inbound traffic on port 443, you must also create an explicit outbound rule for the response traffic. If you forget the outbound rule, the connection breaks silently.
NACLs evaluate rules in order, starting from the lowest rule number. The first matching rule wins, and evaluation stops. Rule ordering matters. A deny rule at number 100 overrides an allow rule at number 200.
Comparison
| Dimension | Security Group | Network ACL |
|---|---|---|
| Scope | Instance (ENI) level | Subnet level |
| State tracking | Stateful (return traffic auto-allowed) | Stateless (return traffic needs explicit rule) |
| Rule evaluation | All rules evaluated; any allow wins | Rules evaluated in order; first match wins |
| Default behavior | Deny all inbound, allow all outbound | Allow all inbound and outbound |
| Allow/Deny rules | Allow rules only | Both allow and deny rules |
| Assignment | Must be explicitly assigned to instance | Automatically applies to all instances in subnet |
| Use case | Fine-grained, per-service access control | Coarse-grained subnet guardrails, IP blocking |
| Typical role | Primary firewall | Secondary defense layer |
In practice, Security Groups handle most access control. NACLs serve as a safety net: broad rules that block known-bad IP ranges, enforce subnet isolation, or provide a fallback if a Security Group is misconfigured.
IDS vs. IPS
Firewalls filter traffic based on rules you define in advance. But what about attacks that look like legitimate traffic? A SQL injection arrives on port 443, just like a normal HTTPS request. A firewall cannot tell the difference.
Intrusion Detection Systems (IDS) and Intrusion Prevention Systems (IPS) inspect packet contents, not just headers. They look for patterns that match known attack signatures or statistical anomalies that suggest an attack in progress.
The difference between them is action. An IDS detects and alerts. An IPS detects and blocks. An IDS sits on a mirror port or tap, passively observing traffic. An IPS sits inline, actively intercepting and filtering traffic. An IDS that misses an attack produces a missed alert. An IPS that produces a false positive drops legitimate traffic.
The trade-off is clear: IPS gives you automated blocking at the cost of potential false positives. IDS gives you visibility without the risk of accidentally breaking production. Many organizations start with IDS to build confidence in their rules, then switch to IPS once false positive rates are low enough.
Web Application Firewall (WAF)
A WAF operates at Layer 7 (HTTP/HTTPS). It inspects request bodies, headers, query strings, and URL paths for patterns associated with web application attacks: SQL injection, cross-site scripting (XSS), path traversal, and other OWASP Top 10 threats.
AWS WAF, Cloudflare WAF, and similar services let you define rules, use managed rule sets, and create rate-limiting policies. A well-configured WAF blocks the most common automated attacks before they reach your application code.
A WAF is not a replacement for writing secure code. It is a filter that catches the obvious attacks. A determined attacker who understands your application can craft requests that bypass WAF rules. Defense in depth means the WAF catches the 90% of attacks that follow known patterns, and your application code handles the rest through proper input validation and output encoding.
VPC Design for Defense in Depth
A well-designed VPC separates resources into subnets based on their exposure level. The goal: minimize the blast radius of any single compromise. If an attacker gains access to a web server, they should not be able to reach the database directly.
Load Balancer"] NAT["NAT Gateway"] end subgraph Private["Private Subnet (10.0.2.0/24)"] App1["App Server 1"] App2["App Server 2"] end subgraph Isolated["Isolated Subnet (10.0.3.0/24)"] DB1["Primary DB"] DB2["Replica DB"] end end IGW --> ALB ALB -->|"SG: 443 only"| App1 ALB -->|"SG: 443 only"| App2 App1 -->|"SG: 5432 only"| DB1 App2 -->|"SG: 5432 only"| DB2 App1 --> NAT NAT --> IGW style Public fill:#2a2a28,stroke:#6b8f71,color:#ede9e3 style Private fill:#2a2a28,stroke:#c8a882,color:#ede9e3 style Isolated fill:#2a2a28,stroke:#c47a5a,color:#ede9e3 style VPC fill:#191918,stroke:#8a8478,color:#ede9e3
Three Subnet Tiers
Public subnet. Contains resources that need direct internet access: load balancers, NAT gateways, bastion hosts. Has a route to the internet gateway. Resources here get public IP addresses. Security Groups restrict inbound traffic to specific ports (80, 443).
Private subnet. Contains application servers. No direct internet access. Outbound internet traffic (for package updates, API calls) routes through a NAT gateway in the public subnet. Inbound traffic comes only from the load balancer. Security Groups allow traffic only from the ALB's Security Group.
Isolated subnet. Contains databases and other sensitive data stores. No internet access at all, not even through NAT. No route to any internet gateway. The only allowed inbound traffic comes from the application servers' Security Group on the database port. This is the most restricted tier.
Security Controls at Each Boundary
| Boundary | Controls |
|---|---|
| Internet to Public Subnet | NACL (allow 80/443, deny known-bad IPs), WAF (filter L7 attacks), Security Group on ALB (allow 80/443 from 0.0.0.0/0) |
| Public to Private Subnet | NACL (restrict to ALB source), Security Group on App (allow from ALB SG only) |
| Private to Isolated Subnet | NACL (restrict to App subnet CIDR), Security Group on DB (allow port 5432 from App SG only) |
| Isolated to Internet | No route exists. Blocked by design, not by rules. |
Notice the last row. The isolated subnet does not rely on a rule to block internet access. It has no route to the internet gateway. This is structural security: the capability does not exist, so it cannot be misconfigured. This is stronger than any firewall rule.
Further Reading
- Control Subnet Traffic with Network Access Control Lists (AWS Documentation)
- VPC with Servers in Private Subnets and NAT (AWS Documentation)
- Infrastructure Security in Amazon VPC (AWS Documentation)
- OWASP Top 10: 2021 (OWASP Foundation)
Assignment
Design a VPC for a three-tier web application. Your system has a public-facing load balancer, a fleet of application servers, and a PostgreSQL database cluster.
- Draw the VPC with three subnet tiers (public, private, isolated). Label CIDR ranges.
- For each boundary between tiers, specify the Security Group rules (protocol, port, source).
- Write NACL rules for the private subnet. Remember: NACLs are stateless. What happens if you forget ephemeral port ranges for return traffic?
- Where does the WAF sit in this architecture? What does it protect against that Security Groups cannot?
- An attacker compromises one application server. What can they reach? What can they not reach? Why?