- Knowledge Base
- Amazon Web Services
- Elastic Load Balancing
- ELB Insecure SSL Ciphers
Check the security policy configured for your Amazon Classic Load Balancers for any cipher suites that demonstrate vulnerabilities or have been rendered insecure by recent 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 resolution is part of the Conformity Security & Compliance tool for AWS.
Using insecure and deprecated ciphers for your Classic Load Balancer could make the SSL connection between the client and the load balancer vulnerable to exploits. If the SSL negotiation configuration defined for your load balancer use outdated cipher suites, a security policy update is strongly recommended.
Audit
To determine if the security policy associated with your Classic Load Balancer is using insecure ciphers, perform the following actions:
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 security policy type used:
- If the Predefined Security Policy option is selected, check the SSL Ciphers section for active (i.e. selected) cipher definitions. Compare the selected ciphers with the ones listed on this page in order to identify if one or more ciphers used by your security policy are insecure. The ciphers without an asterisk, available in the SSL ciphers list, are not secure and should be used at your own risk. If one or more insecure and/or deprecated ciphers are enabled within the predefined security policy associated with your Amazon Classic Load Balancer, follow the steps outlined in the Remediation section to disable them.
- If the Custom Security Policy option is selected, check the SSL Ciphers section for active cipher definitions. Compare the selected ciphers with the ones listed on this page in order to identify if one or more ciphers used by your security policy are insecure. The ciphers without an asterisk, available in the SSL ciphers list, are not secure. If one or more insecure ciphers are enabled for the custom security policy associated with your Classic Load Balancer, follow the steps outlined in the Remediation section to disable them.
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-1234567890120" ]
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 describe the protocols and ciphers configured for 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-1234567890120" --output table --query 'PolicyDescriptions[*].PolicyAttributeDescriptions'
06 The command output should return a table with the requested protocols and ciphers:
---------------------------------------------------------------- | DescribeLoadBalancerPolicies | +--------------------------------+-----------------------------+ | AttributeName | AttributeValue | +--------------------------------+-----------------------------+ | Reference-Security-Policy | ELBSecurityPolicy-2015-05 | | Protocol-TLSv1 | true | | Protocol-SSLv3 | true | | Protocol-TLSv1.1 | false | | Protocol-TLSv1.2 | false | | Server-Defined-Cipher-Order | true | | AES128-GCM-SHA256 | true | | AES128-SHA256 | true | | AES128-SHA | true | | AES256-GCM-SHA384 | true | | AES256-SHA256 | true | | AES256-SHA | true | | DHE-DSS-AES128-SHA | false | | CAMELLIA128-SHA | false | | EDH-RSA-DES-CBC3-SHA | false | | DES-CBC3-SHA | true | | ECDHE-RSA-RC4-SHA | true | | RC4-SHA | true | | ECDHE-ECDSA-RC4-SHA | true | | DHE-DSS-AES256-GCM-SHA384 | true | | DHE-RSA-AES256-GCM-SHA384 | true | | DHE-RSA-AES256-SHA256 | true | | DHE-DSS-AES256-SHA256 | true | | DHE-RSA-AES256-SHA | false | | DHE-DSS-AES256-SHA | true | | DHE-RSA-CAMELLIA256-SHA | true | | DHE-DSS-CAMELLIA256-SHA | true | | PSK-AES256-CBC-SHA | true | | PSK-3DES-EDE-CBC-SHA | false | | KRB5-DES-CBC3-SHA | false | | KRB5-DES-CBC3-MD5 | false | | PSK-AES128-CBC-SHA | false | | PSK-RC4-SHA | false | | KRB5-RC4-SHA | false | | KRB5-RC4-MD5 | true | | KRB5-DES-CBC-SHA | true | | KRB5-DES-CBC-MD5 | true | | EXP-EDH-RSA-DES-CBC-SHA | true | | EXP-EDH-DSS-DES-CBC-SHA | true | | EXP-RC2-CBC-MD5 | true | | EXP-KRB5-RC2-CBC-SHA | false | | EXP-KRB5-DES-CBC-SHA | false | | EXP-KRB5-RC2-CBC-MD5 | false | | EXP-KRB5-DES-CBC-MD5 | false | +--------------------------------+-----------------------------+
The cipher definitions with the AttributeValue set to true are enabled for your security policy. Compare the ciphers list returned by the describe-load-balancer-policies command output with the SSL ciphers list available on this page in order to identify if one or more ciphers used by your security policy are insecure. The ciphers without an asterisk, available in the SSL ciphers list, are not secure and should be used at your own risk. If one or more insecure and/or deprecated ciphers are enabled within the security policy associated with your Amazon Classic Load Balancer, follow the steps outlined in the Remediation section to disable them.
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 deprecated cipher definitions from your load balancer SSL negotiation settings, you need to perform the following actions:
For predefined security policies:Using AWS CloudFormation
01 CloudFormation template (JSON):
{
"AWSTemplateFormatVersion": "2010-09-09",
"Description": "Use Secure Ciphers 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-predefined-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-predefined-negotiation-policy",
"PolicyType": "SSLNegotiationPolicyType",
"Attributes": [{
"Name": "Reference-Security-Policy",
"Value": "ELBSecurityPolicy-TLS-1-2-2017-01"
}]
}]
}
}
}
}
02 CloudFormation template (YAML):
AWSTemplateFormatVersion: '2010-09-09' Description: Use Secure Ciphers 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-predefined-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-predefined-negotiation-policy PolicyType: SSLNegotiationPolicyType Attributes: - Name: Reference-Security-Policy Value: ELBSecurityPolicy-TLS-1-2-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-predefined-negotiation-policy"
policy_type_name = "SSLNegotiationPolicyType"
policy_attribute {
# Use Secure Ciphers for Load Balancer HTTPS Listener Policy
name = "Reference-Security-Policy"
value = "ELBSecurityPolicy-TLS-1-2-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 Ciphers 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": "AES128-SHA256",
"Value": true
}
,
{
"Name": "Server-Defined-Cipher-Order",
"Value": true
}
]
}]
}
}
}
}
02 CloudFormation template (YAML):
AWSTemplateFormatVersion: '2010-09-09'
Description: Use Secure Ciphers 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: AES128-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 Ciphers 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 = "AES128-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. These predefined policies contain secure cipher definitions. Choose Save to apply the configuration changes.
- If the Custom Security Policy option is selected, deselect all the insecure and deprecated cipher definitions enabled in the SSL Ciphers section. Check the SSL ciphers list available on this page to identify the insecure and deprecated ciphers. Choose Save to apply the 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-2-2017-01, which contains only secure cipher definitions (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-2-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-2-2017-01, which contains only secure cipher definitions (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 cipher definitions such as ECDHE-ECDSA-AES128-GCM-SHA256 and AES128-SHA256 (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=AES128-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 cipher definitions such as ECDHE-ECDSA-AES128-GCM-SHA256 and AES128-SHA256 (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:
- 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