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

Enable Origin Access Control for Distributions with S3 Origin

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)

Ensure that the Origin Access Control (OAC) feature is enabled for all your Amazon CloudFront distributions that utilize an S3 bucket as an origin in order to restrict any direct access to your objects through Amazon S3 URLs.

Security

When your CloudFront distributions are using Amazon S3 buckets as origins, the web content should be kept private and delivered only via CloudFront Content Delivery Network (CDN), using an origin access identity to regulate access. With Origin Access Control (OAC) enabled, your Amazon CloudFront distributions can be much more cost effective if your viewers access your objects frequently as the price for CloudFront data transfer is lower than the price for S3 data transfer. In addition, downloads are faster when only the CloudFront service is used to deliver your web content instead of S3 because the objects are copied to all edge locations within the distribution in order to be stored closer to your viewers.


Audit

To determine if Origin Access Control (OAC) is enabled for Amazon CloudFront distributions configured with S3 as origin, perform the following actions:

Using AWS Console

01 Sign in to the AWS Management Console.

02 Navigate to Amazon CloudFront console at https://console.aws.amazon.com/cloudfront/v3/.

03 In the left navigation panel, under CloudFront, choose Distributions.

04 Click on the ID (link) of the CloudFront distribution that you want to examine.

05 Select the Origins tab to access the origins created for the selected distribution.

06 Select the distribution origin with the Origin type set to S3 and choose Edit.

07 On the Edit origin page, check the Origin access configuration setting to determine the origin access configuration set for the selected S3 origin. If the Origin access is not set to Origin access control settings (recommended), the selected Amazon CloudFront distribution is not using the Origin Access Control (OAC) feature to access the S3 bucket, therefore the access to the Amazon S3 bucket used as distribution origin is not properly restricted.

08 Repeat steps no. 4 – 7 for each CloudFront distribution available within your AWS cloud account.

Using AWS CLI

01 Run list-distributions command (OSX/Linux/UNIX) with custom query filters to list the ID of each Amazon CloudFront distribution created in your AWS cloud account:

aws cloudfront list-distributions
  --output table
  --query 'DistributionList.Items[*].Id'

02 The command output should return a table with the requested distribution ID(s):

--------------------
|ListDistributions |
+------------------+
|  AAAABBBBCCCCDD  |
|  ABCDABCDABCDAB  |
|  AABBCCDDAABBCC  |
+------------------+

03 Run get-distribution-config command (OSX/Linux/UNIX) using the ID of the Amazon CloudFront distribution that you want to examine as the identifier parameter and custom filtering to describe the ID of the Origin Access Control (OAC) defined for each S3 bucket configured as origin for the selected distribution:

aws cloudfront get-distribution-config
  --id AAAABBBBCCCCDD
  --query 'DistributionConfig.Origins.Items[*].OriginAccessControlId'

04 The command output should return the requested OAC identifiers (IDs):

[
	""
]

If the get-distribution-config command output returns an array with an empty string (i.e. ""), as shown in the example above, the selected Amazon CloudFront distribution is not using the Origin Access Control (OAC) feature to access the S3 bucket, hence the access to the Amazon S3 bucket used as distribution origin is not properly restricted.

05 Repeat steps no. 3 and 4 for each CloudFront distribution deployed in your AWS cloud account.

Remediation / Resolution

To enable the Origin Access Control (OAC) feature for your Amazon Cloudfront distributions and restrict the user access to the S3 buckets used as distribution origins, perform the following actions:

Using AWS CloudFormation

01 CloudFormation template (JSON):

{
	"AWSTemplateFormatVersion": "2010-09-09",
	"Resources": {
		"OriginAccessControlConfig": {
			"Type": "AWS::CloudFront::OriginAccessControl",
			"Properties": {
				"OriginAccessControlConfig": {
					"Name": "cc-oac-config",
					"Description": "Trend Micro OAC",
					"OriginAccessControlOriginType": "s3",
					"SigningBehavior": "always",
					"SigningProtocol": "sigv4"
				}
			}
		},
		"CloudFrontDistribution": {
			"Type": "AWS::CloudFront::Distribution",
			"Properties": {
				"DistributionConfig": {
					"Enabled": true,
					"Comment": "CloudFront CDN Web Distribution",
					"Origins": [
						{
							"Id": "cc-s3-cdn-origin",
							"DomainName": "trendmicro.s3.amazonaws.com",
							"OriginAccessControlId": {
								"Ref": "OriginAccessControlConfig"
							}
						}
					],
					"DefaultRootObject": "index.html",
					"DefaultCacheBehavior": {
						"Compress": true,
						"AllowedMethods": [
							"HEAD",
							"GET"
						],
						"DefaultTTL": 0,
						"ForwardedValues": {
							"Cookies": {
								"Forward": "none"
							},
							"QueryString": false
						},
						"ViewerProtocolPolicy": "redirect-to-https"
					},
					"HttpVersion": "http2",
					"ViewerCertificate": {
						"CloudFrontDefaultCertificate": true
					},
					"PriceClass": "PriceClass_All"
				}
			}
		}
	}
}

02 CloudFormation template (YAML):

AWSTemplateFormatVersion: '2010-09-09'
	Resources:
	OriginAccessControlConfig:
		Type: AWS::CloudFront::OriginAccessControl
		Properties:
		OriginAccessControlConfig:
			Name: cc-oac-config
			Description: Trend Micro OAC
			OriginAccessControlOriginType: s3
			SigningBehavior: always
			SigningProtocol: sigv4
	CloudFrontDistribution:
		Type: AWS::CloudFront::Distribution
		Properties:
		DistributionConfig:
			Enabled: true
			Comment: CloudFront CDN Web Distribution
			Origins:
			- Id: cc-s3-cdn-origin
				DomainName: trendmicro.s3.amazonaws.com
				OriginAccessControlId: !Ref 'OriginAccessControlConfig'
			DefaultRootObject: index.html
			DefaultCacheBehavior:
			Compress: true
			AllowedMethods:
				- HEAD
				- GET
			DefaultTTL: 0
			ForwardedValues:
				Cookies:
				Forward: none
				QueryString: false
			ViewerProtocolPolicy: redirect-to-https
			HttpVersion: http2
			ViewerCertificate:
			CloudFrontDefaultCertificate: true
			PriceClass: PriceClass_All

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" {
	profile = "default"
	region  = "us-east-1"
}

resource "aws_s3_bucket" "s3-origin-bucket" {
	bucket = "trendmicro"
}

resource "aws_cloudfront_origin_access_control" "origin-access-control-config" {
	name                              = "cc-oac-config"
	description                       = "Trend Micro OAC"
	origin_access_control_origin_type = "s3"
	signing_behavior                  = "always"
	signing_protocol                  = "sigv4"
}

resource "aws_cloudfront_distribution" "cloudfront-distribution" {

	enabled             = true
	default_root_object = "index.html"
	comment             = "CloudFront CDN Web Distribution"

	origin {
		origin_id                = "cc-s3-cdn-origin"
		domain_name              = aws_s3_bucket.s3-origin-bucket.bucket_regional_domain_name
		origin_access_control_id = aws_cloudfront_origin_access_control.origin-access-control-config.id
	}

	default_cache_behavior {
		compress         = true
		target_origin_id = "cc-domain-origin"
		allowed_methods  = ["GET", "HEAD"]
		cached_methods   = ["GET", "HEAD"]
		forwarded_values {
			query_string = false
			cookies {
				forward = "none"
			}
		}
		min_ttl                = 0
		default_ttl            = 3600
		max_ttl                = 86400
		viewer_protocol_policy = "redirect-to-https"
	}

	viewer_certificate {
		cloudfront_default_certificate = true
	}

	price_class = "PriceClass_All"

}

Using AWS Console

01 Sign in to the AWS Management Console.

02 Navigate to Amazon CloudFront console at https://console.aws.amazon.com/cloudfront/v3/.

03 In the left navigation panel, under CloudFront, choose Distributions.

04 Click on the ID (name) of the CloudFront distribution that you want to configure.

05 Select the Origins tab to access the origins created for the selected distribution.

06 Select the distribution origin with the Origin type set to S3 and choose Edit.

07 On the Edit origin configuration page, perform the following operations:

  1. Under Origin access, select Origin access control settings (recommended) to enable the Origin Access Control (OAC) feature for the selected distribution. This will allow you to block public access to the s3 origin, allowing viewers to access the origin's content only through Amazon CloudFront.
  2. For Origin access control, select Create control setting to create the required OAC configuration.
  3. In the Create control setting configuration box, enter a unique name for your OAC, provide a short description, select Sign requests (recommended) for Signing behavior, choose S3 for Origin type, then choose Create to create your new Origin Access Control.
  4. Under Bucket policy, choose Copy policy, select Go to S3 bucket permissionsand update the bucket policy to grant access to the new OAC.
  5. Choose Save changes to apply the changes.

08 Repeat steps no. 4 – 7 to enable Origin Access Control (OAC) for each Amazon CloudFront distribution with S3 origins, available within your AWS cloud account.

Using AWS CLI

01 Define the configuration file required to enable Origin Access Control (OAC). Save the configuration to a JSON file named oac-config.json:

{
	"Name": "cc-oac-config",
	"Description": "Trend Micro OAC",
	"SigningProtocol": "sigv4",
	"SigningBehavior": "always",
	"OriginAccessControlOriginType": "s3"
}

02 Run create-origin-access-control command (OSX/Linux/UNIX) to enable the Origin Access Control (OAC) feature using the configuration file defined at the previous step (i.e. oac-config.json). OAC makes it possible to block public access to the s3 origin, allowing viewers to access the origin's content only through Amazon CloudFront:

aws cloudfront create-origin-access-control 
  --origin-access-control-config file://oac-config.json

03 The command output should return the configuration information available for the OAC:

{
	"Location": "https://cloudfront.amazonaws.com/2020-05-31/origin-access-control/AAABBBCCCDDDAB",
	"ETag": "AAAABBBBCCCCD",
	"OriginAccessControl": {
		"Id": "AAABBBCCCDDDAB",
		"OriginAccessControlConfig": {
			"Name": "cc-oac-config",
			"Description": "Trend Micro OAC",
			"SigningProtocol": "sigv4",
			"SigningBehavior": "always",
			"OriginAccessControlOriginType": "s3"
		}
	}
}

04 Run get-distribution-config command (OSX/Linux/UNIX) to extract all the configuration information from the Amazon CloudFront distribution that you want to reconfigure:

aws cloudfront get-distribution-config
  --id ABCDABCDABCDAB
  --query 'DistributionConfig'

05 The command output should return the requested configuration information:

{
	"CallerReference": "abcd1234-abcd-1234-abcd-1234abcd1234",
	"Aliases": {
		"Quantity": 0
	},
	"DefaultRootObject": "",
	"Origins": {
		"Quantity": 1,
		"Items": [
			{
				"Id": "cc-web-files.s3.us-east-1.amazonaws.com",
				"DomainName": "cc-web-files.s3.us-east-1.amazonaws.com",
				"OriginPath": "",
				"CustomHeaders": {
					"Quantity": 0
				},
				"S3OriginConfig": {
					"OriginAccessIdentity": ""
				},
				"ConnectionAttempts": 3,
				"ConnectionTimeout": 10,
				"OriginShield": {
					"Enabled": false
				}
			}
		]
	},
	"OriginGroups": {
		"Quantity": 0
	},
	"DefaultCacheBehavior": {
		"TargetOriginId": "cc-web-files.s3.us-east-1.amazonaws.com",
		"TrustedSigners": {
			"Enabled": false,
			"Quantity": 0
		},
		"TrustedKeyGroups": {
			"Enabled": false,
			"Quantity": 0
		},
		"ViewerProtocolPolicy": "allow-all",
		"AllowedMethods": {
			"Quantity": 2,
			"Items": [
				"HEAD",
				"GET"
			],
			"CachedMethods": {
				"Quantity": 2,
				"Items": [
					"HEAD",
					"GET"
				]
			}
		},
		"SmoothStreaming": false,
		"Compress": true,
		"LambdaFunctionAssociations": {
			"Quantity": 0
		},
		"FunctionAssociations": {
			"Quantity": 0
		},
		"FieldLevelEncryptionId": "",
		"ForwardedValues": {
			"QueryString": false,
			"Cookies": {
				"Forward": "none"
			},
			"Headers": {
				"Quantity": 0
			},
			"QueryStringCacheKeys": {
				"Quantity": 0
			}
		},
		"MinTTL": 0,
		"DefaultTTL": 86400,
		"MaxTTL": 31536000
	},
	"CacheBehaviors": {
		"Quantity": 1,
		"Items": [
			{
				"PathPattern": "/images",
				"TargetOriginId": "cc-web-files.s3.us-east-1.amazonaws.com",
				"TrustedSigners": {
					"Enabled": false,
					"Quantity": 0
				},
				"TrustedKeyGroups": {
					"Enabled": false,
					"Quantity": 0
				},
				"ViewerProtocolPolicy": "allow-all",
				"AllowedMethods": {
					"Quantity": 2,
					"Items": [
						"HEAD",
						"GET"
					],
					"CachedMethods": {
						"Quantity": 2,
						"Items": [
							"HEAD",
							"GET"
						]
					}
				},
				"SmoothStreaming": false,
				"Compress": true,
				"LambdaFunctionAssociations": {
					"Quantity": 0
				},
				"FunctionAssociations": {
					"Quantity": 0
				},
				"FieldLevelEncryptionId": "",
				"ForwardedValues": {
					"QueryString": false,
					"Cookies": {
						"Forward": "none"
					},
					"Headers": {
						"Quantity": 0
					},
					"QueryStringCacheKeys": {
						"Quantity": 0
					}
				},
				"MinTTL": 0,
				"DefaultTTL": 86400,
				"MaxTTL": 31536000
			}
		]
	},
	"CustomErrorResponses": {
		"Quantity": 0
	},
	"Comment": "",
	"Logging": {
		"Enabled": false,
		"IncludeCookies": false,
		"Bucket": "",
		"Prefix": ""
	},
	"PriceClass": "PriceClass_100",
	"Enabled": true,
	"ViewerCertificate": {
		"CloudFrontDefaultCertificate": true,
		"MinimumProtocolVersion": "TLSv1",
		"CertificateSource": "cloudfront"
	},
	"Restrictions": {
		"GeoRestriction": {
			"RestrictionType": "none",
			"Quantity": 0
		}
	},
	"WebACLId": "",
	"HttpVersion": "http1.1",
	"IsIPV6Enabled": true
}

06 Run get-distribution-config command (OSX/Linux/UNIX) to describe the current version of the configuration available for the selected distribution (i.e. eTag):

aws cloudfront get-distribution-config
  --id ABCDABCDABCDAB
  --query 'ETag'

07 The command output should return the requested information:

"AAAABBBBCCCCD"

08 Modify the configuration document returned at step no. 4 to enable Origin Access Control (OAC) for the S3 bucket configured as origin for selected CloudFront distribution. Use the newly created OAC object created at the previous steps. Save the document with the modified distribution configuration (highlighted) to a JSON file named enable-origin-access-control.json:

{
	"CallerReference": "abcd1234-abcd-1234-abcd-1234abcd1234",
	"Aliases": {
		"Quantity": 0
	},
	"DefaultRootObject": "",
	"Origins": {
		"Quantity": 1,
		"Items": [
			{
				"Id": "cc-web-files.s3.us-east-1.amazonaws.com",
				"DomainName": "cc-web-files.s3.us-east-1.amazonaws.com",
				"OriginPath": "",
				"CustomHeaders": {
					"Quantity": 0
				},
				"S3OriginConfig": {
					""
				},
				"ConnectionAttempts": 3,
				"ConnectionTimeout": 10,
				"OriginShield": {
					"Enabled": false
				},
				"OriginAccessControl": {
					"Id": "AAABBBCCCDDDAB",
					"OriginAccessControlConfig": {
						"Name": "cc-oac-config",
						"Description": "Trend Micro OAC",
						"SigningProtocol": "sigv4",
						"SigningBehavior": "always",
						"OriginAccessControlOriginType": "s3"
					}
				}
			}
		]
	},
	"OriginGroups": {
		"Quantity": 0
	},
	"DefaultCacheBehavior": {
		"TargetOriginId": "cc-web-files.s3.us-east-1.amazonaws.com",
		"TrustedSigners": {
			"Enabled": false,
			"Quantity": 0
		},
		"TrustedKeyGroups": {
			"Enabled": false,
			"Quantity": 0
		},
		"ViewerProtocolPolicy": "allow-all",
		"AllowedMethods": {
			"Quantity": 2,
			"Items": [
				"HEAD",
				"GET"
			],
			"CachedMethods": {
				"Quantity": 2,
				"Items": [
					"HEAD",
					"GET"
				]
			}
		},
		"SmoothStreaming": false,
		"Compress": true,
		"LambdaFunctionAssociations": {
			"Quantity": 0
		},
		"FunctionAssociations": {
			"Quantity": 0
		},
		"FieldLevelEncryptionId": "",
		"ForwardedValues": {
			"QueryString": false,
			"Cookies": {
				"Forward": "none"
			},
			"Headers": {
				"Quantity": 0
			},
			"QueryStringCacheKeys": {
				"Quantity": 0
			}
		},
		"MinTTL": 0,
		"DefaultTTL": 86400,
		"MaxTTL": 31536000
	},
	"CacheBehaviors": {
		"Quantity": 1,
		"Items": [
			{
				"PathPattern": "/images",
				"TargetOriginId": "cc-web-files.s3.us-east-1.amazonaws.com",
				"TrustedSigners": {
					"Enabled": false,
					"Quantity": 0
				},
				"TrustedKeyGroups": {
					"Enabled": false,
					"Quantity": 0
				},
				"ViewerProtocolPolicy": "allow-all",
				"AllowedMethods": {
					"Quantity": 2,
					"Items": [
						"HEAD",
						"GET"
					],
					"CachedMethods": {
						"Quantity": 2,
						"Items": [
							"HEAD",
							"GET"
						]
					}
				},
				"SmoothStreaming": false,
				"Compress": true,
				"LambdaFunctionAssociations": {
					"Quantity": 0
				},
				"FunctionAssociations": {
					"Quantity": 0
				},
				"FieldLevelEncryptionId": "",
				"ForwardedValues": {
					"QueryString": false,
					"Cookies": {
						"Forward": "none"
					},
					"Headers": {
						"Quantity": 0
					},
					"QueryStringCacheKeys": {
						"Quantity": 0
					}
				},
				"MinTTL": 0,
				"DefaultTTL": 86400,
				"MaxTTL": 31536000
			}
		]
	},
	"CustomErrorResponses": {
		"Quantity": 0
	},
	"Comment": "",
	"Logging": {
		"Enabled": false,
		"IncludeCookies": false,
		"Bucket": "",
		"Prefix": ""
	},
	"PriceClass": "PriceClass_100",
	"Enabled": true,
	"ViewerCertificate": {
		"CloudFrontDefaultCertificate": true,
		"MinimumProtocolVersion": "TLSv1",
		"CertificateSource": "cloudfront"
	},
	"Restrictions": {
		"GeoRestriction": {
			"RestrictionType": "none",
			"Quantity": 0
		}
	},
	"WebACLId": "",
	"HttpVersion": "http1.1",
	"IsIPV6Enabled": true
}

09 Run update-distribution command (OSX/Linux/UNIX) using the document modified at the previous step (i.e. enable-origin-access-control.json) as the distribution configuration document, to configure the selected Amazon CloudFront distribution in order to enable Origin Access Control (OAC). --if-match parameter represents the current version of the configuration, returned at step no. 7:

aws cloudfront update-distribution
  --id ABCDABCDABCDAB
  --if-match AAAABBBBCCCCD
  --distribution-config file://enable-origin-access-control.json
  --query 'Distribution.Status'

10 The command output should return the status of the modified CloudFront distribution:

"InProgress"

11 Repeat steps no. 1 – 10 to enable Origin Access Control (OAC) for each Amazon CloudFront distribution with S3 origins, deployed in your AWS cloud account.

References

Publication date May 7, 2017