When You Secure the Building AND Room
If you’ve been following this series, most of the discussion so far has been about who holds the key: IAM roles instead of IAM users, temporary credentials instead of static access keys, X.509 certificates for workloads that live outside AWS. All of that matters, but a key is only useful if the building it opens still has walls.
This time we move from identity to the walls, gates, and cameras — the layers that determine whether a request can reach your resources at all. This is also one of the areas that comes up repeatedly on the AWS Certified Security Specialty (SCS-C03) exam, so treat this as both a mental model and a set of exam notes.
We’ll go from the smallest perimeter (a single subnet) out to DNS and disaster recovery.
Two Guards for the Same Building
Every AWS networking conversation eventually runs into the same two acronyms, and they get confused every time. Let’s settle it once and for all.
A security group is room security. It’s attached to a single room’s door — an EC2 instance, an RDS instance, anything with an ENI — and only cares about traffic entering or leaving that room.
A network ACL is building security. It sits at the subnet level and inspects everyone entering or leaving the building, regardless of which room they’re headed to.

This table shows up on the exam so often because the two controls look similar but fail in different ways. A security group with no explicit rule silently drops the traffic. A newly created custom NACL does the same including the outbound response to a request you already allowed until you remember it denies everything by default. This combination is behind more “why can’t I SSH into this” debugging sessions than almost anything else in networking.
Encrypting the Path Before Data Hits the Wire
Once you connect your own network to AWS via VPN or Direct Connect a different set of concerns kicks in.
You have three hybrid connectivity options: AWS-managed VPN (hardware-based), customer-managed VPN (software-based, running on an EC2 instance or your own device), and Direct Connect.
Whichever you choose, traffic in transit needs three things protected:
- Authentication: pre-shared key or digital certificate
- Integrity: hashing, typically SHA
- Encryption: IPsec
AWS-managed VPN enforces all three automatically. The only real reason to go with customer-managed VPN is needing an algorithm AWS doesn’t support.
IPsec itself isn’t a single protocol, it’s a suite made up of three parts:
- AH (Authentication Header) integrity and authentication, no encryption
- ESP (Encapsulating Security Payload) confidentiality, integrity, and authentication
- ISAKMP key exchange framework, either via manual pre-shared key or IKE
IKE itself negotiates in two phases. Phase 1 establishes a secure channel between the two peers, with the sole purpose of giving them a safe place to negotiate Phase 2. Phase 2 is where they agree on how the actual VPN traffic will be encrypted and authenticated.
An AWS-managed Site-to-Site VPN connection gives you two tunnels, each configured independently — its own Phase 1/2 encryption algorithm, integrity algorithm, Diffie-Hellman group, and IKE version. Both ends of the tunnel must agree on the same settings; if you lock your side to AES-256 and your on-prem device doesn’t support it, the tunnel simply won’t come up. As a rule of thumb: the higher the DH group number, the longer the key and the stronger the encryption.
While Direct Connect Isn’t Actually Encrypted
Here’s the trap that catches almost everyone at least once: Direct Connect is not encrypted by default. It’s a dedicated, private network connection, which feels like it should mean “secure”, but private and encrypted are two different properties. If you need encryption on Direct Connect, you have two options.
Option 1: Run a VPN over Direct Connect. This gives you a Public VIF (not a Private VIF — the distinction matters), advertises your customer gateway’s public IP and prefixes, and then layers a standard Site-to-Site VPN connection on top via a virtual private gateway or transit gateway. Result: Direct Connect’s low latency and high bandwidth, wrapped in a VPN’s encryption.
Option 2: Enable MACsec. This one is worth memorizing in detail, because its restrictions are exactly the kind of thing exam questions like to test:
- Provides confidentiality, integrity, and origin authenticity
- Works only on Dedicated connections — Hosted connections don’t support it
- Works only at 10 Gbps or 100 Gbps — a 1 Gbps connection doesn’t qualify
- Operates at Layer 2, is hardware-based, and is therefore faster than IPsec
- Uses the full bandwidth of the connection — a standard VPN tunnel caps out around 1.25 Gbps, MACsec has no such cap
- Requires support from both your on-prem device and your last-mile provider
If you remember nothing else from this section: whenever a question mentions Direct Connect and “encryption” in the same sentence, your first instinct should be to check whether encryption is actually turned on not assume it already is.
Bringing a Real Firewall to the VPC
Security groups and NACLs give you access control. What they don’t give you is deep packet inspection, intrusion prevention, or centralized logging across all of a VPC’s traffic. That’s the gap AWS Network Firewall fills.
It’s fully managed no infrastructure to patch, deployed in a few clicks — and supports fine-grained rules, importing open-source rule sets, and third-party threat intelligence feeds. It also integrates with Firewall Manager, so you can push policies across an entire organization instead of configuring every VPC by hand. Typical use cases: VPC-to-VPC inspection, outbound filtering, securing traffic over Direct Connect or VPN, and general internet traffic filtering.
A few features worth internalizing:
- High availability and automatic scaling, backed by a 99.99% SLA
- A stateful firewall remembers sessions and can filter by protocol without specifying a port
- Web filtering: unencrypted traffic is inspected directly; encrypted traffic is filtered using SNI (Server Name Indication)
- Built-in application-layer IPS (Intrusion Prevention System), protecting against exploits and brute-force attempts
- Centralized management and visibility rule grouping, compliance views
- Alerts and flow logs can be exported to S3, Kinesis, or CloudWatch
Where You Put the Firewall Changes Everything
Knowing Network Firewall exists is one thing. Knowing where to place it in your architecture is where the exam actually tries to catch you, because there are three deployment models, and each trades off cost, blast radius, and which traffic it can actually see.

Worth asking directly: if you have 50 VPCs and choose the distributed model, do you need 50 separate firewalls? Yes. That single fact tells you almost everything about when distributed makes sense (small blast radius, isolated workloads) and when it doesn’t (you’ll drown in management overhead long before VPC number 30).
Choosing the Right Guard for the Job
With three network-layer controls in play, the actual decision usually comes down to scope and depth:
- A security group protects an instance EC2 and other AWS-managed resources with an ENI.
- A NACL protects only the network and subnet, not the instance itself. It’s a “set it and forget it” layer you configure it once as a coarse guardrail and rarely touch it again.
- Network Firewall inspects all VPC traffic, adds alerting, logging, application-layer awareness, and ties into WAF, Shield, and Firewall Manager.
If you need full control, logging, and application-layer inspection, reach for Network Firewall. If you don’t, a NACL is genuinely enough there’s no need to over-engineer a subnet boundary that just needs to say “no” to a specific CIDR range.
Managing Every Guard in Every Building at Once
None of this matters much if you’re running a single AWS account. It matters a lot if you’re running fifty. AWS Firewall Manager exists to centrally manage security policy across multiple accounts, and it covers five services: AWS WAF, Shield Advanced, Network Firewall, VPC security groups, and Route 53 Resolver DNS Firewall.
Setting it up has a strict order of operations, and the exam likes to test that order:
- Choose which account will be the Firewall Manager admin account.
- This account must be part of AWS Organizations and critically, with “all features enabled,” not just consolidated billing. This is the most common stumbling point in this whole workflow.
- Configure this account as the Firewall Manager admin account.
- Enable AWS Config in every account and region you plan to protect.
- If you want Network Firewall or DNS Firewall policies, turn on “enable sharing with AWS Organizations” in AWS RAM.
- Turn on any regions that are disabled by default, in both the management account and the Firewall Manager admin account.
Once that’s done, Firewall Manager works through policies five types matching the five services it manages: WAF Policy, Shield Advanced Policy, Network Firewall Policy, VPC Security Group Policy, and Route 53 Resolver DNS Firewall Policy. Creating one generally follows five steps (Network Firewall and Security Group policies add a sixth): choose the policy type and region, define the policy itself (name, rules, action), define its scope (which accounts and resources, include/exclude by tag), optionally add tags, then review and create. Budget roughly $100 per policy per region, plus whatever AWS Config charges for the rule evaluations underneath.
Two policy types are worth a closer look. WAF policies run both before and after a Web ACL’s own rules account owners remain free to insert their own rules in between, a reasonable compromise between central control and local flexibility. Security Group policies come in three flavors: Common SG (distribute a new security group across the whole org), Audit & enforce (force existing rules into compliance), and Audit & cleanup (find and remove unused or redundant security groups).
Teaching the Guard to Recognize a Bad Visitor
Everything so far has been about where traffic is allowed to go. AWS WAF is about what that traffic actually contains. It sits in front of CloudFront, API Gateway REST APIs, Application Load Balancers, and AppSync GraphQL APIs, and is designed to catch the OWASP Top 10 — SQL injection, cross-site scripting — plus any custom criteria you define, like blocking specific IPs or entire countries.
(One note: two versions circulate in AWS’s own documentation — WAF Classic from before November 2019, and the current WAF. If you see “Classic” anywhere in an exam question, treat it as a historical footnote, not an answer.)
Here’s the component hierarchy, since everything else builds on top of it:
Web ACL (the main building block — default action: allow or block)
└── Rules (a statement + an action: allow / block / count)
└── Rule Groups (reusable collection of rules)
The traffic flow, at least for a resource sitting behind CloudFront, is simple: the user’s request hits CloudFront first, CloudFront forwards it to the Web ACL, WAF evaluates it, and the result comes back — allow means the request continues to CloudFront, block means it goes no further. The underlying principle generalizes well beyond WAF: the closer a security control sits to the perimeter, the less damage a bad request can do before it’s stopped.
Rules and Rule Groups, in More Detail
When adding rules to a Web ACL, you choose between Managed Rule Groups — maintained by AWS or vendors like F5, Fortinet, Imperva, GeoGuard — or writing your own.
The number that trips people up here is WCU, Web ACL Capacity Unit. Every Web ACL has a hard cap of 1,500 WCU. When you create a rule group, you set its immutable maximum capacity at creation time — and that number can never be changed afterward. The reason is subtle but important: if another Web ACL is also using that same rule group, letting its capacity grow unpredictably could push that other Web ACL over its own 1,500 limit without warning. Locking the cap upfront protects not just you, but everyone else sharing the rule group.
Custom rules generally take a few shapes:
- IP Set matches on source IP or an IP found in a header (you set up the IP set in CIDR format first, then reference it)
- Rule Builder a visual editor or raw JSON editor; for anything with nested AND/OR/NOT logic, writing the JSON directly is genuinely faster
- Rule Group created as a separate standalone object so it can be reused across Web ACLs
Rules themselves come in two types. Regular rules are a simple if/then with an allow, block, or count action. Rate-based rules count requests per source IP over a rolling 5-minute window — and their action can only be block or count. There’s no allow action for a rate-based rule, which makes sense given what the rule is for: it exists to say “too much,” never “not enough.”
Here’s a minimal example of what a rate-based rule looks like as JSON, the kind you could paste into the Rule Builder:
{
"Name": "LimitRequestsPerIP",
"Priority": 2,
"Statement": {
"RateBasedStatement": {
"Limit": 2000,
"AggregateKeyType": "IP"
}
},
"Action": { "Block": {} },
"VisibilityConfig": {
"SampledRequestsEnabled": true,
"CloudWatchMetricsEnabled": true,
"MetricName": "LimitRequestsPerIP"
}
}Priority matters here in a very literal sense: rules run in order, and the first match wins. A typical, sensible ordering looks like: whitelist IPs allowed first, blacklisted IPs blocked second, and known bad signatures SQLi, XSS patterns — blocked last. Reverse that order and a whitelisted IP can still get caught by a signature rule that fires before its allow rule ever gets a chance.
Demo Flow, Summarized
f you’re setting this up for the first time, the practical order is: create an IP Set (CIDR plus region), create a Rule Group and add rules to it while setting its max capacity, then create the Web ACL itself, attach it to a resource like a CloudFront distribution, add the rule group, and choose a default action.
One thing to watch: a rule group occupies the maximum capacity you set inside a Web ACL, not whatever WCU it’s currently using, whether or not its rules ever grow to fill that capacity. Plan your 1,500 WCU budget with that in mind.
When the Crowd Itself Is the Weapon
Everything so far assumed that traffic hitting your defenses was legitimate but unwanted. Sometimes it’s neither legitimate nor small it’s just volume, and the volume itself is the attack.
DoS is a flood from a single source. DDoS is a flood from many sources at once, usually a botnet a network of bots, one or more C&C (command and control) servers, and a botmaster coordinating the whole thing. Tools like LOIC and HOIC (Low/High Orbit Ion Cannon) made this kind of attack accessible to people with very little technical skill, which is part of why the threat has stayed so widespread.
Two attack patterns worth knowing by name:
- Ping Flood (ICMP flood) floods the target with ICMP echo requests. The attacker needs to know the target IP. A local-disclosed flood hits a single machine; a router-disclosed flood hits the entire network behind that router.
- SYN Flood exploits the TCP three-way handshake (SYN → SYN-ACK → ACK). The attacker sends a SYN, gets a SYN-ACK back, and never sends the final ACK usually while spoofing the source IP so there’s nowhere real to respond to. The result is a pile of half-open connections silently exhausting the server’s connection table.
Managed Protection: AWS Shield
AWS Shield is AWS’s managed response to these attack patterns, detecting and mitigating at Layer 3 (network), Layer 4 (transport), and Layer 7 (application).

If you’re building a CloudWatch dashboard around Shield, the metrics you actually want are: DDoSDetected, DDoSAttackBitsPerSecond and DDoSAttackPacketsPerSecond for L3/L4 events, and DDoSAttackRequestsPerSecond for L7.

Serving Content From the Edge, Not the Vault
Not every defense is about blocking traffic. Some of it is about never letting traffic reach the origin in the first place.
That’s why CloudFront is as much a security tool as a performance one: it caches content at 300+ edge locations, cutting latency for static content in S3 and dynamic content served from EC2 or Lambda.
Caching happens across three layers:
- Edge locations (300+)
- Regional edge caches (13)
- Origin Shield (optional, off by default, enable per origin) → better cache hit ratio, less load on your origin
On the security side, CloudFront gives you:
- Encrypted storage on its SSDs
- Signed URLs and Signed Cookies for restricting access
- Native WAF Web ACL integration
- Geo-restriction
- IAM-based control over who can manage the distribution
Two origin patterns come up constantly, and both share the same underlying risk: if there’s a second, unprotected path to your origin, CloudFront (and everything in front of it) is optional, not enforced.

Then lock the bucket down with an OAI (Origin Access Identity) and a bucket policy that trusts only that OAI public access is closed off entirely, and CloudFront becomes the only path to the content. Skip this step and the raw S3 bucket URL still works, meaning anyone who finds it can bypass CloudFront (and everything in front of it) just as easily as in the ALB pattern above.
The Phone Book That Runs the Internet
Underneath all of this sits DNS, and in AWS that’s Route 53. A Public Hosted Zone handles internet routing; a Private Hosted Zone handles resolution inside a VPC (both DNS Hostnames and DNS Support need to be enabled for it to work). Every hosted zone comes automatically with 4 NS records and 1 SOA record, whether you asked for them or not.

Health Checks
By default, Route 53 checks a resource’s health every 30 seconds (10-second checks are available at a higher cost), over TCP, HTTP, or HTTPS, with optional string matching against the first 5,120 bytes of the response. It can also watch a CloudWatch alarm’s state directly OK means healthy, ALARM means unhealthy, INSUFFICIENT can be configured either way. Watch for the trap here: a record with no health check attached is always considered healthy, silently, even if the resource behind it is completely down.

Two of these deserve extra attention. Simple routing genuinely cannot use a health check if you need failover logic, you’re on the wrong policy. And Geoproximity is locked behind Traffic Flow you can’t configure it through a plain record.
Traffic Flow itself is a visual editor that lets you combine multiple routing policies and health checks into a single, versioned Traffic Policy. A Policy Record binds that traffic policy to an actual domain or subdomain, and a single traffic policy can be reused to create hundreds of records across multiple hosted zones.
When the Whole Region Goes Down
Everything above assumed your infrastructure was up. Application Recovery Controller (ARC) exists for the moment it isn’t monitors and controls your application’s ability to recover across Availability Zones, regions, or on-prem.

The whole point of ARC comes down to this: “we have a backup region” and “we can safely fail over to that region” are two very different claims. ARC is what closes the gap between them.
Same Perimeter, Many Layers
Stepping back, a pattern emerges from everything above: nothing here operates in isolation, and none of it was designed to. A security group without a NACL is fine. A NACL without Network Firewall is fine. WAF without Shield is fine until it isn’t. AWS’s security model, at least in this area, is built on the assumption that any single layer will eventually fail or be misconfigured, and what actually saves you is the layer behind it.
If you’re preparing for the exam specifically, here’s a condensed list of the traps this area leans on most:
- Direct Connect is not encrypted by default
- MACsec only works on Dedicated connections at 10/100 Gbps never Hosted, never 1 Gbps
- NACLs are stateless, security groups are stateful
- A Web ACL caps out at 1,500 WCU, and rule groups reserve their immutable maximum, not their current usage
- Rate-based WAF rules can block or count never allow
- A CloudFront distribution’s ACM certificate must live in us-east-1
- An S3 origin without an OAI can be bypassed entirely
- Simple routing can’t use health checks
- Geoproximity only exists inside Traffic Flow
- Firewall Manager requires AWS Organizations with “all features” enabled consolidated billing alone isn’t enough
It’s the same lesson this series keeps arriving at, just applied one layer further out: identity gets you through the door, but for that identity to mean anything, the door, the walls, and the guard standing next to it actually need to be there and configured correctly.
Now that we’ve wrapped up the Data Protection part as well, we can slowly start to relax. We’re getting closer and closer to the end.
Once again, if reading through this series and working along with it has helped you in any way, I’m really happy to hear that.
See you in the next blog, take a care ❤
Sources
- Compare security groups and network ACLs — Amazon VPC
- Control traffic with security groups — Amazon VPC
- What is AWS Site-to-Site VPN?
- Encryption in transit — AWS Direct Connect
- What is AWS Network Firewall?
- AWS Firewall Manager developer guide
- How AWS WAF works
- Managing your own rule groups in AWS WAF
- How AWS Shield and Shield Advanced work
- What is Amazon CloudFront?
- Choosing a routing policy — Amazon Route 53
- About routing control — Amazon Route 53 Application Recovery Controller
If this write-up helped, consider sharing it or exploring more of the log.