Course outline

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

ResourceScope of the web ACL
Amazon CloudFront distributionGlobal: created in us-east-1 (the console calls it “Global (CloudFront)”)
Application Load BalancerRegional, same Region as the ALB
Amazon API Gateway REST APIRegional, same Region as the API
AWS AppSync GraphQL APIRegional
Amazon Cognito user poolRegional
AWS App Runner serviceRegional
AWS Verified Access instanceRegional
AWS Amplify appMust be created in the global CloudFront scope
Amazon Bedrock AgentCore GatewayRegional (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:

ActionWhat happensEnds the evaluation?
AllowThe request goes to the resourceYes
BlockWAF answers 403 Forbidden (or a custom response you define, such as a 429 page)Yes
CountWAF counts the match in metrics and logs, may add a label, and continuesNo
CAPTCHAThe client must solve a puzzle; a valid token lets later requests throughYes, unless the client has a valid token
ChallengeA silent browser check (JavaScript) instead of a puzzle; stops simple botsYes, 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

StatementExample on the results site
IP setBlock 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 matchBlock /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 injectionLook 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 constraintBlock a query string longer than 1 KB, or a body larger than expected.
String match and regex pattern setBlock a User-Agent used by a known bad tool, allow only /api/v2/… paths.
Label matchAct on labels added by earlier rules.
ASN matchMatch the network (autonomous system) the request comes from.
Rate-basedCount requests per key over a window and act above a limit (section below).
AND / OR / NOTCombine 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.

Studentin Dhaka
Attacker
Web ACLon CloudFront
ALBorigin
Results app
WAF logs
GET /result

Request

Path

/result?roll=482913

Country

Bangladesh

Source IP

198.51.100.20

Step 1 of 3
1

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 an Authorization header 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.

Buyer firewallallowlist only2 IPs allowed
Global Accelerator2 static IPs
ALBweb ACL attached
Order API
HTTPS to 2 IPs
Step 1 of 4
1

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.

Botnet
Students
CloudFrontweb ACL
ALBorigin
App fleet
SYN + UDP flood
Step 1 of 3
1

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 StandardShield Advanced
CostFree3,000 USD per month per organization, 1-year commitment, plus data transfer fees
Turned onAutomatically, for everyoneSubscribe, then add each resource
Layers3 and 43, 4 and 7 (layer 7 through WAF)
ResourcesAll AWS customers; strongest at CloudFront, Route 53, Global AcceleratorCloudFront, Route 53, Global Accelerator, ALB, CLB, Elastic IPs (EC2, NLB)
DetectionGeneric, AWS-wideTuned per resource, health-based with Route 53 health checks
ExpertsNoneShield Response Team 24/7, proactive engagement
Bill protectionNoneDDoS cost protection (service credits)
WAF chargesPaid separatelyIncluded 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

  1. The accounts are in AWS Organizations with all features enabled (lesson 20.1).
  2. A Firewall Manager administrator account is chosen (from the management account; usually a dedicated security account).
  3. 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).
  4. For Network Firewall and DNS Firewall policies, resource sharing through AWS RAM; for third-party firewalls, a Marketplace subscription.

#Policy types

Policy typeWhat it enforces
AWS WAFWeb 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 AdvancedShield Advanced protection (and optionally automatic application layer mitigation) on the chosen resource types
Security groupCommon 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 ACLA baseline of network ACL rules on subnets
AWS Network FirewallFirewall endpoints and rule groups in VPCs (lesson 22.7)
Route 53 Resolver DNS FirewallDomain block and allow lists on VPCs
Third-party firewallsPalo 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.

Firewall Manageradmin accountWAF policy
Shop accountALBs
Payments accountEC2 + SGs
Step 1 of 3
1

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 needChoose
Granular layer 7 rules for one application or one accountAWS WAF alone
The same WAF rules across many accounts, faster rollout, automatic protection of new resourcesFirewall Manager with AWS WAF
DDoS specialists, cost protection, tuned detection, advanced reporting on top of WAF; frequent or costly DDoS attacksShield Advanced
Basic protection against network floodsShield Standard (already on)
Central security groups, network ACLs, Network Firewall or DNS Firewall policiesFirewall 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:

LabelBuilding blockWhat it gives
BP1CloudFront and Global AcceleratorDelivery from the edge, huge capacity, SYN flood and reflection mitigation before traffic reaches the Region
BP2AWS WAFLayer 7 filtering on CloudFront and the ALB: rate-based rules, managed rules, geo and IP rules
BP3Route 53DNS answered at the edge, with shuffle sharding and anycast to stay up during DNS floods
BP4API GatewayA managed front door for APIs that hides the back end, with throttling
BP5Security groups and network ACLs in the VPCOnly the needed ports and sources reach the subnets and instances
BP6Elastic Load BalancingScales with traffic and spreads it over many targets; only valid TCP connections reach them
BP7EC2 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.

Students
CloudFrontcache + WAF
ALB
Auto Scalingapp servers
SQS queue
Workers
1M visits
Step 1 of 2
1

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.

Scraper bot203.0.113.9
Campus NAT3,000 students
Rate rule2,000 per 5 min
Results site
GET /result

Counter for 203.0.113.9

Last 5 min

1,200

Limit

2,000

Action

none (allowed)

Step 1 of 2
1

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 example X-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.

Student
Attacker
CloudFrontweb ACL
ALBsecurity group
App servers
+ secret header
Step 1 of 2
1

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).