CloudFront Distribution Serves HTTPS Requests Using SNI
Overview
This check verifies that your CloudFront distributions using custom SSL/TLS certificates are configured to use Server Name Indication (SNI) instead of dedicated IP addresses.
SNI is a modern TLS extension that allows multiple SSL certificates to share a single IP address. When you use a custom domain with CloudFront (like www.example.com), you need an SSL certificate. SNI lets CloudFront serve that certificate efficiently without reserving a dedicated IP address just for your distribution.
Risk
Without SNI enabled, CloudFront uses dedicated IP SSL, which creates several problems:
- Higher costs: Dedicated IP addresses cost significantly more than SNI
- IP quota strain: You may run out of available IP addresses as you scale
- Reduced availability: IP constraints can limit your ability to expand
- Operational complexity: Managing IP-bound certificates is harder during rotations and expansions
Remediation Steps
Prerequisites
- Access to the AWS Console with permissions to modify CloudFront distributions
- If using a custom SSL certificate, it must already be in AWS Certificate Manager (ACM) in the us-east-1 region
AWS Console Method
- Open the CloudFront console
- Select the distribution you want to update
- Click the General tab, then click Edit in the Settings section
- Scroll to Custom SSL certificate - you should see your certificate selected
- Under Legacy clients support, select SNI only (recommended) instead of "Legacy clients support"
- Click Save changes
Changes typically take 5-15 minutes to deploy across all CloudFront edge locations.
AWS CLI Method
The CLI approach requires downloading the current configuration, modifying it, and uploading the changes.
Step 1: Get the current configuration
# Replace DISTRIBUTION_ID with your actual distribution ID (e.g., E1A2B3C4D5E6F7)
DISTRIBUTION_ID="<your-distribution-id>"
# Get current config and ETag
aws cloudfront get-distribution-config \
--id "$DISTRIBUTION_ID" \
--region us-east-1 \
--output json > /tmp/dist-config.json
# Extract the ETag (needed for updates)
ETAG=$(aws cloudfront get-distribution-config \
--id "$DISTRIBUTION_ID" \
--region us-east-1 \
--query "ETag" \
--output text)
Step 2: Modify the configuration
Edit /tmp/dist-config.json to change the ViewerCertificate section:
"ViewerCertificate": {
"ACMCertificateArn": "arn:aws:acm:us-east-1:123456789012:certificate/abc123",
"SSLSupportMethod": "sni-only",
"MinimumProtocolVersion": "TLSv1.2_2021"
}
Important: You must also:
- Remove the top-level
ETagfield from the JSON - Keep only the
DistributionConfigobject (remove the wrapper)
Step 3: Apply the update
aws cloudfront update-distribution \
--id "$DISTRIBUTION_ID" \
--distribution-config file:///tmp/dist-config.json \
--if-match "$ETAG" \
--region us-east-1
CloudFormation Template
Use this template to create a new CloudFront distribution with SNI enabled, or reference it when updating existing stacks.
AWSTemplateFormatVersion: '2010-09-09'
Description: CloudFront Distribution with SNI-only SSL configuration
Parameters:
DomainName:
Type: String
Description: Your custom domain name (e.g., www.example.com)
AcmCertificateArn:
Type: String
Description: ARN of the ACM certificate in us-east-1 for your domain
S3BucketDomainName:
Type: String
Description: S3 bucket regional domain name for origin
Resources:
CloudFrontDistribution:
Type: AWS::CloudFront::Distribution
Properties:
DistributionConfig:
Enabled: true
Comment: Distribution with SNI-only SSL configuration
DefaultRootObject: index.html
Aliases:
- !Ref DomainName
Origins:
- Id: S3Origin
DomainName: !Ref S3BucketDomainName
S3OriginConfig:
OriginAccessIdentity: ''
DefaultCacheBehavior:
TargetOriginId: S3Origin
ViewerProtocolPolicy: redirect-to-https
AllowedMethods:
- GET
- HEAD
CachedMethods:
- GET
- HEAD
ForwardedValues:
QueryString: false
Cookies:
Forward: none
ViewerCertificate:
AcmCertificateArn: !Ref AcmCertificateArn
SslSupportMethod: sni-only
MinimumProtocolVersion: TLSv1.2_2021
Outputs:
DistributionId:
Description: CloudFront Distribution ID
Value: !Ref CloudFrontDistribution
DistributionDomainName:
Description: CloudFront Distribution Domain Name
Value: !GetAtt CloudFrontDistribution.DomainName
The key configuration is in the ViewerCertificate section:
SslSupportMethod: sni-only- Uses SNI instead of dedicated IPMinimumProtocolVersion: TLSv1.2_2021- Enforces modern TLS
Terraform Configuration
terraform {
required_providers {
aws = {
source = "hashicorp/aws"
version = "~> 5.0"
}
}
}
provider "aws" {
region = "us-east-1"
}
variable "domain_name" {
description = "Your custom domain name (e.g., www.example.com)"
type = string
}
variable "acm_certificate_arn" {
description = "ARN of the ACM certificate in us-east-1"
type = string
}
variable "origin_domain_name" {
description = "Domain name of the origin (e.g., S3 bucket)"
type = string
}
resource "aws_cloudfront_distribution" "main" {
enabled = true
comment = "Distribution with SNI-only SSL configuration"
default_root_object = "index.html"
aliases = [var.domain_name]
origin {
domain_name = var.origin_domain_name
origin_id = "S3Origin"
}
default_cache_behavior {
allowed_methods = ["GET", "HEAD"]
cached_methods = ["GET", "HEAD"]
target_origin_id = "S3Origin"
viewer_protocol_policy = "redirect-to-https"
forwarded_values {
query_string = false
cookies {
forward = "none"
}
}
}
viewer_certificate {
acm_certificate_arn = var.acm_certificate_arn
ssl_support_method = "sni-only"
minimum_protocol_version = "TLSv1.2_2021"
}
restrictions {
geo_restriction {
restriction_type = "none"
}
}
}
output "distribution_id" {
description = "CloudFront Distribution ID"
value = aws_cloudfront_distribution.main.id
}
output "distribution_domain_name" {
description = "CloudFront Distribution Domain Name"
value = aws_cloudfront_distribution.main.domain_name
}
The critical setting in the viewer_certificate block is:
ssl_support_method = "sni-only"- Enables SNI instead of dedicated IP
Verification
After making changes, verify SNI is enabled:
- Open the CloudFront console
- Select your distribution
- In the General tab, look for Custom SSL certificate
- Confirm it shows SNI (not "Legacy clients support" or "Dedicated IP")
CLI Verification
aws cloudfront get-distribution \
--id "<your-distribution-id>" \
--region us-east-1 \
--query "Distribution.DistributionConfig.ViewerCertificate.SSLSupportMethod" \
--output text
The output should be sni-only.
Additional Resources
- AWS CloudFront Custom SSL Documentation
- Choosing Between SNI and Dedicated IP
- Supported TLS Protocols and Ciphers
- Prowler Check Documentation
Notes
-
SNI compatibility: SNI is supported by all modern browsers and clients. The only exception is very old clients (Internet Explorer on Windows XP, Android 2.x). If you must support these legacy clients, you may need dedicated IP, but this should be rare.
-
Certificate location: Custom SSL certificates for CloudFront must be stored in ACM in the us-east-1 region, regardless of where your origin is located.
-
Cost difference: SNI is included at no additional charge. Dedicated IP SSL costs approximately $600/month per distribution.
-
Deployment time: Changes to SSL settings typically propagate across all CloudFront edge locations within 5-15 minutes.