← Back to Tutorials
Tutorial 10 Intermediate

How to Secure AWS Load Balancers in 25 Minutes

Load balancers are the front door to your applications. Learn how to protect them with modern TLS configuration, health check security, DDoS protection, and comprehensive monitoring.

25 min implementation
12 min read
Network Security

Why AWS Load Balancer Security is Critical

Load balancers are the front door to your high-traffic applications, handling millions of requests and distributing them across your infrastructure. This central position makes them both critical for performance and prime targets for attackers.

  • Exposed load balancer endpoints without rate limiting can be overwhelmed by DDoS attacks
  • Weak SSL/TLS configurations enable man-in-the-middle attacks and data interception
  • Publicly accessible health check URLs reveal internal architecture
  • Missing access logs prevent detection of attacks and compliance violations
  • Overly permissive security groups expand your attack surface
  • Compromised load balancers can expose API keys, session tokens, and customer data
⚠️
Critical: High-traffic applications can lose tens of thousands of dollars per hour during outages caused by load balancer security failures. Beyond revenue loss, insecure load balancers can violate PCI DSS, HIPAA, and SOC 2 requirements.

The Five Most Dangerous Load Balancer Misconfigurations

1

Weak SSL/TLS Termination

Outdated TLS versions (1.0, 1.1) and weak cipher suites allow man-in-the-middle attacks, data interception, session hijacking, and compliance violations.

2

Exposed Health Check Endpoints

Publicly accessible health check URLs reveal internal architecture and can be used for reconnaissance or DDoS amplification attacks.

3

No Rate Limiting or DDoS Protection

Load balancers without rate limiting can be overwhelmed by traffic spikes or deliberate attacks, causing service unavailability and resource exhaustion.

4

Insecure Access Logging

Missing or insufficient access logs prevent detection of attacks, delay incident response, and create compliance failures.

5

Overly Permissive Security Groups

Security groups allowing 0.0.0.0/0 access on all ports expose load balancers to unnecessary attack vectors and lateral movement opportunities.

1

Secure SSL/TLS Termination Configuration

~8 minutes

Prerequisites

  • Existing Application Load Balancer (ALB) or Network Load Balancer (NLB)
  • Valid SSL certificate (ACM or imported)
  • AWS CLI configured with appropriate permissions

Console Steps

1.1 Configure Security Policy

  • Navigate to EC2 Console → Load Balancers
  • Select your load balancer
  • Go to the Listeners tab
  • Edit the HTTPS listener (port 443)

1.2 Update Security Policy

  • In the listener configuration, find Security policy
  • Change from default to ELBSecurityPolicy-TLS13-1-2-2021-06 for TLS 1.3 support
  • For post-quantum security, use ELBSecurityPolicy-TLS13-1-2-Res-PQ-2025-09
  • Click Save changes
AWS CLI - Update Security Policy
# Update security policy via AWS CLI
aws elbv2 modify-listener \
    --listener-arn arn:aws:elasticloadbalancing:REGION:ACCOUNT_ID:listener/app/my-load-balancer/50dc6c495c0c9188/0467ef3c8400ae65 \
    --ssl-policy ELBSecurityPolicy-TLS13-1-2-2021-06

# Verify the configuration
aws elbv2 describe-listeners \
    --listener-arns arn:aws:elasticloadbalancing:REGION:ACCOUNT_ID:listener/app/my-load-balancer/50dc6c495c0c9188/0467ef3c8400ae65 \
    --query 'Listeners[*].SslPolicy'

1.3 Force HTTPS Redirect

  • Create or edit HTTP listener (port 80)
  • Configure redirect action to HTTPS
  • Set redirect to port 443 with protocol HTTPS
AWS CLI - Create HTTP to HTTPS Redirect
# Create HTTP to HTTPS redirect rule
aws elbv2 create-listener \
    --load-balancer-arn arn:aws:elasticloadbalancing:REGION:ACCOUNT_ID:loadbalancer/app/my-load-balancer/50dc6c495c0c9188 \
    --protocol HTTP \
    --port 80 \
    --default-actions Type=redirect,RedirectConfig='{
        "Protocol": "HTTPS",
        "Port": "443",
        "StatusCode": "HTTP_301"
    }'
Security Enhancement: Your load balancer now enforces modern TLS 1.3 standards and redirects all traffic to HTTPS automatically.
💡
Performance Tip: Use ELBSecurityPolicy-TLS13-1-2-2021-06 for the best balance of security and compatibility. This policy supports TLS 1.3 with strong cipher suites while maintaining backward compatibility with TLS 1.2 clients.
2

Implement Health Check Security

~6 minutes

Health checks are essential for load balancer functionality but can expose sensitive information if not properly secured.

Console Steps

2.1 Secure Health Check Endpoint

  • Navigate to EC2 Console → Target Groups
  • Select your target group
  • Go to Health checks tab
  • Click Edit health check settings

2.2 Configure Secure Health Check Path

  • Change health check path from / to /health/lb or similar
  • Set protocol to HTTPS (if backend supports it)
  • Configure appropriate success codes (200,202)
  • Set reasonable timeout and interval values
AWS CLI - Update Health Check Configuration
# Update health check configuration
aws elbv2 modify-target-group \
    --target-group-arn arn:aws:elasticloadbalancing:REGION:ACCOUNT_ID:targetgroup/my-targets/73e2d6bc24d8a067 \
    --health-check-protocol HTTPS \
    --health-check-port 443 \
    --health-check-path "/health/lb" \
    --health-check-interval-seconds 30 \
    --health-check-timeout-seconds 10 \
    --healthy-threshold-count 2 \
    --unhealthy-threshold-count 3 \
    --matcher HttpCode=200,202

2.3 Restrict Health Check Access via Security Groups

  • Configure security groups to allow health checks only from load balancer subnets
  • Use NACLs to further restrict access if needed
  • Consider implementing IP allowlisting in application code
AWS CLI - Create Security Group for Health Checks
# Create security group for health check access
aws ec2 create-security-group \
    --group-name health-check-access \
    --description "Allow health checks from load balancer subnets" \
    --vpc-id vpc-12345678

# Add inbound rule for load balancer subnets only
aws ec2 authorize-security-group-ingress \
    --group-id sg-12345678 \
    --protocol tcp \
    --port 443 \
    --cidr 10.0.1.0/24  # Load balancer subnet CIDR

aws ec2 authorize-security-group-ingress \
    --group-id sg-12345678 \
    --protocol tcp \
    --port 443 \
    --cidr 10.0.2.0/24  # Additional LB subnet CIDR
⚠️
Important: Never expose detailed system information through health checks. Attackers can use this information to map your infrastructure and identify potential vulnerabilities.
Security Win: Your health checks now provide necessary functionality without exposing sensitive infrastructure details to potential attackers.
3

Configure DDoS Protection and Rate Limiting

~7 minutes

Protect your load balancer and applications from DDoS attacks and abuse through AWS WAF and proper rate limiting.

Console Steps

3.1 Configure AWS WAF for Application Layer Protection

  • Navigate to AWS WAF console
  • Click Create web ACL
  • Name: LoadBalancerProtection
  • Associate with your Application Load Balancer
AWS CLI - Create WAF Web ACL with Rate Limiting
# Create WAF Web ACL with rate limiting
aws wafv2 create-web-acl \
    --name LoadBalancerProtection \
    --scope REGIONAL \
    --default-action Allow={} \
    --visibility-config SampledRequestsEnabled=true,CloudWatchMetricsEnabled=true,MetricName=LoadBalancerProtection \
    --rules '[
        {
            "Name": "RateLimitRule",
            "Priority": 1,
            "Statement": {
                "RateBasedStatement": {
                    "Limit": 2000,
                    "AggregateKeyType": "IP"
                }
            },
            "Action": {
                "Block": {}
            },
            "VisibilityConfig": {
                "SampledRequestsEnabled": true,
                "CloudWatchMetricsEnabled": true,
                "MetricName": "RateLimitRule"
            }
        }
    ]'

3.2 Add Geographic Blocking and IP Reputation Rules

  • Add geographic blocking rules for high-risk regions (if applicable to your business)
  • Enable AWS Managed IP Reputation rules
  • Configure CloudWatch alarms for DDoS detection
AWS CLI - Add IP Reputation Managed Rule
# Add AWS Managed IP Reputation rule to existing Web ACL
# Note: Get your Web ACL ID and lock token first
aws wafv2 update-web-acl \
    --name LoadBalancerProtection \
    --scope REGIONAL \
    --id YOUR_WEB_ACL_ID \
    --lock-token YOUR_LOCK_TOKEN \
    --default-action Allow={} \
    --visibility-config SampledRequestsEnabled=true,CloudWatchMetricsEnabled=true,MetricName=LoadBalancerProtection \
    --rules '[
        {
            "Name": "AWSManagedIPReputation",
            "Priority": 2,
            "Statement": {
                "ManagedRuleGroupStatement": {
                    "VendorName": "AWS",
                    "Name": "AWSManagedRulesAmazonIpReputationList"
                }
            },
            "OverrideAction": {
                "None": {}
            },
            "VisibilityConfig": {
                "SampledRequestsEnabled": true,
                "CloudWatchMetricsEnabled": true,
                "MetricName": "IPReputationRule"
            }
        }
    ]'

3.3 Configure CloudWatch Alarms for DDoS Detection

  • Create alarms for high request rates
  • Monitor target response times
  • Set up SNS notifications for alerts
AWS CLI - Create CloudWatch Alarms
# Create CloudWatch alarm for high request rate
aws cloudwatch put-metric-alarm \
    --alarm-name "LoadBalancer-HighRequestRate" \
    --alarm-description "Alert on unusually high request rate" \
    --metric-name RequestCount \
    --namespace AWS/ApplicationELB \
    --statistic Sum \
    --period 300 \
    --threshold 10000 \
    --comparison-operator GreaterThanThreshold \
    --dimensions Name=LoadBalancer,Value=app/my-load-balancer/50dc6c495c0c9188 \
    --evaluation-periods 2 \
    --alarm-actions arn:aws:sns:REGION:ACCOUNT_ID:security-alerts

# Create alarm for target response time
aws cloudwatch put-metric-alarm \
    --alarm-name "LoadBalancer-HighLatency" \
    --alarm-description "Alert on high target response time" \
    --metric-name TargetResponseTime \
    --namespace AWS/ApplicationELB \
    --statistic Average \
    --period 300 \
    --threshold 2.0 \
    --comparison-operator GreaterThanThreshold \
    --dimensions Name=LoadBalancer,Value=app/my-load-balancer/50dc6c495c0c9188 \
    --evaluation-periods 3 \
    --alarm-actions arn:aws:sns:REGION:ACCOUNT_ID:security-alerts
💡
Cost Optimization: For smaller applications, start with AWS WAF rate limiting (~$1/month + $0.60 per million requests) before considering AWS Shield Advanced ($3,000/month). Shield Advanced is recommended for production environments requiring 24/7 DDoS Response Team support.
Protection Active: Your load balancer now has multi-layered DDoS protection with rate limiting and IP reputation filtering.
4

Secure Load Balancer Access and Monitoring

~4 minutes

Implement comprehensive logging and monitoring to detect and respond to security incidents quickly.

Console Steps

4.1 Enable Access Logging

  • Navigate to EC2 Console → Load Balancers
  • Select your load balancer
  • Go to Attributes tab
  • Edit Access logs settings
  • Enable and specify S3 bucket for log storage

4.2 Create S3 Bucket with Proper Policy

  • Create an S3 bucket in the same region as your load balancer
  • Apply the correct bucket policy to allow ELB log delivery
  • Enable server-side encryption (SSE-S3)
AWS CLI - Create S3 Bucket and Enable Access Logging
# Create S3 bucket for access logs
aws s3 mb s3://my-lb-access-logs-ACCOUNT_ID --region REGION

# Create bucket policy file (save as bucket-policy.json)
cat > bucket-policy.json << 'EOF'
{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Principal": {
                "Service": "logdelivery.elasticloadbalancing.amazonaws.com"
            },
            "Action": "s3:PutObject",
            "Resource": "arn:aws:s3:::my-lb-access-logs-ACCOUNT_ID/AWSLogs/ACCOUNT_ID/*"
        }
    ]
}
EOF

# Apply bucket policy
aws s3api put-bucket-policy \
    --bucket my-lb-access-logs-ACCOUNT_ID \
    --policy file://bucket-policy.json

# Enable access logging on load balancer
aws elbv2 modify-load-balancer-attributes \
    --load-balancer-arn arn:aws:elasticloadbalancing:REGION:ACCOUNT_ID:loadbalancer/app/my-load-balancer/50dc6c495c0c9188 \
    --attributes \
        Key=access_logs.s3.enabled,Value=true \
        Key=access_logs.s3.bucket,Value=my-lb-access-logs-ACCOUNT_ID

4.3 Set Up Security Group Change Monitoring

  • Create EventBridge rule for security group changes
  • Configure SNS notifications for security alerts
  • Monitor for unauthorized modifications
AWS CLI - Monitor Security Group Changes
# Create SNS topic for security alerts
aws sns create-topic --name LoadBalancerSecurityAlerts

# Subscribe email to security alerts
aws sns subscribe \
    --topic-arn arn:aws:sns:REGION:ACCOUNT_ID:LoadBalancerSecurityAlerts \
    --protocol email \
    --notification-endpoint security@yourcompany.com

# Create EventBridge rule for security group changes
aws events put-rule \
    --name SecurityGroupChanges \
    --event-pattern '{
        "source": ["aws.ec2"],
        "detail-type": ["AWS API Call via CloudTrail"],
        "detail": {
            "eventSource": ["ec2.amazonaws.com"],
            "eventName": [
                "AuthorizeSecurityGroupIngress",
                "AuthorizeSecurityGroupEgress",
                "RevokeSecurityGroupIngress",
                "RevokeSecurityGroupEgress"
            ]
        }
    }'

# Add SNS target to the rule
aws events put-targets \
    --rule SecurityGroupChanges \
    --targets Id=1,Arn=arn:aws:sns:REGION:ACCOUNT_ID:LoadBalancerSecurityAlerts
Monitoring Active: Your load balancer now has comprehensive logging and alerting to detect and respond to security incidents in real-time.

Validate Your Configuration

Complete these checks to ensure your load balancer is properly secured:

Security Validation Script

Run this script to validate your load balancer security configuration:

Bash Script
#!/bin/bash
# Load Balancer Security Validation Script

echo "Validating Load Balancer Security Configuration..."
echo "================================================="

LB_ARN="arn:aws:elasticloadbalancing:REGION:ACCOUNT_ID:loadbalancer/app/my-load-balancer/50dc6c495c0c9188"

# Check SSL/TLS configuration
echo ""
echo "Checking SSL/TLS configuration..."
LISTENERS=$(aws elbv2 describe-listeners --load-balancer-arn $LB_ARN \
    --query 'Listeners[?Protocol==`HTTPS`].SslPolicy' --output text)
if [[ "$LISTENERS" == *"TLS13"* ]]; then
    echo "✓ TLS 1.3 policy configured"
elif [[ "$LISTENERS" == *"TLS-1-2"* ]]; then
    echo "✓ TLS 1.2 policy configured (consider upgrading to TLS 1.3)"
else
    echo "✗ WARNING: Weak or missing TLS policy!"
fi

# Check for HTTP to HTTPS redirect
echo ""
echo "Checking HTTP to HTTPS redirect..."
REDIRECT=$(aws elbv2 describe-listeners --load-balancer-arn $LB_ARN \
    --query 'Listeners[?Protocol==`HTTP`].DefaultActions[0].Type' --output text)
if [[ "$REDIRECT" == "redirect" ]]; then
    echo "✓ HTTP to HTTPS redirect configured"
else
    echo "✗ WARNING: No HTTP to HTTPS redirect found!"
fi

# Check access logging
echo ""
echo "Checking access logging..."
ACCESS_LOGS=$(aws elbv2 describe-load-balancer-attributes --load-balancer-arn $LB_ARN \
    --query 'Attributes[?Key==`access_logs.s3.enabled`].Value' --output text)
if [[ "$ACCESS_LOGS" == "true" ]]; then
    echo "✓ Access logging enabled"
else
    echo "✗ WARNING: Access logging not enabled!"
fi

# Check WAF association
echo ""
echo "Checking WAF association..."
WAF_ASSOC=$(aws wafv2 get-web-acl-for-resource \
    --resource-arn $LB_ARN 2>/dev/null)
if [[ -n "$WAF_ASSOC" ]]; then
    echo "✓ WAF Web ACL associated"
else
    echo "! No WAF Web ACL associated with load balancer"
fi

# Check security groups
echo ""
echo "Checking security group configuration..."
SG_IDS=$(aws elbv2 describe-load-balancers --load-balancer-arns $LB_ARN \
    --query 'LoadBalancers[0].SecurityGroups' --output text)
for sg_id in $SG_IDS; do
    OPEN_RULES=$(aws ec2 describe-security-groups --group-ids $sg_id \
        --query 'SecurityGroups[0].IpPermissions[?IpRanges[?CidrIp==`0.0.0.0/0`]]' --output text)
    if [[ -n "$OPEN_RULES" ]]; then
        echo "! Security group $sg_id has rules open to 0.0.0.0/0"
    else
        echo "✓ Security group $sg_id properly restricted"
    fi
done

echo ""
echo "================================================="
echo "Load balancer security validation complete!"

Common Mistakes to Avoid

Using default security policies that allow weak TLS versions. Always specify modern security policies like ELBSecurityPolicy-TLS13-1-2-2021-06.

Exposing health check endpoints publicly. Restrict health checks to load balancer subnets and return minimal information.

Not implementing rate limiting at multiple layers. Use both WAF and application-level rate limiting for comprehensive protection.

Ignoring access logs. Regularly analyze logs for attack patterns and unusual traffic spikes.

Not testing failover scenarios. Regularly test how your security controls behave during traffic spikes and failover events.

Configuring overly permissive security groups. Only allow necessary traffic and regularly audit security group rules.

Want Automated Load Balancer Monitoring?

Manually checking load balancer configurations is time-consuming and error-prone. AWSight automatically monitors your AWS environment against 500+ security best practices daily—including all load balancer security configurations.

References