Skip to main content

Secure Listeners Should Be In Web-tier ELBs

More Info:

Your web-tier Elastic Load Balancer (ELB) listeners should be using the HTTPS/SSL protocol to encrypt the communication between your application clients and the load balancer.

Risk Level

Medium

Address

Security

Compliance Standards

  • APRA CPS 234 (Australia)
  • AWS Well Architected Framework
  • BSI C5 (Germany)
  • Brazil LGPD
  • CCPA / CPRA (California)
  • CIS Critical Security Controls v8
  • CMMC 2.0
  • CSA Cloud Controls Matrix v4
  • DPDPA
  • Digital Operational Resilience Act (EU)
  • GDPR
  • HIPAA
  • ISO/IEC 27017
  • ISO/IEC 27018
  • ISO/IEC 27701
  • KSA PDPL
  • MAS Technology Risk Management (Singapore)
  • MITRE ATT&CK (Cloud)
  • NIS2 Directive
  • NIST
  • NIST SP 800-171
  • NYDFS 23 NYCRR 500
  • SWIFT Customer Security Controls Framework
  • Sarbanes-Oxley IT General Controls
  • UK NCSC Cyber Assessment Framework

Triage and Remediation

Remediation

Using Console

The misconfiguration "Secure Listeners in Web-tier ELBs" suggests that the Elastic Load Balancer (ELB) in the web-tier of your AWS environment is not configured to use secure listeners. To remediate this issue, you can follow the below steps:

  1. Open the AWS Management Console and navigate to the EC2 dashboard.
  2. From the left-hand menu, click on "Load Balancers" under the "EC2" section.
  3. Select the web-tier ELB that needs to be remediated.
  4. Click on the "Listeners" tab at the bottom of the page.
  5. Click on the "Edit" button next to the HTTP listener.
  6. In the "Edit Listener" dialog box, change the protocol from "HTTP" to "HTTPS".
  7. Select the SSL certificate that you want to use for the HTTPS listener.
  8. Click on the "Save" button to save the changes.

Once the above steps are completed, the web-tier ELB will be configured to use secure listeners, and all the traffic between the clients and the ELB will be encrypted using SSL.

Using CLI

The misconfiguration "Secure Listeners in Web-tier ELBs" indicates that the Elastic Load Balancer (ELB) in the web-tier is not configured to use secure listeners (HTTPS). To remediate this issue, you can follow the below steps using AWS CLI:

  1. List all the ELBs in your AWS account using the following command:
aws elbv2 describe-load-balancers
  1. Identify the web-tier ELB that needs to be remediated.

  2. Check the current listener configuration for the identified ELB using the following command:

aws elbv2 describe-listeners --load-balancer-arn <ELB_ARN>
  1. If the listener is not configured to use HTTPS, create a new HTTPS listener using the following command:
aws elbv2 create-listener --load-balancer-arn <ELB_ARN> --protocol HTTPS --port 443 --default-actions Type=forward,TargetGroupArn=<TARGET_GROUP_ARN> --certificates CertificateArn=<CERTIFICATE_ARN>

Note: Replace <ELB_ARN>, <TARGET_GROUP_ARN>, and <CERTIFICATE_ARN> with the appropriate values for your environment.

  1. Verify that the new HTTPS listener is added successfully using the following command:
aws elbv2 describe-listeners --load-balancer-arn <ELB_ARN>
  1. Once the HTTPS listener is added, you can enable the redirect from HTTP to HTTPS using the following command:
aws elbv2 create-rule --listener-arn <HTTPS_LISTENER_ARN> --priority 1 --conditions Field=host-header,Values=<YOUR_DOMAIN_NAME> --actions Type=redirect,RedirectConfig={Protocol=HTTPS,Port=443,StatusCode=HTTP_301}

Note: Replace <HTTPS_LISTENER_ARN> and <YOUR_DOMAIN_NAME> with the appropriate values for your environment.

  1. Verify that the HTTP to HTTPS redirect is added successfully using the following command:
aws elbv2 describe-rules --listener-arn <HTTPS_LISTENER_ARN>

By following these steps, you can remediate the misconfiguration "Secure Listeners in Web-tier ELBs" in AWS.

Using Python

To remediate the misconfiguration "Secure Listeners in Web-tier ELBs" for AWS using Python, you can follow the below steps:

  1. Create a boto3 client object for Elastic Load Balancing (ELB) using the AWS SDK for Python (boto3).
import boto3
elb_client = boto3.client('elbv2')
  1. Get a list of all the ELBs in your AWS account using the describe_load_balancers method of the ELB client.
response = elb_client.describe_load_balancers()
elbs = response['LoadBalancers']
  1. Loop through the list of ELBs and check if they have any HTTP listeners. If an ELB has HTTP listeners, create a new listener with HTTPS protocol and a valid SSL certificate.
for elb in elbs:
http_listeners = [listener for listener in elb['Listeners'] if listener['Protocol'] == 'HTTP']
if http_listeners:
elb_arn = elb['LoadBalancerArn']
listener_arns = [listener['ListenerArn'] for listener in http_listeners]
ssl_cert_arn = 'arn:aws:acm:us-east-1:123456789012:certificate/abcd1234-abcd-1234-abcd-1234abcd1234'
response = elb_client.create_listener(
LoadBalancerArn=elb_arn,
Protocol='HTTPS',
Port=443,
SslPolicy='ELBSecurityPolicy-2016-08',
Certificates=[
{
'CertificateArn': ssl_cert_arn
}
]
)
https_listener_arn = response['Listeners'][0]['ListenerArn']
for listener_arn in listener_arns:
elb_client.delete_listener(
ListenerArn=listener_arn
)
  1. Once the HTTPS listener is created and the HTTP listeners are deleted, the ELB will only accept secure traffic over HTTPS.

Note: You will need to replace the ssl_cert_arn value with the ARN of a valid SSL certificate in your AWS account. Also, make sure to update the region and AWS account ID in the ARN.

Using Terraform
############################
# Classic Load Balancer (CLB)
############################

resource "aws_elb" "WEB_TIER_ELB" {
name = "WEB_TIER_ELB_NAME" # replace with your CLB name

availability_zones = [
"AZ_1",
"AZ_2",
]

# Existing HTTP listener on port 80 (OPTIONAL: remove this block after you confirm HTTPS works)
# Removing this listener is destructive and may break existing HTTP integrations.
listener {
lb_port = 80
lb_protocol = "http"
instance_port = 80
instance_protocol = "http"
}

# REQUIRED: new HTTPS listener on port 443
listener {
lb_port = 443
lb_protocol = "https"
instance_port = 80 # adjust if your backend listens on a different port
instance_protocol = "http" # adjust if your backend uses HTTPS
ssl_certificate_id = "YOUR_CERTIFICATE_ARN" # replace with your ACM or IAM certificate ARN
}

health_check {
target = "HTTP:80/"
interval = 30
timeout = 5
unhealthy_threshold = 2
healthy_threshold = 2
}

instances = [
"INSTANCE_ID_1",
"INSTANCE_ID_2",
]
}

############################
# Application / Network Load Balancer (ALB / NLB)
############################

resource "aws_lb" "WEB_TIER_LB" {
name = "WEB_TIER_LB_NAME" # replace with your ALB/NLB name
internal = false
load_balancer_type = "application" # or "network"

subnets = [
"SUBNET_ID_1",
"SUBNET_ID_2",
]
}

resource "aws_lb_target_group" "WEB_TIER_TG" {
name = "WEB_TIER_TG_NAME" # replace with your target group name
port = 80 # adjust if your backend listens on a different port
protocol = "HTTP" # adjust if your backend uses HTTPS
vpc_id = "VPC_ID"
}

# REQUIRED: new HTTPS listener on port 443 forwarding to the target group
resource "aws_lb_listener" "WEB_TIER_HTTPS" {
load_balancer_arn = aws_lb.WEB_TIER_LB.arn
port = 443
protocol = "HTTPS"
ssl_policy = "ELBSecurityPolicy-2016-08" # or another approved policy

certificate_arn = "YOUR_ACM_CERTIFICATE_ARN" # replace with your ACM certificate ARN

default_action {
type = "forward"
target_group_arn = aws_lb_target_group.WEB_TIER_TG.arn
}
}

# OPTIONAL: existing HTTP listener on port 80 (you may keep it or later change it to redirect to HTTPS)
resource "aws_lb_listener" "WEB_TIER_HTTP" {
load_balancer_arn = aws_lb.WEB_TIER_LB.arn
port = 80
protocol = "HTTP"

default_action {
type = "forward"
target_group_arn = aws_lb_target_group.WEB_TIER_TG.arn
}
}

Removing an existing HTTP listener (the 80-port listener block on aws_elb or the aws_lb_listener on port 80) is a destructive change that can break current HTTP clients, but it does not replace the load balancer resource itself.

Verification with terraform plan should show:

  • For CLB: addition of a new listener block with lb_port = 443, lb_protocol = "https", instance_port = 80, instance_protocol = "http", and ssl_certificate_id = "YOUR_CERTIFICATE_ARN", and (optionally) removal of the HTTP listener if you delete that block.
  • For ALB/NLB: creation of a new aws_lb_listener on port 443 with protocol = "HTTPS" and certificate_arn = "YOUR_ACM_CERTIFICATE_ARN" forwarding to the specified target group, and (optionally) removal or modification of the HTTP listener if you change or delete that resource.

Additional Reading: