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

ELB Insecure SSL Protocols

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-005

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.

Security

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:

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

  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. Choose Save to apply the changes.
  2. 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:

  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-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
      
  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 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
      

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