VPC Security Tutorial: Building Your AWS Network Fortress | AWSight
AWSight
AWS Security Insights

VPC Security Tutorial: Building Your AWS Network Fortress

Learn how to build an impenetrable VPC network defense that stops DDoS attacks before they cost you millions

🚨 The $5.3 Million Holiday DDoS Disaster

In November 2023, an Indonesian e-commerce platform faced the largest retail DDoS attack ever recorded—2.3 million requests per second during their Black Friday sale. The attack originated from over 6,300 IP addresses and escalated within just 6 minutes.

$5.3M

in lost holiday sales, server costs, and emergency mitigation fees during their peak shopping period. The attack exploited weak VPC network controls that could have been prevented with proper security group and NACL configurations.

The root cause? Their VPC had overly permissive security groups (0.0.0.0/0 on multiple ports), no WAF protection, and missing DDoS shields—creating the perfect storm for disaster.

417%
increase in retail DDoS attacks in 2024
106%
surge in DDoS attack frequency year-over-year
$6,000
average cost per minute during DDoS attack
45
minutes average DDoS attack duration

🎯 Want Our Complete AWS Security Checklist?

Don't just secure your VPC—get our comprehensive 20-point security checklist covering all critical AWS configurations. Used by 500+ companies to prevent security incidents and maintain continuous compliance.

🎯 Why VPC Security Misconfigurations Are So Dangerous

Your AWS VPC is the foundation of your entire cloud security posture. Unlike other vulnerabilities that might affect individual resources, VPC misconfigurations expose your entire network infrastructure to attack, potentially compromising hundreds of resources simultaneously.

🏰 The Multi-Layer VPC Defense Architecture

Internet Gateway → WAF → Shield → NACL → Security Groups → EC2 Instances

Each layer provides specific protection against different attack vectors

The Five Most Critical VPC Attack Vectors

🌊 Layer 3/4 DDoS Attacks (Network/Transport Layer)

Volumetric attacks that flood your network with massive amounts of traffic—UDP floods, SYN floods, and amplification attacks. These can overwhelm your VPC's network capacity and knock out entire subnets.

🎯 Layer 7 DDoS Attacks (Application Layer)

Sophisticated HTTP floods targeting your web applications with seemingly legitimate requests. These bypass basic network filters and can exhaust application resources while appearing normal.

🔓 Overly Permissive Security Groups

Security groups with 0.0.0.0/0 access on critical ports (22, 3389, 3306) expose instances to brute force attacks, data exfiltration, and lateral movement within your VPC.

🕳️ Missing NACL Protection

Default NACLs that allow all traffic remove your subnet-level defense, enabling attackers to move freely between subnets once they breach the perimeter.

🚫 No Application Layer Filtering

Without WAF protection, attackers can exploit application vulnerabilities like SQL injection, XSS, and OWASP Top 10 attacks directly against your web applications.

⚠️ Critical Insight: According to AWS security reports, DDoS attacks surged 106% from H2 2023 to H1 2024, with retail industry seeing a 417% increase in DDoS attacks. The average attack now lasts 45 minutes and costs $270,000 per incident.

🏗️ VPC Security Architecture Design

Before implementing individual components, it's crucial to understand how VPC security layers work together to create a comprehensive defense strategy.

🛡️ Layer 1: AWS Shield (Network Edge)

Purpose: Protects against network and transport layer (L3/L4) DDoS attacks at the AWS network edge.
Coverage: Automatic protection for all AWS resources, enhanced protection with Shield Advanced.
Detection Time: Seconds to minutes for volumetric attacks.

🔥 Layer 2: AWS WAF (Application Gateway)

Purpose: Filters malicious application layer (L7) traffic and advanced DDoS attacks.
Coverage: Web application protection, bot management, rate limiting.
Detection Time: Real-time request inspection and blocking.

🚧 Layer 3: Network ACLs (Subnet Level)

Purpose: Stateless firewall that controls traffic entering and leaving VPC subnets.
Coverage: Subnet-level traffic filtering with allow/deny rules.
Scope: Affects all instances within the subnet.

🔐 Layer 4: Security Groups (Instance Level)

Purpose: Stateful firewall that controls traffic to individual EC2 instances.
Coverage: Instance-level protection with allow-only rules.
Scope: Granular control per instance or group of instances.

Defense in Depth Strategy

Each layer provides specific protection capabilities:

  • Shield: Absorbs volumetric attacks before they reach your VPC
  • WAF: Blocks malicious application requests and bot traffic
  • NACLs: Provide subnet boundaries and network segmentation
  • Security Groups: Create micro-segmentation around individual resources
1
Create Secure VPC Foundation (8 minutes)

Prerequisites:

  • AWS CLI configured with appropriate permissions
  • VPC creation permissions (ec2:CreateVpc, ec2:CreateSubnet, etc.)
  • Understanding of CIDR block allocation

Design Principles:

  • Network Segmentation: Separate public and private subnets across multiple AZs
  • Least Privilege: Default deny with explicit allow rules
  • Defense in Depth: Multiple security layers
  • Monitoring: Enable VPC Flow Logs for all traffic

Console Steps:

1.1 Create VPC with Secure Defaults

  • Navigate to VPC Dashboard → "Create VPC"
  • Select "VPC and more" for guided setup
  • Name: secure-vpc-production
  • IPv4 CIDR: 10.0.0.0/16 (65,536 IP addresses)
  • IPv6 CIDR: None (unless specifically required)
  • Tenancy: Default
  • Enable DNS hostnames and DNS resolution
# Create VPC via AWS CLI aws ec2 create-vpc \ --cidr-block 10.0.0.0/16 \ --enable-dns-hostnames \ --enable-dns-support \ --tag-specifications 'ResourceType=vpc,Tags=[{Key=Name,Value=secure-vpc-production},{Key=Environment,Value=production},{Key=Security,Value=high}]' # Get VPC ID for subsequent commands VPC_ID=$(aws ec2 describe-vpcs --filters "Name=tag:Name,Values=secure-vpc-production" --query 'Vpcs[0].VpcId' --output text) echo "VPC ID: $VPC_ID"

1.2 Create Multi-AZ Subnet Architecture

# Create Public Subnets (for load balancers, NAT gateways) aws ec2 create-subnet \ --vpc-id $VPC_ID \ --cidr-block 10.0.1.0/24 \ --availability-zone us-east-1a \ --tag-specifications 'ResourceType=subnet,Tags=[{Key=Name,Value=public-subnet-1a},{Key=Type,Value=public}]' aws ec2 create-subnet \ --vpc-id $VPC_ID \ --cidr-block 10.0.2.0/24 \ --availability-zone us-east-1b \ --tag-specifications 'ResourceType=subnet,Tags=[{Key=Name,Value=public-subnet-1b},{Key=Type,Value=public}]' # Create Private Subnets (for application servers) aws ec2 create-subnet \ --vpc-id $VPC_ID \ --cidr-block 10.0.10.0/24 \ --availability-zone us-east-1a \ --tag-specifications 'ResourceType=subnet,Tags=[{Key=Name,Value=private-subnet-1a},{Key=Type,Value=private}]' aws ec2 create-subnet \ --vpc-id $VPC_ID \ --cidr-block 10.0.20.0/24 \ --availability-zone us-east-1b \ --tag-specifications 'ResourceType=subnet,Tags=[{Key=Name,Value=private-subnet-1b},{Key=Type,Value=private}]' # Create Database Subnets (for RDS instances) aws ec2 create-subnet \ --vpc-id $VPC_ID \ --cidr-block 10.0.50.0/24 \ --availability-zone us-east-1a \ --tag-specifications 'ResourceType=subnet,Tags=[{Key=Name,Value=database-subnet-1a},{Key=Type,Value=database}]' aws ec2 create-subnet \ --vpc-id $VPC_ID \ --cidr-block 10.0.60.0/24 \ --availability-zone us-east-1b \ --tag-specifications 'ResourceType=subnet,Tags=[{Key=Name,Value=database-subnet-1b},{Key=Type,Value=database}]'

1.3 Enable VPC Flow Logs

# Create CloudWatch log group for VPC Flow Logs aws logs create-log-group --log-group-name VPCFlowLogs # Enable VPC Flow Logs aws ec2 create-flow-logs \ --resource-type VPC \ --resource-ids $VPC_ID \ --traffic-type ALL \ --log-destination-type cloud-watch-logs \ --log-group-name VPCFlowLogs \ --deliver-logs-permission-arn arn:aws:iam::ACCOUNT-ID:role/flowlogsRole
Foundation Complete: You now have a well-architected VPC with proper network segmentation across multiple availability zones and comprehensive logging enabled.
2
Configure Security Groups Defense (10 minutes)

Security groups act as virtual firewalls at the instance level. We'll create purpose-built security groups following the principle of least privilege.

Console Steps:

2.1 Create Web Tier Security Group

# Create security group for web tier (load balancers) WEB_SG=$(aws ec2 create-security-group \ --group-name web-tier-sg \ --description "Security group for web tier - load balancers and web servers" \ --vpc-id $VPC_ID \ --tag-specifications 'ResourceType=security-group,Tags=[{Key=Name,Value=web-tier-sg},{Key=Tier,Value=web}]' \ --query 'GroupId' --output text) # Allow HTTPS from internet (port 443) aws ec2 authorize-security-group-ingress \ --group-id $WEB_SG \ --protocol tcp \ --port 443 \ --cidr 0.0.0.0/0 # Allow HTTP from internet (port 80) - redirect to HTTPS aws ec2 authorize-security-group-ingress \ --group-id $WEB_SG \ --protocol tcp \ --port 80 \ --cidr 0.0.0.0/0 # Allow health checks from ALB health check ranges aws ec2 authorize-security-group-ingress \ --group-id $WEB_SG \ --protocol tcp \ --port 80 \ --cidr 10.0.0.0/16

2.2 Create Application Tier Security Group

# Create security group for application tier APP_SG=$(aws ec2 create-security-group \ --group-name app-tier-sg \ --description "Security group for application tier - app servers" \ --vpc-id $VPC_ID \ --tag-specifications 'ResourceType=security-group,Tags=[{Key=Name,Value=app-tier-sg},{Key=Tier,Value=application}]' \ --query 'GroupId' --output text) # Allow HTTP from web tier only aws ec2 authorize-security-group-ingress \ --group-id $APP_SG \ --protocol tcp \ --port 8080 \ --source-group $WEB_SG # Allow HTTPS from web tier only aws ec2 authorize-security-group-ingress \ --group-id $APP_SG \ --protocol tcp \ --port 8443 \ --source-group $WEB_SG # Allow SSH from bastion host (create bastion SG first) BASTION_SG=$(aws ec2 create-security-group \ --group-name bastion-sg \ --description "Security group for bastion host" \ --vpc-id $VPC_ID \ --query 'GroupId' --output text) aws ec2 authorize-security-group-ingress \ --group-id $APP_SG \ --protocol tcp \ --port 22 \ --source-group $BASTION_SG

2.3 Create Database Tier Security Group

# Create security group for database tier DB_SG=$(aws ec2 create-security-group \ --group-name database-tier-sg \ --description "Security group for database tier - RDS instances" \ --vpc-id $VPC_ID \ --tag-specifications 'ResourceType=security-group,Tags=[{Key=Name,Value=database-tier-sg},{Key=Tier,Value=database}]' \ --query 'GroupId' --output text) # Allow MySQL/Aurora from application tier only aws ec2 authorize-security-group-ingress \ --group-id $DB_SG \ --protocol tcp \ --port 3306 \ --source-group $APP_SG # Allow PostgreSQL from application tier only aws ec2 authorize-security-group-ingress \ --group-id $DB_SG \ --protocol tcp \ --port 5432 \ --source-group $APP_SG # Allow Redis from application tier only aws ec2 authorize-security-group-ingress \ --group-id $DB_SG \ --protocol tcp \ --port 6379 \ --source-group $APP_SG

2.4 Configure Bastion Host Security Group

# Allow SSH from specific admin IP ranges only (replace with your IPs) aws ec2 authorize-security-group-ingress \ --group-id $BASTION_SG \ --protocol tcp \ --port 22 \ --cidr 203.0.113.0/24 # Replace with your office IP range # Allow SSH from corporate VPN range aws ec2 authorize-security-group-ingress \ --group-id $BASTION_SG \ --protocol tcp \ --port 22 \ --cidr 198.51.100.0/24 # Replace with your VPN IP range
⚠️ Security Best Practice: Never use 0.0.0.0/0 for SSH (port 22), RDP (port 3389), or database ports. Always restrict access to specific IP ranges or security groups. Replace the example IP ranges above with your actual office/VPN IP addresses.
Micro-Segmentation Complete: Your instances now have purpose-built security groups that enforce the principle of least privilege and prevent lateral movement between tiers.
VPC Security Tutorial: Building Your AWS Network Fortress | AWSight
3
Set up NACL Network Barriers (8 minutes)

Network ACLs provide subnet-level stateless firewall protection. Unlike security groups, NACLs can deny traffic and provide an additional layer of defense.

Console Steps:

3.1 Create Public Subnet NACL

# Create NACL for public subnets PUBLIC_NACL=$(aws ec2 create-network-acl \ --vpc-id $VPC_ID \ --tag-specifications 'ResourceType=network-acl,Tags=[{Key=Name,Value=public-nacl},{Key=Tier,Value=public}]' \ --query 'NetworkAcl.NetworkAclId' --output text) # Allow inbound HTTPS from internet aws ec2 create-network-acl-entry \ --network-acl-id $PUBLIC_NACL \ --rule-number 100 \ --protocol tcp \ --rule-action allow \ --port-range From=443,To=443 \ --cidr-block 0.0.0.0/0 # Allow inbound HTTP from internet (for redirects) aws ec2 create-network-acl-entry \ --network-acl-id $PUBLIC_NACL \ --rule-number 110 \ --protocol tcp \ --rule-action allow \ --port-range From=80,To=80 \ --cidr-block 0.0.0.0/0 # Allow ephemeral ports for outbound connections aws ec2 create-network-acl-entry \ --network-acl-id $PUBLIC_NACL \ --rule-number 120 \ --protocol tcp \ --rule-action allow \ --port-range From=1024,To=65535 \ --cidr-block 0.0.0.0/0 # Allow outbound HTTPS aws ec2 create-network-acl-entry \ --network-acl-id $PUBLIC_NACL \ --rule-number 100 \ --protocol tcp \ --rule-action allow \ --port-range From=443,To=443 \ --cidr-block 0.0.0.0/0 \ --egress # Allow outbound HTTP aws ec2 create-network-acl-entry \ --network-acl-id $PUBLIC_NACL \ --rule-number 110 \ --protocol tcp \ --rule-action allow \ --port-range From=80,To=80 \ --cidr-block 0.0.0.0/0 \ --egress # Allow ephemeral ports outbound aws ec2 create-network-acl-entry \ --network-acl-id $PUBLIC_NACL \ --rule-number 120 \ --protocol tcp \ --rule-action allow \ --port-range From=1024,To=65535 \ --cidr-block 0.0.0.0/0 \ --egress

3.2 Create Private Subnet NACL

# Create NACL for private subnets PRIVATE_NACL=$(aws ec2 create-network-acl \ --vpc-id $VPC_ID \ --tag-specifications 'ResourceType=network-acl,Tags=[{Key=Name,Value=private-nacl},{Key=Tier,Value=private}]' \ --query 'NetworkAcl.NetworkAclId' --output text) # Allow traffic from public subnets only aws ec2 create-network-acl-entry \ --network-acl-id $PRIVATE_NACL \ --rule-number 100 \ --protocol tcp \ --rule-action allow \ --port-range From=8080,To=8080 \ --cidr-block 10.0.1.0/24 # Public subnet 1a aws ec2 create-network-acl-entry \ --network-acl-id $PRIVATE_NACL \ --rule-number 110 \ --protocol tcp \ --rule-action allow \ --port-range From=8080,To=8080 \ --cidr-block 10.0.2.0/24 # Public subnet 1b # Allow SSH from bastion subnet only aws ec2 create-network-acl-entry \ --network-acl-id $PRIVATE_NACL \ --rule-number 120 \ --protocol tcp \ --rule-action allow \ --port-range From=22,To=22 \ --cidr-block 10.0.1.0/24 # Allow ephemeral ports for responses aws ec2 create-network-acl-entry \ --network-acl-id $PRIVATE_NACL \ --rule-number 130 \ --protocol tcp \ --rule-action allow \ --port-range From=1024,To=65535 \ --cidr-block 0.0.0.0/0 # Outbound rules for private NACL aws ec2 create-network-acl-entry \ --network-acl-id $PRIVATE_NACL \ --rule-number 100 \ --protocol tcp \ --rule-action allow \ --port-range From=443,To=443 \ --cidr-block 0.0.0.0/0 \ --egress aws ec2 create-network-acl-entry \ --network-acl-id $PRIVATE_NACL \ --rule-number 110 \ --protocol tcp \ --rule-action allow \ --port-range From=3306,To=3306 \ --cidr-block 10.0.50.0/24 \ --egress # Database subnet access aws ec2 create-network-acl-entry \ --network-acl-id $PRIVATE_NACL \ --rule-number 120 \ --protocol tcp \ --rule-action allow \ --port-range From=1024,To=65535 \ --cidr-block 0.0.0.0/0 \ --egress

3.3 Create Database Subnet NACL

# Create NACL for database subnets DATABASE_NACL=$(aws ec2 create-network-acl \ --vpc-id $VPC_ID \ --tag-specifications 'ResourceType=network-acl,Tags=[{Key=Name,Value=database-nacl},{Key=Tier,Value=database}]' \ --query 'NetworkAcl.NetworkAclId' --output text) # Allow MySQL from private subnets only aws ec2 create-network-acl-entry \ --network-acl-id $DATABASE_NACL \ --rule-number 100 \ --protocol tcp \ --rule-action allow \ --port-range From=3306,To=3306 \ --cidr-block 10.0.10.0/24 # Private subnet 1a aws ec2 create-network-acl-entry \ --network-acl-id $DATABASE_NACL \ --rule-number 110 \ --protocol tcp \ --rule-action allow \ --port-range From=3306,To=3306 \ --cidr-block 10.0.20.0/24 # Private subnet 1b # Allow PostgreSQL from private subnets only aws ec2 create-network-acl-entry \ --network-acl-id $DATABASE_NACL \ --rule-number 120 \ --protocol tcp \ --rule-action allow \ --port-range From=5432,To=5432 \ --cidr-block 10.0.10.0/24 aws ec2 create-network-acl-entry \ --network-acl-id $DATABASE_NACL \ --rule-number 130 \ --protocol tcp \ --rule-action allow \ --port-range From=5432,To=5432 \ --cidr-block 10.0.20.0/24 # Deny all other inbound traffic (explicit deny) aws ec2 create-network-acl-entry \ --network-acl-id $DATABASE_NACL \ --rule-number 200 \ --protocol -1 \ --rule-action deny \ --cidr-block 0.0.0.0/0 # Allow outbound ephemeral ports for responses aws ec2 create-network-acl-entry \ --network-acl-id $DATABASE_NACL \ --rule-number 100 \ --protocol tcp \ --rule-action allow \ --port-range From=1024,To=65535 \ --cidr-block 10.0.0.0/16 \ --egress

3.4 Associate NACLs with Subnets

# Get subnet IDs PUBLIC_SUBNET_1A=$(aws ec2 describe-subnets --filters "Name=tag:Name,Values=public-subnet-1a" --query 'Subnets[0].SubnetId' --output text) PUBLIC_SUBNET_1B=$(aws ec2 describe-subnets --filters "Name=tag:Name,Values=public-subnet-1b" --query 'Subnets[0].SubnetId' --output text) PRIVATE_SUBNET_1A=$(aws ec2 describe-subnets --filters "Name=tag:Name,Values=private-subnet-1a" --query 'Subnets[0].SubnetId' --output text) PRIVATE_SUBNET_1B=$(aws ec2 describe-subnets --filters "Name=tag:Name,Values=private-subnet-1b" --query 'Subnets[0].SubnetId' --output text) DATABASE_SUBNET_1A=$(aws ec2 describe-subnets --filters "Name=tag:Name,Values=database-subnet-1a" --query 'Subnets[0].SubnetId' --output text) DATABASE_SUBNET_1B=$(aws ec2 describe-subnets --filters "Name=tag:Name,Values=database-subnet-1b" --query 'Subnets[0].SubnetId' --output text) # Associate NACLs with subnets aws ec2 associate-network-acl --network-acl-id $PUBLIC_NACL --subnet-id $PUBLIC_SUBNET_1A aws ec2 associate-network-acl --network-acl-id $PUBLIC_NACL --subnet-id $PUBLIC_SUBNET_1B aws ec2 associate-network-acl --network-acl-id $PRIVATE_NACL --subnet-id $PRIVATE_SUBNET_1A aws ec2 associate-network-acl --network-acl-id $PRIVATE_NACL --subnet-id $PRIVATE_SUBNET_1B aws ec2 associate-network-acl --network-acl-id $DATABASE_NACL --subnet-id $DATABASE_SUBNET_1A aws ec2 associate-network-acl --network-acl-id $DATABASE_NACL --subnet-id $DATABASE_SUBNET_1B
Network Segmentation Complete: Your subnets now have subnet-level firewall protection with explicit deny rules and network segmentation between tiers.
4
Deploy AWS WAF Application Protection (5 minutes)

AWS WAF protects your web applications from common web exploits and Layer 7 DDoS attacks. We'll configure comprehensive protection with managed rules and custom rate limiting.

Console Steps:

4.1 Create WAF Web ACL

# Create WAF Web ACL cat > waf-webacl.json << EOF { "Name": "production-web-acl", "Scope": "REGIONAL", "DefaultAction": { "Allow": {} }, "Description": "Production Web ACL with comprehensive protection", "Rules": [ { "Name": "AWSManagedRulesCommonRuleSet", "Priority": 1, "OverrideAction": { "None": {} }, "Statement": { "ManagedRuleGroupStatement": { "VendorName": "AWS", "Name": "AWSManagedRulesCommonRuleSet" } }, "VisibilityConfig": { "SampledRequestsEnabled": true, "CloudWatchMetricsEnabled": true, "MetricName": "CommonRuleSetMetric" } }, { "Name": "AWSManagedRulesKnownBadInputsRuleSet", "Priority": 2, "OverrideAction": { "None": {} }, "Statement": { "ManagedRuleGroupStatement": { "VendorName": "AWS", "Name": "AWSManagedRulesKnownBadInputsRuleSet" } }, "VisibilityConfig": { "SampledRequestsEnabled": true, "CloudWatchMetricsEnabled": true, "MetricName": "KnownBadInputsMetric" } }, { "Name": "AWSManagedRulesAmazonIpReputationList", "Priority": 3, "OverrideAction": { "None": {} }, "Statement": { "ManagedRuleGroupStatement": { "VendorName": "AWS", "Name": "AWSManagedRulesAmazonIpReputationList" } }, "VisibilityConfig": { "SampledRequestsEnabled": true, "CloudWatchMetricsEnabled": true, "MetricName": "IpReputationMetric" } }, { "Name": "AWSManagedRulesAntiDDoSRuleSet", "Priority": 4, "OverrideAction": { "None": {} }, "Statement": { "ManagedRuleGroupStatement": { "VendorName": "AWS", "Name": "AWSManagedRulesAntiDDoSRuleSet" } }, "VisibilityConfig": { "SampledRequestsEnabled": true, "CloudWatchMetricsEnabled": true, "MetricName": "AntiDDoSMetric" } } ], "VisibilityConfig": { "SampledRequestsEnabled": true, "CloudWatchMetricsEnabled": true, "MetricName": "ProductionWebACL" } } EOF # Create the Web ACL aws wafv2 create-web-acl \ --cli-input-json file://waf-webacl.json \ --region us-east-1

4.2 Add Rate Limiting Rules

# Create rate limiting rule cat > rate-limit-rule.json << EOF { "Name": "RateLimitRule", "Priority": 5, "Statement": { "RateBasedStatement": { "Limit": 2000, "AggregateKeyType": "IP" } }, "Action": { "Block": {} }, "VisibilityConfig": { "SampledRequestsEnabled": true, "CloudWatchMetricsEnabled": true, "MetricName": "RateLimitMetric" } } EOF # Get Web ACL ID WEB_ACL_ID=$(aws wafv2 list-web-acls --scope REGIONAL --region us-east-1 --query "WebACLs[?Name=='production-web-acl'].Id" --output text) # Add rate limiting rule to Web ACL aws wafv2 update-web-acl \ --scope REGIONAL \ --id $WEB_ACL_ID \ --cli-input-json file://rate-limit-rule.json \ --region us-east-1

4.3 Associate WAF with Application Load Balancer

# Get ALB ARN (replace with your ALB ARN) ALB_ARN="arn:aws:elasticloadbalancing:us-east-1:ACCOUNT-ID:loadbalancer/app/production-alb/1234567890123456" # Associate Web ACL with ALB aws wafv2 associate-web-acl \ --web-acl-arn "arn:aws:wafv2:us-east-1:ACCOUNT-ID:regional/webacl/production-web-acl/$WEB_ACL_ID" \ --resource-arn $ALB_ARN \ --region us-east-1
Application Layer Protection Active: Your web applications are now protected against Layer 7 attacks, bot traffic, and known malicious IPs with automatic DDoS mitigation.
5
Enable AWS Shield DDoS Defense (4 minutes)

AWS Shield provides always-on DDoS protection. Shield Standard is automatic, while Shield Advanced provides enhanced protection with 24/7 expert support.

Shield Standard (Free):

Shield Standard is automatically enabled for all AWS customers and protects against common Layer 3 and 4 DDoS attacks.

Shield Advanced Configuration (Optional - $3,000/month):

5.1 Subscribe to Shield Advanced

# Subscribe to Shield Advanced (requires confirmation in console) aws shield subscribe-to-proactive-engagement \ --proactive-engagement-status ENABLED # Create emergency contact for DDoS Response Team aws shield put-proactive-engagement-details \ --proactive-engagement-status ENABLED \ --emergency-contact-list '[ {