Use the Conformity Knowledge Base AI to help improve your Cloud Posture

ELB Insecure SSL Ciphers

Trend Cloud One™ – Conformity is a continuous assurance tool that provides peace of mind for your cloud infrastructure, delivering over 1000 automated best practice checks.

Risk Level: Medium (should be achieved)
Rule ID: ELB-006

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.

Security

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:

  1. 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.
  2. 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:

  1. 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.
  2. 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:

  1. 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
      
  2. 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
      

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

Publication date Oct 13, 2016