Distributed Denial of Service (DDoS) attacks remain one of the most persistent threats to cloud-hosted applications. Amazon EC2 instances are particularly vulnerable when not properly configured, as attackers exploit:
- Open ports in security groups
- Unrestricted API access
- Resource-intensive application endpoints
Before diving into custom solutions, ensure you've configured these AWS-native protections:
# AWS CLI command to enable Shield Advanced (for accounts with Business/Enterprise support)
aws shield create-protection --name "Production-EC2" \
--resource-arn arn:aws:ec2:us-east-1:123456789012:instance/i-0abcdef1234567890
Implementing rate limiting at the OS level provides crucial protection before traffic reaches your application:
# Basic iptables rules for SYN flood protection
iptables -N SYN_FLOOD
iptables -A SYN_FLOOD -p tcp --syn -m limit --limit 10/s --limit-burst 25 -j RETURN
iptables -A SYN_FLOOD -j DROP
iptables -A INPUT -p tcp --syn -j SYN_FLOOD
# HTTP request rate limiting per IP
iptables -A INPUT -p tcp --dport 80 -m recent --name HTTP --set
iptables -A INPUT -p tcp --dport 80 -m recent --name HTTP --update --seconds 60 --hitcount 100 -j DROP
AWS Web Application Firewall offers robust rule sets to filter malicious traffic:
# CloudFormation snippet for WAF rate-based rule
Resources:
RateBasedRule:
Type: AWS::WAF::RateBasedRule
Properties:
Name: EC2RateLimitRule
MetricName: EC2RateLimitRule
RateKey: IP
RateLimit: 2000
MatchPredicates:
- FieldToMatch:
Type: URI
TextTransformation: NONE
Type: REGULAR
Configure your Auto Scaling group to handle traffic spikes:
# Terraform configuration for DDoS-resilient auto-scaling
resource "aws_autoscaling_policy" "ddos_scale_out" {
name = "ddos_scale_out"
scaling_adjustment = 2
adjustment_type = "ChangeInCapacity"
cooldown = 300
autoscaling_group_name = aws_autoscaling_group.web.name
}
resource "aws_cloudwatch_metric_alarm" "high_cpu" {
alarm_name = "ddos_cpu_spike"
comparison_operator = "GreaterThanThreshold"
evaluation_periods = "2"
metric_name = "CPUUtilization"
namespace = "AWS/EC2"
period = "60"
statistic = "Average"
threshold = "70"
alarm_actions = [aws_autoscaling_policy.ddos_scale_out.arn]
}
Create a comprehensive monitoring system that automatically responds to anomalies:
# Python Lambda function for DDoS detection
import boto3
from datetime import datetime, timedelta
def lambda_handler(event, context):
cloudwatch = boto3.client('cloudwatch')
# Check NetworkIn metric
response = cloudwatch.get_metric_statistics(
Namespace='AWS/EC2',
MetricName='NetworkIn',
Dimensions=[{'Name':'InstanceId', 'Value':'i-0abcdef1234567890'}],
StartTime=datetime.utcnow() - timedelta(minutes=5),
EndTime=datetime.utcnow(),
Period=60,
Statistics=['Sum']
)
# If traffic exceeds 100MB in 5 minutes, trigger mitigation
if response['Datapoints'] and max(d['Sum'] for d in response['Datapoints']) > 100000000:
ec2 = boto3.client('ec2')
ec2.create_network_acl_entry(
NetworkAclId='acl-12345678',
RuleNumber=100,
Protocol='-1',
RuleAction='deny',
Egress=False,
CidrBlock='0.0.0.0/0'
)
return {"action": "network_acl_updated"}
return {"action": "no_action"}
MySQL-specific optimizations to prevent connection exhaustion:
# MySQL configuration additions in my.cnf
[mysqld]
max_connections = 500
wait_timeout = 60
interactive_timeout = 60
skip_name_resolve = ON
max_connect_errors = 100
When your EC2 instance faces periodic DDoS attacks, the first step is identifying vulnerable entry points. Common attack vectors include:
- HTTP/HTTPS flood attacks targeting port 80/443
- TCP SYN floods overwhelming connection tables
- UDP amplification attacks exploiting DNS/NTP services
Beyond basic security groups, implement these AWS-native defenses:
# AWS CLI command to enable Shield Advanced (note: requires business support plan)
aws shield create-protection --name "EC2-DDoS-Protection" \
--resource-arn arn:aws:ec2:us-east-1:123456789012:instance/i-0abcdef1234567890
Configure iptables rules to throttle connections:
# Install required modules
sudo apt-get install iptables-persistent
# Basic rate limiting (adjust thresholds as needed)
sudo iptables -A INPUT -p tcp --dport 80 -m connlimit --connlimit-above 50 -j REJECT
sudo iptables -A INPUT -p tcp --dport 80 -m limit --limit 50/minute --limit-burst 100 -j ACCEPT
# Save rules permanently
sudo netfilter-persistent save
For web servers, implement these NGINX configurations:
# In nginx.conf
http {
limit_req_zone $binary_remote_addr zone=ddos:10m rate=30r/s;
server {
location / {
limit_req zone=ddos burst=50 nodelay;
# Additional proxy settings...
}
}
}
Create CloudWatch alarms that trigger scaling policies during traffic spikes:
# Terraform example for auto-scaling configuration
resource "aws_autoscaling_policy" "ddos_scale_out" {
name = "ddos_scale_out"
scaling_adjustment = 2
adjustment_type = "ChangeInCapacity"
cooldown = 300
autoscaling_group_name = aws_autoscaling_group.web.name
}
resource "aws_cloudwatch_metric_alarm" "high_cpu" {
alarm_name = "ddos_cpu_spike"
comparison_operator = "GreaterThanThreshold"
evaluation_periods = "2"
metric_name = "CPUUtilization"
namespace = "AWS/EC2"
period = "60"
statistic = "Average"
threshold = "85"
alarm_actions = [aws_autoscaling_policy.ddos_scale_out.arn]
}
Combine these tools for comprehensive visibility:
- CloudWatch anomaly detection for traffic patterns
- VPC Flow Logs analysis with Athena
- Custom metrics via the AWS CLI:
aws cloudwatch put-metric-alarm \
--alarm-name "HighNetworkIn" \
--metric-name NetworkIn \
--namespace AWS/EC2 \
--statistic Average \
--period 60 \
--threshold 10000000 \
--comparison-operator GreaterThanThreshold \
--dimensions Name=InstanceId,Value=i-1234567890abcdef0 \
--evaluation-periods 2 \
--alarm-actions arn:aws:sns:us-east-1:123456789012:ddos-alerts
For MySQL instances vulnerable to connection exhaustion:
# In my.cnf
[mysqld]
max_connections = 500
wait_timeout = 30
interactive_timeout = 30
connection_cache = sequential
# Install and configure mysqlnd plugin
INSTALL PLUGIN mysqlnd_qc SONAME 'mysqlnd_qc.so'
SET GLOBAL query_cache_type = 1;