Skip to content
intermediate Phase 6 · AWS Security & Compliance

WAF & Shield

Protect applications from web attacks with WAF and DDoS protection with Shield.

1h
0 problems
Topic Progress 0%

WAF Fundamentals

WAF Fundamentals

AWS WAF is a web application firewall that protects against common web exploits and bots.

WAF Components

Component Description
Web ACL Collection of rules
Rules Conditions that trigger actions
Rule Group Reusable set of rules
Action Allow, Block, or Count

Create Web ACL

# Create a web ACL
aws wafv2 create-web-acl \
  --name my-web-acl \
  --scope REGIONAL \
  --default-action '{"Allow": {}}' \
  --rules '[{
    "Name": "RateLimitRule",
    "Priority": 1,
    "Statement": {
      "RateBasedStatement": {
        "Limit": 2000,
        "AggregateKeyType": "IP"
      }
    },
    "Action": {"Block": {}},
    "VisibilityConfig": {
      "SampledRequestsEnabled": true,
      "CloudWatchMetricsEnabled": true,
      "MetricName": "RateLimitRule"
    }
  }]' \
  --visibility-config '{
    "SampledRequestsEnabled": true,
    "CloudWatchMetricsEnabled": true,
    "MetricName": "my-web-acl"
  }' \
  --association-configuration '{
    "RequestBodyConfig": {
      "InspectionSize": 8192
    }
  }'

Attach to ALB

# Associate WAF with ALB
aws wafv2 associate-web-acl \
  --web-acl-arn arn:aws:wafv2:us-east-1:xxx:regional/webacl/my-web-acl/xxx \
  --resource-arn arn:aws:elasticloadbalancing:us-east-1:xxx:loadbalancer/app/my-alb/xxx

WAF Rules and Conditions

WAF Rules and Conditions

Rate-Based Rules

# Block IPs making more than 100 requests per 5 minutes
aws wafv2 create-web-acl \
  --name rate-limiting \
  --scope REGIONAL \
  --default-action '{"Allow": {}}' \
  --rules '[{
    "Name": "RateLimit",
    "Priority": 1,
    "Statement": {
      "RateBasedStatement": {
        "Limit": 100,
        "AggregateKeyType": "IP"
      }
    },
    "Action": {"Block": {}},
    "VisibilityConfig": {
      "SampledRequestsEnabled": true,
      "CloudWatchMetricsEnabled": true,
      "MetricName": "RateLimit"
    }
  }]'

IP Set Filtering

# Create IP set
aws wafv2 create-ip-set \
  --name blocked-ips \
  --scope REGIONAL \
  --addresses '203.0.113.0/24,198.51.100.1'

# Create rule using IP set
aws wafv2 create-web-acl \
  --name ip-filtering \
  --scope REGIONAL \
  --default-action '{"Allow": {}}' \
  --rules '[{
    "Name": "BlockBadIPs",
    "Priority": 1,
    "Statement": {
      "IPSetReferenceStatement": {
        "ARN": "arn:aws:wafv2:us-east-1:xxx:regional/ipset/blocked-ips/xxx"
      }
    },
    "Action": {"Block": {}},
    "VisibilityConfig": {
      "SampledRequestsEnabled": true,
      "CloudWatchMetricsEnabled": true,
      "MetricName": "BlockBadIPs"
    }
  }]'

SQL Injection Protection

# Add SQL injection rule
aws wafv2 update-web-acl \
  --name my-web-acl \
  --scope REGIONAL \
  --lock-token lock-token \
  --rules '[{
    "Name": "SQLInjection",
    "Priority": 2,
    "Statement": {
      "SqliMatchStatement": {
        "FieldToMatch": {
          "Body": {
            "OversizeHandling": "MATCH"
          }
        },
        "TextTransformations": [{
          "Priority": 0,
          "Type": "URL_DECODE"
        }]
      }
    },
    "Action": {"Block": {}},
    "VisibilityConfig": {
      "SampledRequestsEnabled": true,
      "CloudWatchMetricsEnabled": true,
      "MetricName": "SQLInjection"
    }
  }]'

Managed Rule Groups

# AWS Managed Rules
# - AWSManagedRulesCommonRuleSet: Common attacks
# - AWSManagedRulesSQLiRuleSet: SQL injection
# - AWSManagedRulesKnownBadInputsRuleSet: Known bad inputs
# - AWSManagedRulesAdminProtectRuleSet: Admin path protection

aws wafv2 update-web-acl \
  --name my-web-acl \
  --scope REGIONAL \
  --lock-token lock-token \
  --rules '[{
    "Name": "AWSManagedRulesCommon",
    "Priority": 0,
    "Statement": {
      "ManagedRuleGroupStatement": {
        "VendorName": "AWS",
        "Name": "AWSManagedRulesCommonRuleSet"
      }
    },
    "OverrideAction": {"None": {}},
    "VisibilityConfig": {
      "SampledRequestsEnabled": true,
      "CloudWatchMetricsEnabled": true,
      "MetricName": "AWSManagedRulesCommon"
    }
  }]'

AWS Shield

AWS Shield

Shield Standard vs Advanced

Feature Standard Advanced
DDoS Protection Basic Advanced
Cost Free $3,000/month
24/7 DDoS Response Team No Yes
Cost Protection No Yes
Advanced Metrics No Yes
WAF Integration Yes Yes

Shield Advanced

# Enable Shield Advanced
aws shield create-subscription

# Add protection
aws shield create-protection \
  --name my-alb-protection \
  --resource-arn arn:aws:elasticloadbalancing:us-east-1:xxx:loadbalancer/app/my-alb/xxx

# Create protection group
aws shield create-protection-group \
  --protection-group-id my-group \
  --aggregation TYPE \
  --pattern ALL \
  --members '[{
    "Type": "APPLICATION_LOAD_BALANCER",
    "ResourceId": "xxx"
  }]'

# Get subscription details
aws shield describe-subscription

# Get attack details
aws shield describe-dirt-access-event --max-items 10

Shield DDoS Protection

┌─────────────────────────────────────────────────────────────┐
│                Shield Protection Architecture                │
├─────────────────────────────────────────────────────────────┤
│                                                             │
│  DDoS Attack ──▶ Shield ──▶ Auto-mitigation               │
│                               ├── Rate limiting             │
│                               ├── IP blocking              │
│                               └── Geographic restriction   │
│                                                             │
│  If protection fails:                                       │
│  • AWS credits for scaling costs                            │
│  • 24/7 DDoS Response Team                                  │
│  • Advanced monitoring                                      │
└─────────────────────────────────────────────────────────────┘

WAF Monitoring and Automation

WAF Monitoring and Automation

CloudWatch Metrics

# Get WAF metrics
aws cloudwatch get-metric-statistics \
  --namespace AWS/WAF \
  --metric-name AllowedRequests \
  --dimensions Name=WebACL,Value=my-web-acl Name=Region,Value=us-east-1 \
  --start-time $(date -u -d '1 hour ago') \
  --end-time $(date -u) \
  --period 300 \
  --statistics Sum

# Key metrics:
# - AllowedRequests: Requests allowed by WAF
# - BlockedRequests: Requests blocked by WAF
# - CountedRequests: Requests matched by counting rules

CloudWatch Alarms

# Alarm on high block rate
aws cloudwatch put-metric-alarm \
  --alarm-name WAF-High-Block-Rate \
  --metric-name BlockedRequests \
  --namespace AWS/WAF \
  --dimensions Name=WebACL,Value=my-web-acl Name=Region,Value=us-east-1 \
  --statistic Sum \
  --period 300 \
  --threshold 1000 \
  --comparison-operator GreaterThanThreshold \
  --evaluation-periods 1 \
  --alarm-actions arn:aws:sns:us-east-1:xxx:security-alerts

WAF Logging

# Enable logging to S3
aws wafv2 put-logging-configuration \
  --logging-configuration '{
    "ResourceArn": "arn:aws:wafv2:us-east-1:xxx:regional/webacl/my-web-acl/xxx",
    "LogDestinationConfigs": ["arn:aws:s3:::my-waf-logs"],
    "RedactedFields": [
      {
        "SingleHeader": {"Name": "authorization"}
      },
      {
        "SingleHeader": {"Name": "cookie"}
      }
    ]
  }'

Automated Responses

# Lambda function for automated IP blocking
import boto3

def lambda_handler(event, context):
    # Parse CloudWatch alarm
    detail = event['detail']
    if detail['state']['value'] == 'ALARM':
        # Add IP to block list
        waf = boto3.client('wafv2')
        waf.update_ip_set(
            Name='auto-blocked-ips',
            Scope='REGIONAL',
            Id='xxx',
            Addresses=['attacker-ip/32']
        )

WAF Best Practices

WAF Best Practices

Defense in Depth

┌─────────────────────────────────────────────────────────────┐
│                   Security Layers                            │
├─────────────────────────────────────────────────────────────┤
│                                                             │
│  Layer 1: Shield (DDoS protection)                         │
│  Layer 2: WAF (Application firewall)                       │
│  Layer 3: Security Groups (Network firewall)               │
│  Layer 4: IAM (Access control)                             │
│  Layer 5: Encryption (Data protection)                      │
│                                                             │
└─────────────────────────────────────────────────────────────┘

Best Practices

  1. Start with AWS Managed Rules for common protection
  2. Use rate-based rules to prevent abuse
  3. Implement geo-blocking if not serving global users
  4. Log all requests for forensics
  5. Use counting mode before blocking to test rules
  6. Implement automated responses to common attacks
  7. Monitor metrics and adjust thresholds
  8. Use rule groups for reusable protection

Cost Optimization

Feature Cost
WAF Web ACL $5/month
WAF Rules $1/rule/month
WAF Requests $0.60 per million
Managed Rules $1-10/rule/month
Shield Standard Free
Shield Advanced $3,000/month
# Use counting mode to test rules before blocking
aws wafv2 update-web-acl \
  --name my-web-acl \
  --scope REGIONAL \
  --lock-token lock-token \
  --rules '[{
    "Name": "TestRule",
    "Priority": 1,
    "Statement": {
      "SqliMatchStatement": {
        "FieldToMatch": {"UriPath": {}},
        "TextTransformations": [{"Priority": 0, "Type": "URL_DECODE"}]
      }
    },
    "Action": {"Count": {}},
    "VisibilityConfig": {
      "SampledRequestsEnabled": true,
      "CloudWatchMetricsEnabled": true,
      "MetricName": "TestRule"
    }
  }]'