21.6
WAF, Shield, Firewall Manager and DDoS Resiliency
Web ACLs and rate rules, Shield Standard vs Advanced, central rule management, and the DDoS best practices.
26 min Reading + animations
Tip: tap or hover any dotted-underlined term to see what it means.
By the end of this lesson you will be able to
- Explain what AWS WAF inspects (layer 7: path, query string, headers, cookies, body), which resources a web ACL can protect, and why it cannot sit on an NLB, a Classic Load Balancer or an EC2 instance directly.
- Build a web ACL from rules and rule groups: priorities, default action, the Allow, Block, Count, CAPTCHA and Challenge actions, IP sets, geo match, size constraints, regex, SQL injection and XSS statements, and the AWS managed rule groups.
- Design rate-based rules (minimum 10 requests, windows of 1, 2, 5 or 10 minutes, aggregation keys) and know what they cannot do.
- Give static IP addresses to a WAF-protected application with Global Accelerator in front of an ALB, and know the NLB alternative.
- Compare Shield Standard and Shield Advanced (protected resources, price and commitment, SRT, health-based detection, automatic application layer mitigation, cost protection).
- Use Firewall Manager to apply WAF, Shield Advanced, security group, network ACL, Network Firewall and DNS Firewall policies across an Organization, and know its prerequisites.
- Apply the AWS DDoS resiliency best practices BP1 to BP7: edge services, scaling, decoupling, caching, application layer defence and attack surface reduction.
#Three different jobs
An exam-results website in Bangladesh is quiet for 364 days and then, on result day, a million students open it within the same hour. That is the day attackers like best too. The site faces three different kinds of trouble, and AWS has a different service for each:
- Malicious requests: an SQL injection in a roll number, a script hidden in a comment form, a password-guessing bot on the admin page, a scraper copying every result. Each one is a real HTTP request that looks bad only when you read it. That is AWS WAF, a firewall that reads layer 7.
- Floods: millions of SYN packets, UDP reflection traffic, or millions of perfectly valid HTTP requests meant to exhaust the servers. That is AWS Shield (with WAF's rate-based rules for the layer 7 part) and a design that can absorb load.
- Many accounts: the education board runs 20 AWS accounts. Configuring WAF and security groups by hand in each one guarantees that one gets forgotten. That is AWS Firewall Manager.
Lesson 11.2 already introduced Shield Standard, WAF and Shield Advanced as the edge protections of CloudFront, with a table of which layer stops which attack. This lesson goes inside each service, adds Firewall Manager, and ends with the AWS DDoS resiliency best practices that tie them together.
#AWS WAF: a firewall that reads HTTP
AWS WAF (web application firewall) protects web applications from common web exploits at layer 7. A security group or network ACL looks at addresses and ports (layers 3 and 4); WAF looks inside the HTTP request: the URI path, the query string, headers, cookies, the HTTP method and the body. It decides per request: let it through, block it, count it, or challenge the client.
WAF is not a box you deploy. You create a web ACL and associate it with a resource; the resource's own service (CloudFront, the ALB, API Gateway…) hands each request to WAF before processing it.
#Where a web ACL can be attached
| Resource | Scope of the web ACL |
|---|---|
| Amazon CloudFront distribution | Global: created in us-east-1 (the console calls it “Global (CloudFront)”) |
| Application Load Balancer | Regional, same Region as the ALB |
| Amazon API Gateway REST API | Regional, same Region as the API |
| AWS AppSync GraphQL API | Regional |
| Amazon Cognito user pool | Regional |
| AWS App Runner service | Regional |
| AWS Verified Access instance | Regional |
| AWS Amplify app | Must be created in the global CloudFront scope |
| Amazon Bedrock AgentCore Gateway | Regional (added in 2025) |
What is not on the list matters just as much for the exam:
- Network Load Balancer, Gateway Load Balancer and Classic Load Balancer: no WAF. The NLB works at layer 4 and never parses HTTP (lesson 6.3).
- EC2 instances directly: no. Put an ALB or CloudFront in front.
- API Gateway HTTP APIs (the cheaper API type): no; only REST APIs (lesson 15.6).
Two association rules: a resource can have only one web ACL, while one web ACL can protect many resources of its scope; and the web ACL plus everything it uses (IP sets, rule groups, regex pattern sets) must be in the same Region as the resource. A web ACL in us-east-1 cannot be chosen for an ALB in Singapore.
#Web ACLs, rules and rule groups
A web ACL (web access control list) is an ordered list of rules plus a default action:
- Each rule has a priority (WAF evaluates the lowest number first), a statement that says what to match, and an action.
- A rule group is a reusable set of rules that you add to a web ACL as a single entry. It can be your own, an AWS managed rule group, or a group sold by a vendor in AWS Marketplace.
- The default action (Allow or Block) applies when no rule ends the evaluation. Most public sites use default Allow with Block rules for bad traffic; a private admin tool might use default Block with Allow rules for the office's addresses.
The rule actions:
| Action | What happens | Ends the evaluation? |
|---|---|---|
| Allow | The request goes to the resource | Yes |
| Block | WAF answers 403 Forbidden (or a custom response you define, such as a 429 page) | Yes |
| Count | WAF counts the match in metrics and logs, may add a label, and continues | No |
| CAPTCHA | The client must solve a puzzle; a valid token lets later requests through | Yes, unless the client has a valid token |
| Challenge | A silent browser check (JavaScript) instead of a puzzle; stops simple bots | Yes, unless the client has a valid token |
Labels connect rules: a Count rule (or a managed rule group) can add a label such as awswaf:managed:aws:sql-database:SQLi_QueryArguments, and a later rule can match on that label. This is how you build “block SQL injection everywhere except on this one field” without disabling the whole group.
Every rule costs capacity units (web ACL capacity units, a measure of how much processing a rule needs; a regex costs more than an IP set). A web ACL includes 1,500 units in its base price and can go up to 5,000 at extra cost. Prices, for orientation: about 5 USD per web ACL per month, 1 USD per rule or rule group per month, and 0.60 USD per million requests inspected, plus extra for Bot Control, Fraud Control and some managed groups.
#What a rule can match
| Statement | Example on the results site |
|---|---|
| IP set | Block a list of scraper addresses. One IP set holds up to 10,000 addresses or CIDR ranges; for more, use several IP sets in several rules (slide p686). |
| Geo match | Block /admin unless the country is Bangladesh. WAF uses the source IP (or a forwarded IP header) to decide the country, and can match a region inside a country too. |
| SQL injection | Look for SQL code in the query string, body, headers or cookies. |
| Cross-site scripting (XSS) | Look for script tags and JavaScript in a field that will be shown to other users. |
| Size constraint | Block a query string longer than 1 KB, or a body larger than expected. |
| String match and regex pattern set | Block a User-Agent used by a known bad tool, allow only /api/v2/… paths. |
| Label match | Act on labels added by earlier rules. |
| ASN match | Match the network (autonomous system) the request comes from. |
| Rate-based | Count requests per key over a window and act above a limit (section below). |
| AND / OR / NOT | Combine any of these, for example “country is not Bangladesh and path starts with /admin”. |
WAF only inspects the first part of a large body: 8 KB on an ALB and AppSync (fixed), 16 KB by default on CloudFront, API Gateway, Cognito, App Runner and Verified Access (raisable to 64 KB at extra cost). An oversize handling setting decides what to do with a body larger than the limit: continue, match or no match. An attacker who pads the body to hide the payload past 8 KB is the reason to set it, or to add a size constraint.
#AWS managed rule groups
Writing good SQL injection and XSS rules is hard. AWS maintains rule groups that its threat research team updates for you:
- Baseline groups: the core rule set (protection against many risks in the OWASP Top 10, such as XSS, local file inclusion, and request bodies over 8 KB), admin protection (blocks external access to admin pages), and known bad inputs (request patterns tied to exploits, including the Log4j vulnerability).
- Use-case groups: SQL database (SQL injection), Linux, POSIX and Windows operating system, PHP and WordPress applications.
- IP reputation groups: the Amazon IP reputation list (addresses seen attacking, bots, reconnaissance) and the anonymous IP list (VPNs, Tor exit nodes, hosting providers that hide the real client).
These baseline, use-case and reputation groups have no extra fee beyond normal WAF pricing. Add them first in Count mode, read the logs for a week, then switch to Block, overriding any single rule that hits legitimate traffic.
How a web ACL decides
Result day for an exam-results site behind CloudFront. Every request meets the web ACL first; its rules run in priority order until one of them blocks or allows.
Scenario
No rule matches, so the web ACL’s default action (Allow) lets the request through.
Request
Path
/result?roll=482913
Country
Bangladesh
Source IP
198.51.100.20
A student asks for her result. The request reaches the nearest CloudFront edge, and the web ACL attached to the distribution inspects it before the cache or the origin ever sees it.
Try the same web ACL yourself. Switch the SQL group to Count, try the admission photo upload, and change the default action to Block to see why most public sites keep it on Allow.
Which rule catches this request?
A web ACL with five rules protects an exam-results site. Pick a request, set the switches, and send it. The trace walks the rules in priority order.
The request
GET /result?roll=482913 from Dhaka, 198.51.100.20
The web ACL
1 IP set (scrapers) → Block · 2 Geo not Bangladesh, only /admin → Block · 3 Rate: 100 per IP per 5 min → Block · 4 Core rule set (XSS, body over 8 KB) → Block · 5 SQL database group → Block
Default action
Pick a request and press the button to see the evaluation.
#Logs and visibility
- Logging: a web ACL can send full logs (every request, the matching rule, the action, labels, headers) to CloudWatch Logs, an S3 bucket, or an Amazon Data Firehose stream. The log group, bucket or stream name must start with
aws-waf-logs-. Sensitive fields such as anAuthorizationheader can be redacted. CloudWatch Logs Insights or Athena then answer “which rule blocked this student?” (lesson 19.2, lesson 17.1). - Sampled requests: without full logging, the console still shows a sample of recent matching requests per rule for 3 hours.
- Metrics: every rule and web ACL publishes allowed, blocked and counted request counts to CloudWatch, so you can alarm on a sudden rise in blocked requests.
#A fixed IP address in front of WAF
A tricky design question from the notes and slide p687. A Bangladeshi garments exporter's order API is called by a European buyer. The buyer's firewall allows outbound connections only to IP addresses on a list, and every change to that list needs weeks of approval. The exporter also wants the API protected by AWS WAF.
- An ALB can carry a web ACL, but it has no static IP. Its addresses change as it scales and replaces nodes, and AWS gives no list to allow.
- An NLB has static IPs (one Elastic IP per AZ), but it is layer 4, so WAF cannot be attached to it.
The answer is AWS Global Accelerator in front of the ALB. The accelerator gives two static anycast IPv4 addresses that never change for its lifetime (lesson 11.4). The buyer allows those two addresses once. Global Accelerator routes the traffic over the AWS network to the ALB, and the web ACL on the ALB (in the ALB's Region) inspects it.
Users → Global Accelerator (2 fixed IPs) → ALB with a web ACL → targets.
Global Accelerator has no WAF of its own and does not read HTTP; it only provides the fixed entry point and fast failover between Regions. Shield Standard protects it at the edge, and Shield Advanced can protect it too.
Fixed IP addresses with WAF
A garments exporter’s order API must be reachable from a European buyer whose firewall only allows listed IP addresses, and it must be protected by AWS WAF.
Scenario
The exam answer: two static anycast IPs in front, WAF on the ALB behind them.
Global Accelerator gives two static anycast IPv4 addresses that never change for the life of the accelerator. The buyer’s firewall team adds those two addresses once.
#AWS Shield: DDoS protection
A DDoS (distributed denial of service) attack sends traffic from many machines at once to make a service unavailable. Slide p688 sums it up as “many requests at the same time”; the requests can be packets that never form a connection (layers 3 and 4) or valid HTTP requests (layer 7).
#Shield Standard
Shield Standard is free, automatic and on for every AWS customer; there is nothing to subscribe to or turn on. It protects against the common layer 3 and layer 4 attacks: SYN floods, UDP floods, reflection attacks (DNS, NTP or memcached servers tricked into sending big replies to the victim) and similar. The protection is strongest on the edge services, CloudFront, Route 53 and Global Accelerator, where AWS absorbs the flood across hundreds of locations; resources in a Region (ELB, Elastic IPs) are covered too. Shield Standard does not read HTTP, so a flood of valid HTTP requests is not its job: that is WAF.
#Shield Advanced
Shield Advanced is the paid tier for applications that must stay up:
- Protected resources: CloudFront distributions, Route 53 hosted zones, Global Accelerator standard accelerators, Application and Classic Load Balancers, and Elastic IP addresses. EC2 instances and NLBs are protected through their Elastic IPs. Shield Advanced does not protect anything automatically: you add each resource (or a Firewall Manager policy adds them).
- Price: 3,000 USD per month per organization (charged once to the payer account, covering all its member accounts), with a one-year commitment, plus data transfer out usage fees for protected resources. AWS WAF charges for protected resources are included (up to a large monthly request volume, at the default capacity), and Firewall Manager policies are free for Shield Advanced customers.
- Detection tuned to each resource: Shield Advanced learns the normal traffic of each protected resource and uses lower, resource-specific thresholds than Standard.
- Health-based detection: associate a Route 53 health check with a protected resource (lesson 8.4). When traffic is unusual and the application is unhealthy, Shield Advanced is more confident it is an attack, detects faster and raises fewer false alarms on a merely busy day.
- Automatic application layer DDoS mitigation: during a layer 7 attack, Shield Advanced creates, evaluates and deploys WAF rules in the web ACL of the protected resource, in Block or Count mode as you choose. It needs a web ACL associated with the resource (CloudFront, ALB).
- Shield Response Team (SRT): AWS DDoS specialists available 24/7 to help during an attack (needs Business or Enterprise Support; since the December 2025 plan change that means Business Support+, Enterprise Support or Unified Operations, while exam questions still say Business or Enterprise). With proactive engagement, the SRT calls you when a protected resource's health check fails during an event. Slide p688 calls them the
DRP; the old name was DDoS Response Team (DRT), the current name is SRT. - DDoS cost protection: if an attack on a protected resource drives up scaling charges (more EC2 instances, more CloudFront or ELB usage), you request service credits for those charges.
- Protection groups: group several protected resources (for example every ALB of one application) so Shield treats them as one unit for detection and mitigation.
- Visibility: attack reports and CloudWatch metrics per resource, plus a global threat dashboard.
Shield Standard and Advanced under attack
The same results site on result day, hit by a botnet. Compare what the free tier stops on its own and what the paid tier adds.
Scenario
Shield Standard, free and always on, absorbs the network flood at the edge.
Thousands of machines send SYN packets and UDP reflection traffic, trying to fill connection tables and bandwidth. None of it is a valid HTTP request.
| Shield Standard | Shield Advanced | |
|---|---|---|
| Cost | Free | 3,000 USD per month per organization, 1-year commitment, plus data transfer fees |
| Turned on | Automatically, for everyone | Subscribe, then add each resource |
| Layers | 3 and 4 | 3, 4 and 7 (layer 7 through WAF) |
| Resources | All AWS customers; strongest at CloudFront, Route 53, Global Accelerator | CloudFront, Route 53, Global Accelerator, ALB, CLB, Elastic IPs (EC2, NLB) |
| Detection | Generic, AWS-wide | Tuned per resource, health-based with Route 53 health checks |
| Experts | None | Shield Response Team 24/7, proactive engagement |
| Bill protection | None | DDoS cost protection (service credits) |
| WAF charges | Paid separately | Included for protected resources |
#AWS Firewall Manager
AWS Firewall Manager manages firewall rules centrally across all accounts of an AWS Organization. You write a security policy once in a Firewall Manager administrator account; Firewall Manager applies it to every account and resource in scope, keeps checking, and applies it to new accounts and new resources as they are created.
#Prerequisites
- The accounts are in AWS Organizations with all features enabled (lesson 20.1).
- A Firewall Manager administrator account is chosen (from the management account; usually a dedicated security account).
- AWS Config is enabled in every member account and Region in scope; Firewall Manager uses it to discover resources and watch changes (lesson 19.7).
- For Network Firewall and DNS Firewall policies, resource sharing through AWS RAM; for third-party firewalls, a Marketplace subscription.
#Policy types
| Policy type | What it enforces |
|---|---|
| AWS WAF | Web ACLs on ALBs, API Gateway stages, CloudFront distributions and the other WAF resources: rule groups that must run first and last; account teams may add their own rules in between |
| Shield Advanced | Shield Advanced protection (and optionally automatic application layer mitigation) on the chosen resource types |
| Security group | Common security groups attached to EC2 instances and ENIs, content audit (forbid rules such as 0.0.0.0/0 on port 22), usage audit (find unused or redundant groups) |
| Network ACL | A baseline of network ACL rules on subnets |
| AWS Network Firewall | Firewall endpoints and rule groups in VPCs (lesson 22.7) |
| Route 53 Resolver DNS Firewall | Domain block and allow lists on VPCs |
| Third-party firewalls | Palo Alto Networks Cloud NGFW and Fortinet FortiGate Cloud Native Firewall |
Policies are created per Region (a policy for CloudFront is global). Each policy can auto-remediate non-compliant resources or only report them. Firewall Manager costs about 100 USD per policy per Region per month, plus the AWS Config rules it creates and the underlying services (WAF, Network Firewall…); for Shield Advanced customers the policies are free.
Firewall Manager across many accounts
A group of companies runs 20 accounts in one AWS Organization. One security team must keep the same WAF and security group baseline everywhere.
Scenario
Define a WAF policy once; Firewall Manager creates and attaches the web ACLs in every account in scope.
In the Firewall Manager administrator account, the security team writes one WAF policy: first rule groups are the core rule set and the IP reputation list; scope is every ALB in the Organization, in this Region.
#WAF, Firewall Manager or Shield?
They are used together, but each answers a different question (slide p690):
| You need | Choose |
|---|---|
| Granular layer 7 rules for one application or one account | AWS WAF alone |
| The same WAF rules across many accounts, faster rollout, automatic protection of new resources | Firewall Manager with AWS WAF |
| DDoS specialists, cost protection, tuned detection, advanced reporting on top of WAF; frequent or costly DDoS attacks | Shield Advanced |
| Basic protection against network floods | Shield Standard (already on) |
| Central security groups, network ACLs, Network Firewall or DNS Firewall policies | Firewall Manager |
The rules themselves are always written in WAF. Firewall Manager only distributes them, and Shield Advanced adds detection, experts and money protection around them.
#DDoS resiliency best practices
AWS publishes a whitepaper, AWS Best Practices for DDoS Resiliency, that labels each building block with a best practice number. Slides p691–p694 use these labels, so the exam may too:
| Label | Building block | What it gives |
|---|---|---|
| BP1 | CloudFront and Global Accelerator | Delivery from the edge, huge capacity, SYN flood and reflection mitigation before traffic reaches the Region |
| BP2 | AWS WAF | Layer 7 filtering on CloudFront and the ALB: rate-based rules, managed rules, geo and IP rules |
| BP3 | Route 53 | DNS answered at the edge, with shuffle sharding and anycast to stay up during DNS floods |
| BP4 | API Gateway | A managed front door for APIs that hides the back end, with throttling |
| BP5 | Security groups and network ACLs in the VPC | Only the needed ports and sources reach the subnets and instances |
| BP6 | Elastic Load Balancing | Scales with traffic and spreads it over many targets; only valid TCP connections reach them |
| BP7 | EC2 with Auto Scaling (and containers, Lambda) | Capacity grows with a flash crowd or an attack |
#Edge mitigation: BP1 and BP3
The first line of defence is to never expose the application directly. Put CloudFront in front of web applications, Global Accelerator in front of TCP or UDP applications (or HTTP back ends CloudFront does not suit), and serve DNS from Route 53. Attack traffic then lands on the AWS global edge network, whose capacity is measured in terabits per second and whose Shield systems are built in, and is absorbed or filtered there, far from your origin. Requests that CloudFront or WAF reject are not charged for CloudFront data transfer.
#Scale, decouple and cache
Some traffic cannot be filtered because it looks exactly like real users, and some days the real users themselves are the flood. The design must absorb it:
- Infrastructure scaling (BP6, BP7): an ALB in front of an Auto Scaling group (lesson 6.5). The load balancer scales by itself; the group adds instances as load rises. Shield Advanced's cost protection exists precisely because this scaling costs money during an attack.
- Decoupling: put SQS (or Kinesis) between the web tier and slower back-end work (lesson 13.1). A burst becomes a longer queue, which workers drain at a steady pace, instead of an overloaded database.
- Caching at the edge: CloudFront serves static content (and cacheable API responses) from edge locations, so most requests never reach the origin. A cache policy that ignores unknown query strings stops attackers from defeating the cache with random URLs.
Absorb, scale and buffer
Result day brings a flash crowd and an attack at the same time. Each layer of the design takes part of the load.
Scenario
Most requests are answered at the edge and never reach the Region.
At noon a million students open the site. The result PDFs, images and scripts are cached at CloudFront edge locations.
#Application layer defence: BP1 and BP2
Layer 7 attacks are subtle: an HTTP GET or POST flood sends requests that are each valid, aimed at expensive pages (search, login, report generation) to drain CPU and memory. Shield Standard does not see them as an attack. The defence is AWS WAF on CloudFront or the ALB:
- Rate-based rules block or challenge the sources sending too many requests.
- Managed rules block requests from addresses with a bad IP reputation or from anonymous sources (VPNs, Tor, hosting providers).
- Geo rules in WAF, or CloudFront geographic restrictions, block whole countries the site never serves.
- CloudFront caching absorbs repeated requests for the same content.
- Shield Advanced (BP1, BP2, BP6) adds automatic application layer mitigation that writes the WAF rules for you during the attack.
Rate-based rules in detail
A rate-based rule counts the requests of each aggregation key (by default each source IP address) over a sliding evaluation window, and applies its action to that key's further requests while it is over the limit:
- Limit: from 10 requests upward. The notes' “2,000 requests in 5 minutes” is only an example (it was once the minimum, then 100; since August 2024 the minimum is 10, and the 1, 2 and 10 minute windows arrived in March 2024).
- Evaluation window: 1, 2, 5 or 10 minutes (60, 120, 300 or 600 seconds); 5 minutes is the default. The window is how far back WAF looks each time it checks, not how often it checks.
- Aggregation: source IP; an IP from a header such as
X-Forwarded-For(when WAF sits behind a proxy); ASN; count all requests that match a scope-down statement; or custom keys, up to five combined, from headers, cookies, a query argument, the query string, the URI path, the HTTP method, a label namespace, JA3 or JA4 fingerprints and the IP. “IP + session cookie” counts each logged-in user separately, even behind one NAT address. - Scope-down statement: count only requests that match, for example only
POST /login, so a strict limit on the login page does not touch normal browsing. - Action: Block (403 or a custom 429 response), CAPTCHA, Challenge or Count. Never Allow.
- Timing: WAF estimates the rate continuously and usually starts limiting within about 30 seconds of a source crossing the limit; when the rate falls back below the limit, WAF lifts the limit by itself, again within about 30 seconds. It is a speed limit, not a precise counter: a few requests over the limit can get through.
A rate-based rule at work
The results site has a rate-based rule: at most 2,000 requests per IP address in a 5-minute window. Watch the counter for one address.
Scenario
Below the limit nothing happens; the rule only counts.
Counter for 203.0.113.9
Last 5 min
1,200
Limit
2,000
Action
none (allowed)
A coaching centre’s script checks results for its students. WAF keeps a count per source IP of the requests in the last 5 minutes.
#Attack surface reduction: BP1, BP4, BP5, BP6
The fewer doors you have, the fewer an attacker can knock on:
- Hide the back end (obfuscation): users reach CloudFront, API Gateway or a load balancer, never an instance or a Lambda function directly.
- Private subnets: application servers and databases have no public address (lesson 3.5).
- Security groups and network ACLs (BP5): open only the ports you serve (443, maybe 80 to redirect), only to the sources that need them; network ACLs can deny specific addresses at the subnet. Elastic IPs can be protected by Shield Advanced.
- Protecting API endpoints (BP4): use an edge-optimized API Gateway endpoint, or your own CloudFront distribution (with WAF) in front of a regional endpoint for more control; add WAF on the API, throttling and burst limits, and API keys with usage plans for partners.
- Lock the origin behind CloudFront: an attacker who can reach the origin directly bypasses the cache, WAF and Shield at the edge.
- S3 origin: Origin Access Control (OAC) plus a bucket policy that allows only the distribution (lesson 10.9).
- ALB or EC2 origin: a security group that allows only the AWS managed prefix list
com.amazonaws.global.cloudfront.origin-facing, plus a secret custom header added by CloudFront (for exampleX-Origin-Verify; the name is your choice) that the ALB checks with a listener rule or a WAF rule. The prefix list alone lets in every CloudFront distribution, including one an attacker creates; the header closes that gap. - CloudFront VPC origins (November 2024): the ALB, NLB or EC2 instance stays in a private subnet with no public address at all, and CloudFront reaches it through the VPC origin. This removes the side door instead of guarding it.
Only through CloudFront
WAF and Shield on CloudFront protect nothing if attackers can reach the ALB directly. Follow the ways in and the locks that close them.
Scenario
CloudFront adds a secret header; the ALB’s security group admits only CloudFront’s addresses.
The student’s request is inspected by the web ACL at the edge, then sent to the origin with a custom header that only your distribution knows, for example X-Origin-Verify with a long random value.
#What goes wrong
- “Associate web ACL” lists no NLB: WAF does not support NLBs, CLBs or GWLBs. Use an ALB, or CloudFront in front.
- The web ACL cannot be selected for a resource: it is in the wrong Region, or it is a CloudFront (global) web ACL and you are attaching it to a regional resource, or the resource already has a web ACL.
- Real users blocked after enabling a managed group: false positives (an address field with “--”, a large photo upload hitting the 8 KB body rule). Start in Count, read the logs, override single rules to Count or narrow them with scope-down statements.
- An attack payload hidden past the inspection limit: bodies over 8 KB (ALB) are only partly inspected. Set oversize handling to match, or add a size constraint.
- A whole campus or office blocked by a rate rule: many users behind one NAT address. Aggregate on a better key, allow the known range first, or scope the rule down to sensitive paths.
- Rate rule on the ALB counts CloudFront, not users: aggregate on the forwarded IP header, or rate limit on the CloudFront web ACL.
- WAF protects CloudFront but the origin is still public: attackers go around it. Lock the origin (prefix list + header, OAC, VPC origin).
- Shield Advanced subscribed, but a resource is not protected: it was never added. Add resources explicitly or with a Firewall Manager Shield Advanced policy.
- No layer 7 automatic mitigation: the protected resource has no web ACL associated.
- Firewall Manager shows an account as unknown or does not apply policies: AWS Config is not recording there, the account is outside the policy scope, or the Organization does not have all features enabled.
- Allowlisted ALB IPs stop working: ALB addresses change. Use Global Accelerator (or an NLB with an ALB target).
- No logs arrive: the destination name does not start with
aws-waf-logs-. - Blocking one bad IP everywhere: depending on where the request is stopped (NACL, security group, ALB, WAF on CloudFront) the tool differs; lesson 24.3 compares them.
#WAF and Shield in system design
Patterns to remember:
- Public web application: Route 53 → CloudFront + WAF → ALB (locked to CloudFront) → Auto Scaling group in private subnets → database in private subnets.
- Partner API with allowlisting: Global Accelerator (2 static IPs) → ALB + WAF → targets.
- Public API: API Gateway (edge-optimized, or CloudFront + regional) + WAF + throttling and usage plans → Lambda.
- Many accounts: Firewall Manager policies for WAF, security groups and Shield Advanced; findings and compliance flow to Security Hub (lesson 21.7).
- Non-HTTP traffic (games, VoIP over UDP): Global Accelerator + Shield (Advanced for Elastic IPs and accelerators); WAF does not apply. Deep packet inspection inside the VPC is AWS Network Firewall (lesson 22.7).
- HTTPS everywhere: the TLS certificates on CloudFront and the ALB come from ACM (lesson 21.4); WAF inspects the decrypted request after TLS is terminated at CloudFront or the ALB.
#Try it yourself
These commands use the AWS CLI v2. WAF and Firewall Manager cost money per month, and Shield Advanced commits you for a year, so read before you run, and delete what you create.
Save these rules as rules.json, for a regional web ACL protecting an ALB in ap-southeast-1:
[
{ "Name": "block-scrapers", "Priority": 1,
"Statement": { "IPSetReferenceStatement": { "ARN": "arn:aws:wafv2:ap-southeast-1:111122223333:regional/ipset/scrapers/a1b2c3d4-5678-90ab-cdef-EXAMPLE11111" } },
"Action": { "Block": {} },
"VisibilityConfig": { "SampledRequestsEnabled": true, "CloudWatchMetricsEnabled": true, "MetricName": "block-scrapers" } },
{ "Name": "admin-only-from-bd", "Priority": 2,
"Statement": { "AndStatement": { "Statements": [
{ "NotStatement": { "Statement": { "GeoMatchStatement": { "CountryCodes": ["BD"] } } } },
{ "ByteMatchStatement": { "FieldToMatch": { "UriPath": {} }, "PositionalConstraint": "STARTS_WITH",
"SearchString": "/admin", "TextTransformations": [ { "Priority": 0, "Type": "LOWERCASE" } ] } } ] } },
"Action": { "Block": {} },
"VisibilityConfig": { "SampledRequestsEnabled": true, "CloudWatchMetricsEnabled": true, "MetricName": "admin-geo" } },
{ "Name": "per-ip-limit", "Priority": 3,
"Statement": { "RateBasedStatement": { "Limit": 300, "EvaluationWindowSec": 300, "AggregateKeyType": "IP" } },
"Action": { "Block": { "CustomResponse": { "ResponseCode": 429 } } },
"VisibilityConfig": { "SampledRequestsEnabled": true, "CloudWatchMetricsEnabled": true, "MetricName": "per-ip-limit" } },
{ "Name": "core-rule-set", "Priority": 4,
"Statement": { "ManagedRuleGroupStatement": { "VendorName": "AWS", "Name": "AWSManagedRulesCommonRuleSet" } },
"OverrideAction": { "None": {} },
"VisibilityConfig": { "SampledRequestsEnabled": true, "CloudWatchMetricsEnabled": true, "MetricName": "crs" } },
{ "Name": "sql-database", "Priority": 5,
"Statement": { "ManagedRuleGroupStatement": { "VendorName": "AWS", "Name": "AWSManagedRulesSQLiRuleSet" } },
"OverrideAction": { "Count": {} },
"VisibilityConfig": { "SampledRequestsEnabled": true, "CloudWatchMetricsEnabled": true, "MetricName": "sqli" } }
]
"OverrideAction": { "Count": {} } runs the whole SQL group in Count mode for the first week; change it to { "None": {} } to let its rules block.
# 1. An IP set of scraper addresses (up to 10,000 per set)
aws wafv2 create-ip-set --name scrapers --scope REGIONAL --region ap-southeast-1 \
--ip-address-version IPV4 --addresses 203.0.113.77/32 198.51.100.0/26
# { "Summary": { "Name": "scrapers", "Id": "a1b2c3d4-5678-90ab-cdef-EXAMPLE11111",
# "ARN": "arn:aws:wafv2:ap-southeast-1:111122223333:regional/ipset/scrapers/a1b2c3d4-5678-90ab-cdef-EXAMPLE11111", ... } }
# 2. The web ACL (default Allow) and its association with the ALB in the same Region
aws wafv2 create-web-acl --name results-acl --scope REGIONAL --region ap-southeast-1 \
--default-action Allow={} --rules file://rules.json \
--visibility-config SampledRequestsEnabled=true,CloudWatchMetricsEnabled=true,MetricName=results-acl
aws wafv2 associate-web-acl --region ap-southeast-1 \
--web-acl-arn arn:aws:wafv2:ap-southeast-1:111122223333:regional/webacl/results-acl/f1e2d3c4-EXAMPLE \
--resource-arn arn:aws:elasticloadbalancing:ap-southeast-1:111122223333:loadbalancer/app/results-alb/50dc6c495c0c9188
# 3. Full logs to CloudWatch Logs (the name must start with aws-waf-logs-)
aws logs create-log-group --log-group-name aws-waf-logs-results --region ap-southeast-1
aws wafv2 put-logging-configuration --region ap-southeast-1 --logging-configuration \
ResourceArn=arn:aws:wafv2:ap-southeast-1:111122223333:regional/webacl/results-acl/f1e2d3c4-EXAMPLE,LogDestinationConfigs=arn:aws:logs:ap-southeast-1:111122223333:log-group:aws-waf-logs-results
# 4. Test from your laptop: an injection, then a burst
curl -s -o /dev/null -w "%{http_code}\n" "https://results.example.com/result?roll=1%27%20OR%201=1--"
# 200 (the SQL group is still in Count mode; after switching to None it returns 403)
for i in $(seq 1 600); do curl -s -o /dev/null -w "%{http_code}\n" https://results.example.com/result?roll=482913; done | sort | uniq -c
# 341 200
# 259 429 (the limit is approximate: a few dozen over 300 got through before WAF reacted)
# 5. Which addresses is the rate rule limiting right now?
aws wafv2 get-rate-based-statement-managed-keys --scope REGIONAL --region ap-southeast-1 \
--web-acl-name results-acl --web-acl-id f1e2d3c4-EXAMPLE --rule-name per-ip-limit
# { "ManagedKeysIPV4": { "IPAddressVersion": "IPV4", "Addresses": [ "198.51.100.20/32" ] } }
# 6. Shield Advanced (only if your organization really subscribes: 1-year commitment)
aws shield describe-subscription --query 'Subscription.[SubscriptionLimits.ProtectionLimits,AutoRenew,TimeCommitmentInSeconds]'
aws shield create-protection --name results-cdn \
--resource-arn arn:aws:cloudfront::111122223333:distribution/E1A2B3C4D5E6F7
# { "ProtectionId": "a1b2c3d4-EXAMPLE-protection" }
aws shield associate-health-check --protection-id a1b2c3d4-EXAMPLE-protection \
--health-check-arn arn:aws:route53:::healthcheck/abcdef12-3456-7890-abcd-EXAMPLE22222
aws shield enable-application-layer-automatic-response \
--resource-arn arn:aws:cloudfront::111122223333:distribution/E1A2B3C4D5E6F7 --action Count={}
# 7. Firewall Manager (from the administrator account): one WAF policy for every ALB in the Organization
aws fms put-policy --region ap-southeast-1 --policy '{
"PolicyName": "org-baseline-waf",
"SecurityServicePolicyData": { "Type": "WAFV2",
"ManagedServiceData": "{\"type\":\"WAFV2\",\"preProcessRuleGroups\":[{\"managedRuleGroupIdentifier\":{\"vendorName\":\"AWS\",\"managedRuleGroupName\":\"AWSManagedRulesCommonRuleSet\"},\"overrideAction\":{\"type\":\"NONE\"},\"ruleGroupType\":\"ManagedRuleGroup\",\"excludeRules\":[]}],\"postProcessRuleGroups\":[],\"defaultAction\":{\"type\":\"ALLOW\"},\"overrideCustomerWebACLAssociation\":false}" },
"ResourceType": "AWS::ElasticLoadBalancingV2::LoadBalancer",
"ExcludeResourceTags": false, "RemediationEnabled": true }'
aws fms list-compliance-status --region ap-southeast-1 --policy-id 1a2b3c4d-EXAMPLE \
--query 'PolicyComplianceStatusList[].[MemberAccount,EvaluationResults[0].ComplianceStatus]' --output text
# 111122223333 COMPLIANT
# 444455556666 NON_COMPLIANT (a new ALB, remediation in progress)
Also try in the console: open the web ACL's Sampled requests for the SQL rule after step 4, then switch to CloudWatch Logs Insights on aws-waf-logs-results and filter on action = "BLOCK". Clean up with disassociate-web-acl, delete-web-acl, delete-ip-set and aws fms delete-policy.
#Summary
Key takeaways
- AWS WAF = layer 7 firewall. A web ACL (rules in priority order + a default action) attaches to CloudFront (global, created in us-east-1), ALB, API Gateway REST APIs, AppSync, Cognito user pools, App Runner, Verified Access, Amplify, in the same Region as the resource. Never an NLB, CLB or EC2.
- Rules match IP sets (10,000 addresses per set), geo, SQL injection, XSS, size, string/regex, labels, rate. Actions: Allow, Block, Count (does not stop evaluation), CAPTCHA, Challenge. AWS managed rule groups: core rule set, known bad inputs, SQL database, IP reputation, anonymous IP; paid Bot Control, Fraud Control, Anti-DDoS. Test in Count first. Logs go to CloudWatch Logs, S3 or Firehose (
aws-waf-logs-names). - Rate-based rules: limit from 10, window 1, 2, 5 or 10 minutes (default 5), per IP or forwarded IP, ASN, custom keys (cookie, header, path…), scope-down; action Block, CAPTCHA, Challenge or Count, never Allow; WAF lifts it by itself. 2,000 per 5 minutes is only an example.
- Fixed IP + WAF → Global Accelerator → ALB with WAF (NLB cannot take WAF; an NLB with an ALB-type target group also works).
- Shield Standard: free, automatic, layer 3/4 (SYN, UDP, reflection). Shield Advanced: 3,000 USD/month per organization, 1-year commitment + data transfer; CloudFront, Route 53, Global Accelerator, ALB, CLB, Elastic IPs (EC2, NLB); tuned and health-based detection, automatic layer 7 mitigation through WAF, SRT 24/7, DDoS cost protection credits, protection groups, WAF fees included.
- Firewall Manager: central WAF, Shield Advanced, security group, network ACL, Network Firewall, DNS Firewall and third-party firewall policies across an Organization; new accounts and resources are covered automatically. Needs Organizations, an administrator account and AWS Config.
- DDoS best practices: BP1 CloudFront and Global Accelerator, BP2 WAF, BP3 Route 53, BP4 API Gateway, BP5 security groups and NACLs, BP6 ELB, BP7 Auto Scaling. Absorb at the edge, scale (ALB + ASG), decouple (SQS), cache, filter layer 7 (WAF rate rules), and reduce the attack surface (private subnets, locked origin: prefix list + header for the ALB, OAC for S3, VPC origins).
Answer on your own first, then read the explanation, even when you got it right.
Self-checkQuestion
At which layer does AWS WAF inspect traffic, and what can its rules look at?
Self-checkQuestion
Which load balancer can have an AWS WAF web ACL associated with it?
Self-checkQuestion
A company creates a web ACL for its CloudFront distribution in ap-south-1, close to its users, but cannot select it on the distribution. Where must the web ACL be created?
Self-checkQuestion
What does Shield Standard cost and how is it enabled?
Self-checkQuestion
Which two are features of Shield Advanced that Shield Standard does not provide?
Choose 2
Self-checkQuestion
How is Shield Advanced priced?
Self-checkQuestion
What is the minimum limit and which evaluation windows can a WAF rate-based rule use?
Self-checkQuestion
Which two actions can a rate-based rule apply to requests over its limit?
Choose 2
Self-checkQuestion
An exam-results site is hit by an HTTP GET flood: millions of valid requests from thousands of IP addresses, each sending a few hundred per minute. Shield Standard is active. What should the architect add?
Self-checkQuestion
A security audit finds that attackers try SQL injection through the search box of a web application behind an ALB. The team wants a managed solution with no code change. What should they use?
Self-checkQuestion
A partner's firewall can only allow fixed IP addresses. The application runs behind an ALB and must be protected by AWS WAF. Which design meets both requirements, as the exam expects?
Self-checkQuestion
A web ACL was created in us-east-1 for an ALB in ap-southeast-1, but it does not appear when associating resources. Why?
Self-checkQuestion
A company with 50 accounts in AWS Organizations must apply the same AWS WAF rules to every ALB and CloudFront distribution, including those in accounts created later. What is the best solution?
Self-checkQuestion
Besides designating a Firewall Manager administrator account, which two are prerequisites for AWS Firewall Manager?
Choose 2
Self-checkQuestion
Which two policy types can AWS Firewall Manager manage across an Organization?
Choose 2
Self-checkQuestion
A new SQL injection rule group is added to the web ACL in Count mode. A matching request arrives. What happens?
Self-checkQuestion
After adding the AWS managed core rule set, applicants can no longer upload their photos (about 120 KB) to /apply on an ALB. What is the best fix?
Self-checkQuestion
A university's 3,000 students share one public IP address through a NAT gateway. On result day a WAF rate-based rule blocks all of them. Which change fixes this while still limiting abusive clients?
Self-checkQuestion
A web ACL with an IP-based rate rule is attached to an ALB that sits behind CloudFront. The rule either blocks large groups of users or nobody. Why?
Self-checkQuestion
An attacker floods a public ALB directly, bypassing the CloudFront distribution and its web ACL. Which change stops direct access while keeping CloudFront working?
Self-checkQuestion
Users must only be able to read files of an S3 bucket through CloudFront, never directly. What should be configured?
Self-checkQuestion
How does Shield Advanced protect an application running behind a Network Load Balancer?
Self-checkQuestion
What does Shield Advanced need in order to apply automatic application layer DDoS mitigation to a resource?
Self-checkQuestion
Shield Advanced keeps raising DDoS events on busy but healthy days. Which feature makes detection depend on the application's real health?
Self-checkQuestion
Which architecture best follows the AWS DDoS resiliency best practices for a public web application?
Self-checkQuestion
Which two labels from the AWS DDoS resiliency whitepaper are correct?
Choose 2
Self-checkQuestion
Which two changes reduce an application's attack surface?
Choose 2
Self-checkQuestion
A company needs to block 25,000 known malicious CIDR ranges with AWS WAF. What should the architect do?
Self-checkQuestion
Where can an AWS WAF web ACL send its full request logs?
Self-checkQuestion
Study notes say: WAF attaches to five services, ALB, API Gateway, CloudFront, AppSync and Cognito. What is the accurate version?
Self-checkQuestion
Study notes say a WAF rate-based rule blocks an IP that sends more than 2,000 requests in 5 minutes. Which statement is accurate?
Self-checkQuestion
A single team runs one application in one account and needs fine-grained rules against SQL injection and bad bots. Which service is enough?
Self-checkQuestion
In 2026 AWS began replacing Shield Advanced's automatic application layer mitigation with what?