- Knowledge Base
- Amazon Web Services
- Elastic Load Balancing
- ELB Insecure SSL Protocols
Check the security policy configured for your Amazon Classic Load Balancers for the SSLv2 and SSLv3 protocols. These SSL protocols demonstrate vulnerabilities or have been rendered insecure by exploits.
This rule can help you with the following compliance standards:
- PCI
- HIPAA
- APRA
- MAS
- NIST4
For further details on compliance standards supported by Conformity, see here.
This rule can help you work with the AWS Well-Architected Framework.
This rule resolution is part of the Conformity Security & Compliance tool for AWS.
Using insecure and deprecated protocols for your Classic Load Balancer could make the connection between the clients and the load balancer vulnerable to exploits such as DROWN (Decrypting RSA using Obsolete and Weakened eNcryption), which targets a specific weakness in the OpenSSL implementation of SSLv2 protocol, and POODLE (Padding Oracle On Downgraded Legacy Encryption), which allows an attacker to read information encrypted with SSLv3 protocol in plain text, using a Man-In-The-Middle (MITM) attack. If the SSL negotiation configuration defined for your load balancer is using Protocol-SSLv2 and/or Protocol-SSLv3, a security policy update is strongly recommended.
Audit
To determine if the security policy associated with your Classic Load Balancer is using insecure SSL protocols, perform the following operations:
Using AWS Console
01 Sign in to the AWS Management Console.
02 Navigate to Amazon EC2 console at https://console.aws.amazon.com/ec2/v2/.
03 In the main navigation panel, under Load Balancing, choose Load Balancers.
04 Click inside the Filter by tags and attributes or search by keyword box, select Type and choose classic to list the Classic Load Balancers available in the current AWS region.
05 Select the Amazon Classic Load Balancer that you want to examine.
06 Select the Listeners tab from the console bottom panel to access the listener configuration available for the selected load balancer.
07 In the Cipher column of the HTTPS listener, choose Change.
08 In the Select a Cipher configuration box, perform one of the following set of actions depending on the policy type used:
- If the Predefined Security Policy option is selected, check the SSL Protocols section available for the selected policy for active Protocol-SSLv2 and/or Protocol-SSLv3 definitions. If the Protocol-SSLv2 and/or Protocol-SSLv3 protocols are selected (i.e. active), the predefined security policy associated with your Amazon Classic Load Balancer is using outdated and insecure protocols.
- If the Custom Security Policy option is selected, check the SSL Protocols section for active Protocol-SSLv2 and/or Protocol-SSLv3 definitions. If the Protocol-SSLv2 and/or Protocol-SSLv3 protocols are selected, the custom security policy associated with your Amazon Classic Load Balancer is using outdated and insecure protocols.
09 Repeat steps no. 5 – 8 for each Classic Load Balancer provisioned within the current AWS region.
10 Change the AWS cloud region from the console navigation bar and repeat the Audit process for other regions.
Using AWS CLI
01 Run describe-load-balancers command (OSX/Linux/UNIX) with custom query filters to list the name of each Classic Load Balancer available in the selected AWS region:
aws elb describe-load-balancers --region us-east-1 --query 'LoadBalancerDescriptions[*].LoadBalancerName'
02 The command output should return an array with the requested load balancer name(s):
[ "cc-frontend-load-balancer", "cc-project5-load-balancer" ]
03 Run describe-load-balancer-policies command (OSX/Linux/UNIX) using the name of the load balancer that you want to examine as the identifier parameter and custom query filters to describe the name of the security policy associated with the selected load balancer:
aws elb describe-load-balancer-policies --region us-east-1 --load-balancer-name cc-frontend-load-balancer --query 'PolicyDescriptions[*].PolicyName'
04 The command output should return the name of the associated security policy:
[ "AWSConsole-SSLNegotiationPolicy-cc-frontend-load-balancer-1654704251533" ]
05 Run describe-load-balancer-policies command (OSX/Linux/UNIX) using the name of the security policy returned at the previous step as the identifier parameter and custom query filters to determine if the Protocol-SSLv2 and/or Protocol-SSLv3 protocols are being used by the selected security policy:
aws elb describe-load-balancer-policies --region us-east-1 --load-balancer-name cc-frontend-load-balancer --policy-name "AWSConsole-SSLNegotiationPolicy-cc-frontend-load-balancer-1654704251533" --query 'PolicyDescriptions[*].PolicyAttributeDescriptions[?(AttributeName == `Protocol-SSLv2` || AttributeName == `Protocol-SSLv3`)].{"AttributeName": AttributeName, "AttributeValue": AttributeValue} | []'
06 The command output should return the configuration status of the specified protocols:
[ { "AttributeName": "Protocol-SSLv2", "AttributeValue": "true" }, { "AttributeName": "Protocol-SSLv3", "AttributeValue": "true" } ]
If the "Protocol-SSLv2" and/or "Protocol-SSLv3" protocols are enabled, i.e. "AttributeValue" is set to "true", as shown in the output example above, the security policy associated with your Amazon Classic Load Balancer is using outdated and insecure protocols.
07 Repeat steps no. 3 – 6 for each Classic Load Balancer provisioned in the selected AWS region.
08 Change the AWS cloud region by updating the --region command parameter value and repeat the Audit process for other regions.
Remediation / Resolution
To remove any insecure and outdated protocol definitions from your load balancer SSL negotiation settings, you need to perform the following operations:
For predefined security policies:Using AWS CloudFormation
01 CloudFormation template (JSON):
{
"AWSTemplateFormatVersion": "2010-09-09",
"Description": "Use Secure Protocols for Load Balancer HTTPS Listener Policy",
"Resources": {
"ClassicLoadBalancer": {
"Type" : "AWS::ElasticLoadBalancing::LoadBalancer",
"Properties" : {
"LoadBalancerName" : "cc-frontend-load-balancer",
"Scheme" : "internet-facing",
"SecurityGroups" : [ "sg-0abcdabcdabcdabcd" ],
"Subnets" : [ "subnet-0abcd1234abcd1234", "subnet-0abcdabcdabcdabcd", "subnet-01234abcd1234abcd", "subnet-01234123412341234" ],
"Instances" : [ "i-0abcd1234abcd1234", "i-0abcdabcdabcdabcd" ],
"Listeners": [{
"InstancePort": "80",
"InstanceProtocol": "HTTP",
"LoadBalancerPort": "443",
"Protocol": "HTTPS",
"PolicyNames": [ "cc-secure-negotiation-policy" ],
"SSLCertificateId": "arn:aws:acm:us-east-1:123456789012:certificate/abcd1234-abcd-1234-abcd-1234abcd1234"
}],
"HealthCheck": {
"Target": "HTTP:80/index.html",
"HealthyThreshold": "10",
"UnhealthyThreshold": "2",
"Interval": "50",
"Timeout": "5"
},
"Policies": [{
"PolicyName": "cc-secure-negotiation-policy",
"PolicyType": "SSLNegotiationPolicyType",
"Attributes": [{
"Name": "Reference-Security-Policy",
"Value": "ELBSecurityPolicy-TLS-1-1-2017-01"
}]
}]
}
}
}
}
02 CloudFormation template (YAML):
AWSTemplateFormatVersion: '2010-09-09'
Description: Use Secure Protocols for Load Balancer HTTPS Listener Policy
Resources:
ClassicLoadBalancer:
Type: AWS::ElasticLoadBalancing::LoadBalancer
Properties:
LoadBalancerName: cc-frontend-load-balancer
Scheme: internet-facing
SecurityGroups:
- sg-0abcdabcdabcdabcd
Subnets:
- subnet-0abcd1234abcd1234
- subnet-0abcdabcdabcdabcd
- subnet-01234abcd1234abcd
- subnet-01234123412341234
Instances:
- i-0abcd1234abcd1234
- i-0abcdabcdabcdabcd
Listeners:
- InstancePort: '80'
InstanceProtocol: HTTP
LoadBalancerPort: '443'
Protocol: HTTPS
PolicyNames:
- cc-secure-negotiation-policy
SSLCertificateId: arn:aws:acm:us-east-1:123456789012:certificate/abcd1234-abcd-1234-abcd-1234abcd1234
HealthCheck:
Target: HTTP:80/index.html
HealthyThreshold: '10'
UnhealthyThreshold: '2'
Interval: '50'
Timeout: '5'
Policies:
- PolicyName: cc-secure-negotiation-policy
PolicyType: SSLNegotiationPolicyType
Attributes:
- Name: Reference-Security-Policy
Value: ELBSecurityPolicy-TLS-1-1-2017-01
Using Terraform (AWS Provider)
01 Terraform configuration file (.tf):
terraform {
required_providers {
aws = {
source = "hashicorp/aws"
version = "~> 4.0"
}
}
required_version = ">= 0.14.9"
}
provider "aws" {
region = "us-east-1"
}
resource "aws_elb" "classic-load-balancer" {
name = "cc-frontend-load-balancer"
internal = false
security_groups = ["sg-0abcdabcdabcdabcd"]
subnets = ["subnet-0abcd1234abcd1234", "subnet-0abcdabcdabcdabcd", "subnet-01234abcd1234abcd", "subnet-01234123412341234"]
instances = ["i-0abcd1234abcd1234", "i-0abcdabcdabcdabcd"]
health_check {
healthy_threshold = 10
unhealthy_threshold = 2
timeout = 5
target = "HTTP:80/index.html"
interval = 50
}
listener {
instance_port = 80
instance_protocol = "http"
lb_port = 443
lb_protocol = "https"
ssl_certificate_id = "arn:aws:acm:us-east-1:123456789012:certificate/abcd1234-abcd-1234-abcd-1234abcd1234"
}
}
resource "aws_load_balancer_policy" "cc-ssl-negotiation-policy" {
load_balancer_name = aws_elb.classic-load-balancer.name
policy_name = "cc-secure-negotiation-policy"
policy_type_name = "SSLNegotiationPolicyType"
policy_attribute {
# Use Secure Protocols for Load Balancer HTTPS Listener Policy
name = "Reference-Security-Policy"
value = "ELBSecurityPolicy-TLS-1-1-2017-01"
}
}
resource "aws_load_balancer_listener_policy" "cc-https-listener-policy" {
load_balancer_name = aws_elb.classic-load-balancer.name
load_balancer_port = 443
policy_names = [
aws_load_balancer_policy.cc-ssl-negotiation-policy.policy_name
]
}
For custom security policies:
Using AWS CloudFormation
01 CloudFormation template (JSON):
{
"AWSTemplateFormatVersion": "2010-09-09",
"Description": "Use Secure Protocols for Load Balancer HTTPS Listener Policy",
"Resources": {
"ClassicLoadBalancer": {
"Type" : "AWS::ElasticLoadBalancing::LoadBalancer",
"Properties" : {
"LoadBalancerName" : "cc-frontend-load-balancer",
"Scheme" : "internet-facing",
"SecurityGroups" : [ "sg-0abcdabcdabcdabcd" ],
"Subnets" : [ "subnet-0abcd1234abcd1234", "subnet-0abcdabcdabcdabcd", "subnet-01234abcd1234abcd", "subnet-01234123412341234" ],
"Instances" : [ "i-0abcd1234abcd1234", "i-0abcdabcdabcdabcd" ],
"Listeners": [{
"InstancePort": "80",
"InstanceProtocol": "HTTP",
"LoadBalancerPort": "443",
"Protocol": "HTTPS",
"PolicyNames": [ "cc-custom-negotiation-policy" ],
"SSLCertificateId": "arn:aws:acm:us-east-1:123456789012:certificate/abcd1234-abcd-1234-abcd-1234abcd1234"
}],
"HealthCheck": {
"Target": "HTTP:80/index.html",
"HealthyThreshold": "10",
"UnhealthyThreshold": "2",
"Interval": "50",
"Timeout": "5"
},
"Policies": [{
"PolicyName": "cc-custom-negotiation-policy",
"PolicyType": "SSLNegotiationPolicyType",
"Attributes": [
{
"Name": "Protocol-TLSv1.1",
"Value": true
},
{
"Name": "Protocol-TLSv1.2",
"Value": true
},
{
"Name": "ECDHE-ECDSA-AES128-GCM-SHA256",
"Value": true
},
{
"Name": "Server-Defined-Cipher-Order",
"Value": true
}
]
}]
}
}
}
}
02 CloudFormation template (YAML):
AWSTemplateFormatVersion: '2010-09-09'
Description: Use Secure Protocols for Load Balancer HTTPS Listener Policy
Resources:
ClassicLoadBalancer:
Type: AWS::ElasticLoadBalancing::LoadBalancer
Properties:
LoadBalancerName: cc-frontend-load-balancer
Scheme: internet-facing
SecurityGroups:
- sg-0abcdabcdabcdabcd
Subnets:
- subnet-0abcd1234abcd1234
- subnet-0abcdabcdabcdabcd
- subnet-01234abcd1234abcd
- subnet-01234123412341234
Instances:
- i-0abcd1234abcd1234
- i-0abcdabcdabcdabcd
Listeners:
- InstancePort: '80'
InstanceProtocol: HTTP
LoadBalancerPort: '443'
Protocol: HTTPS
PolicyNames:
- cc-custom-negotiation-policy
SSLCertificateId: arn:aws:acm:us-east-1:123456789012:certificate/abcd1234-abcd-1234-abcd-1234abcd1234
HealthCheck:
Target: HTTP:80/index.html
HealthyThreshold: '10'
UnhealthyThreshold: '2'
Interval: '50'
Timeout: '5'
Policies:
- PolicyName: cc-custom-negotiation-policy
PolicyType: SSLNegotiationPolicyType
Attributes:
- Name: Protocol-TLSv1.1
Value: true
- Name: Protocol-TLSv1.2
Value: true
- Name: ECDHE-ECDSA-AES128-GCM-SHA256
Value: true
- Name: Server-Defined-Cipher-Order
Value: true
Using Terraform (AWS Provider)
01 Terraform configuration file (.tf):
terraform {
required_providers {
aws = {
source = "hashicorp/aws"
version = "~> 4.0"
}
}
required_version = ">= 0.14.9"
}
provider "aws" {
region = "us-east-1"
}
resource "aws_elb" "classic-load-balancer" {
name = "cc-frontend-load-balancer"
internal = false
security_groups = ["sg-0abcdabcdabcdabcd"]
subnets = ["subnet-0abcd1234abcd1234", "subnet-0abcdabcdabcdabcd", "subnet-01234abcd1234abcd", "subnet-01234123412341234"]
instances = ["i-0abcd1234abcd1234", "i-0abcdabcdabcdabcd"]
health_check {
healthy_threshold = 10
unhealthy_threshold = 2
timeout = 5
target = "HTTP:80/index.html"
interval = 50
}
listener {
instance_port = 80
instance_protocol = "http"
lb_port = 443
lb_protocol = "https"
ssl_certificate_id = "arn:aws:acm:us-east-1:123456789012:certificate/abcd1234-abcd-1234-abcd-1234abcd1234"
}
}
resource "aws_load_balancer_policy" "cc-ssl-negotiation-policy" {
load_balancer_name = aws_elb.classic-load-balancer.name
policy_name = "cc-custom-negotiation-policy"
policy_type_name = "SSLNegotiationPolicyType"
# Use Secure Protocols for Load Balancer HTTPS Listener Policy
policy_attribute {
name = "Protocol-TLSv1.1"
value = "true"
}
policy_attribute {
name = "Protocol-TLSv1.2"
value = "true"
}
policy_attribute {
name = "ECDHE-ECDSA-AES128-GCM-SHA256"
value = "true"
}
policy_attribute {
name = "Server-Defined-Cipher-Order"
value = "true"
}
}
resource "aws_load_balancer_listener_policy" "cc-https-listener-policy" {
load_balancer_name = aws_elb.classic-load-balancer.name
load_balancer_port = 443
policy_names = [
aws_load_balancer_policy.cc-ssl-negotiation-policy.policy_name
]
}
Using AWS Console
01 Sign in to the AWS Management Console.
02 Navigate to Amazon EC2 console at https://console.aws.amazon.com/ec2/v2/.
03 In the main navigation panel, under Load Balancing, choose Load Balancers.
04 Click inside the Filter by tags and attributes or search by keyword box, select Type and choose classic to list the Classic Load Balancers available in the current AWS region.
05 Select the Amazon Classic Load Balancer that you want to reconfigure.
06 Select the Listeners tab from the console bottom panel and in the Cipher column of the HTTPS listener, choose Change.
07 In the Select a Cipher configuration box, perform one of the following set of actions depending on the policy type used:
- If the Predefined Security Policy option is selected, choose one of the following predefined policies from the policy dropdown list: ELBSecurityPolicy-2016-08, ELBSecurityPolicy-TLS-1-1-2017-01, or ELBSecurityPolicy-TLS-1-2-2017-01, depending on your use case. Choose Save to apply the changes.
- If the Custom Security Policy option is selected, deselect the Protocol-SSLv2 and Protocol-SSLv3 definitions from the SSL Protocols section. Choose Save to apply the configuration changes.
08 Repeat steps no. 5 – 7 for each Classic Load Balancer provisioned within the current AWS region.
09 Change the AWS cloud region from the console navigation bar and repeat the Audit process for other regions.
Using AWS CLI
01 Perform one of the following set of commands depending on the policy type used:
- For predefined security policies:
- Run create-load-balancer-policy command (OSX/Linux/UNIX) using the name of the Classic Load Balancer that you want to reconfigure as the identifier parameter, to create a new policy for the selected load balancer listener. The new policy is configured with one of the latest predefined security policies, named ELBSecurityPolicy-TLS-1-1-2017-01, which enables the Protocol-TLSv1.1 and Protocol-TLSv1.2 secure protocols (the command does not produce an output):
aws elb create-load-balancer-policy --load-balancer-name cc-frontend-load-balancer --policy-name cc-predefined-negotiation-policy --policy-type-name SSLNegotiationPolicyType --policy-attributes AttributeName=Reference-Security-Policy,AttributeValue=ELBSecurityPolicy-TLS-1-1-2017-01
- Run set-load-balancer-policies-of-listener command (OSX/Linux/UNIX) to associate the new policy created at the previous step with the HTTPS listener of the load balancer that you want to reconfigure (the command does not produce an output):
aws elb set-load-balancer-policies-of-listener --region us-east-1 --load-balancer-name cc-frontend-load-balancer --load-balancer-port 443 --policy-names cc-predefined-negotiation-policy
- Run create-load-balancer-policy command (OSX/Linux/UNIX) using the name of the Classic Load Balancer that you want to reconfigure as the identifier parameter, to create a new policy for the selected load balancer listener. The new policy is configured with one of the latest predefined security policies, named ELBSecurityPolicy-TLS-1-1-2017-01, which enables the Protocol-TLSv1.1 and Protocol-TLSv1.2 secure protocols (the command does not produce an output):
- For custom security policies:
- Run create-load-balancer-policy command (OSX/Linux/UNIX) using the name of the Classic Load Balancer that you want to reconfigure as the identifier parameter, to create a new custom policy for the selected load balancer listener. The custom policy enables secure TLS protocols such as Protocol-TLSv1.1 and Protocol-TLSv1.2, and secure SSL ciphers (the command does not produce an output):
aws elb create-load-balancer-policy --load-balancer-name cc-frontend-load-balancer --policy-name cc-custom-negotiation-policy --policy-type-name SSLNegotiationPolicyType --policy-attributes AttributeName=Protocol-TLSv1.1,AttributeValue=true AttributeName=Protocol-TLSv1.2,AttributeValue=true AttributeName=ECDHE-ECDSA-AES128-GCM-SHA256,AttributeValue=true AttributeName=Server-Defined-Cipher-Order,AttributeValue=true
- Run set-load-balancer-policies-of-listener command (OSX/Linux/UNIX) to associate the new policy created at the previous step with the HTTPS listener of the load balancer that you want to reconfigure (the command does not produce an output):
aws elb set-load-balancer-policies-of-listener --region us-east-1 --load-balancer-name cc-frontend-load-balancer --load-balancer-port 443 --policy-names cc-custom-negotiation-policy
- Run create-load-balancer-policy command (OSX/Linux/UNIX) using the name of the Classic Load Balancer that you want to reconfigure as the identifier parameter, to create a new custom policy for the selected load balancer listener. The custom policy enables secure TLS protocols such as Protocol-TLSv1.1 and Protocol-TLSv1.2, and secure SSL ciphers (the command does not produce an output):
02 Repeat step no. 1 for each Classic Load Balancer that you want to reconfigure, available in the selected AWS region.
03 Change the AWS cloud region by updating the --region command parameter value and repeat the Remediation process for other regions.
References
- AWS Documentation
- What is Elastic Load Balancing?
- SSL Negotiation Configurations for Elastic Load Balancing
- Predefined SSL Security Policies for Elastic Load Balancing
- SSL Security Policies for Elastic Load Balancing
- Update the SSL Negotiation Configuration of Your Load Balancer
- AWS Command Line Interface (CLI) Documentation:
- elb
- describe-load-balancers
- describe-load-balancer-policies
- describe-load-balancer-policy
- set-load-balancer-policies-of-listener
- CloudFormation Documentation
- AWS::ElasticLoadBalancing::LoadBalancer
- Terraform Documentation
- AWS Provider