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

CloudFront Logging Enabled

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

Ensure that access (standard) logging is enabled for your Amazon CloudFront distributions in order to track all viewer requests for the web content delivered through the Content Delivery Network (CDN).

This rule can help you with the following compliance standards:

  • PCI
  • HIPAA
  • GDPR
  • APRA
  • 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
Sustainability

The CloudFront access logs contain detailed information (requested object name, date and time of the access, client IP, access point, error code, etc.) about each request made for your web content, information that can be extremely useful during security audits or as input data for various analytics/reporting tools. You can also use this feature in combination with Amazon Lambda and Amazon WAF to process the logging data and block the requests coming from those IP addresses that generate too many error codes because the requests that generate these errors are often made by attackers trying to find vulnerabilities within your website/web application.


Audit

To determine if your Amazon CloudFront distributions have access logging enabled, perform the following operations:

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 name (link) of the CloudFront distribution that you want to examine.

05 Select the General tab to access the general configuration settings available for the selected distribution.

06 In the Settings section, check the Standard logging configuration attribute value. If the Standard logging attribute value is set to Off, the logging is disabled, therefore the selected Amazon CloudFront distribution is not tracking viewer requests.

07 Repeat steps no. 4 – 6 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 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 |
+------------------+
|  ABCDABCDABCDAB  |
|  AABBCCDDAABBCC  |
|  AAAABBBBCCCCDD  |
+------------------+

03 Run get-distribution command (OSX/Linux/UNIX) using the ID of the Amazon CloudFront distribution that you want to examine as the identifier parameter and custom query filters to describe the logging feature status available for the selected distribution:

aws cloudfront get-distribution
  --id ABCDABCDABCDAB
  --query 'Distribution.DistributionConfig.Logging.Enabled'

04 The command output should return the feature status:

false

If the get-distribution command output returns false, as shown in the example above, the logging feature is disabled, therefore the selected Amazon CloudFront distribution is not tracking viewer requests.

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

Remediation / Resolution

To enable access (standard) logging for your Amazon Cloudfront distributions, perform the following operations:

Using AWS CloudFormation

01 CloudFormation template (JSON):

{
	"AWSTemplateFormatVersion": "2010-09-09",
	"Resources": {
		"CloudFrontDistribution": {
			"Type": "AWS::CloudFront::Distribution",
			"Properties": {
				"DistributionConfig": {
					"Enabled": true,
					"Comment": "CloudFront CDN Web Distribution",
					"Origins": [
						{
							"Id": "cc-cdn-origin",
							"DomainName": "domain.com"
						}
					],
					"DefaultRootObject": "index.html",
					"DefaultCacheBehavior": {
						"AllowedMethods": [
							"HEAD",
							"GET"
						],
						"Compress": true,
						"DefaultTTL": 0,
						"ForwardedValues": {
							"Cookies": {
								"Forward": "none"
							},
							"QueryString": false
						},
						"ViewerProtocolPolicy": "redirect-to-https"
					},
					"HttpVersion": "http2",
					"ViewerCertificate": {
						"CloudFrontDefaultCertificate": true
					},
					"PriceClass": "PriceClass_All",
					"Logging": {
						"Bucket": "logs.s3.amazonaws.com",
						"Prefix": "access-logs/",
						"IncludeCookies": false
					}
				}
			}
		}
	}
}

02 CloudFormation template (YAML):

AWSTemplateFormatVersion: '2010-09-09'
	Resources:
	CloudFrontDistribution:
		Type: AWS::CloudFront::Distribution
		Properties:
		DistributionConfig:
			Enabled: true
			Comment: CloudFront CDN Web Distribution
			Origins:
			- Id: cc-cdn-origin
				DomainName: domain.com
			DefaultRootObject: index.html
			DefaultCacheBehavior:
			AllowedMethods:
				- HEAD
				- GET
			Compress: true
			DefaultTTL: 0
			ForwardedValues:
				Cookies:
				Forward: none
				QueryString: false
			ViewerProtocolPolicy: redirect-to-https
			HttpVersion: http2
			ViewerCertificate:
			CloudFrontDefaultCertificate: true
			PriceClass: PriceClass_All
			Logging:
			Bucket: logs.s3.amazonaws.com
			Prefix: access-logs/
			IncludeCookies: false

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_cloudfront_distribution" "cloudfront-distribution" {

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

	origin {
		domain_name = "domain.com"
		origin_id   = "cc-cdn-origin"
	}

	default_cache_behavior {
		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
		compress               = true
		viewer_protocol_policy = "redirect-to-https"
	}

	viewer_certificate {
		cloudfront_default_certificate = true
	}

	price_class = "PriceClass_All"

	logging_config {
		bucket          = "logs.s3.amazonaws.com"
		prefix          = "access-logs/"
		include_cookies = false
	}

}

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 name of the CloudFront distribution that you want to reconfigure.

05 Select the Generaltab to access the general configuration settings available for the selected distribution.

06 In the Settings section, choose Edit to modify the configuration settings.

07 On the Edit settings page, perform the following actions:

  1. Under Standard logging, choose On to enable the logging feature.
  2. For S3 bucket, specify the Amazon S3 bucket where CloudFront can deliver the log files. If the origin of the selected distribution is also an S3 bucket, Trend Cloud One™ – Conformity recommends selecting a different bucket for log files storage.
  3. (Optional) For Log prefix – optional, enter a unique prefix for the log file names in order to keep track of which access log files are associated with which distribution.
  4. (Optional) Under Cookie logging, choose On to include cookies in the access logs.
  5. Choose Save changes to apply the changes.

08 Repeat steps no. 4 – 7 to enable access (standard) logging for each Amazon CloudFront distribution available within your AWS cloud account.

Using AWS CLI

01 Run create-bucket command (OSX/Linux/UNIX) to create the Amazon S3 bucket that will store the log files for the selected Cloudfront distribution:

aws s3api create-bucket
  --region us-east-1
  --bucket cc-cloudfront-access-logs
  --acl private

02 The command output should return the name of the newly created S3 bucket:

{
	"Location": "/cc-cloudfront-access-logs"
}

03 Run put-public-access-block command (OSX/Linux/UNIX) to enable the S3 Public Access Block feature for the new S3 bucket (the command should not produce an output):

aws s3api put-public-access-block
  --region us-east-1
  --bucket cc-cloudfront-access-logs
  --public-access-block-configuration BlockPublicAcls=true,IgnorePublicAcls=true,BlockPublicPolicy=true,RestrictPublicBuckets=true

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": "cloudconformity.com",
				"DomainName": "cloudconformity.com",
				"OriginPath": "",
				"CustomHeaders": {
					"Quantity": 0
				},
				"CustomOriginConfig": {
					"HTTPPort": 80,
					"HTTPSPort": 443,
					"OriginProtocolPolicy": "http-only",
					"OriginSslProtocols": {
						"Quantity": 3,
						"Items": [
							"TLSv1",
							"TLSv1.1",
							"TLSv1.2"
						]
					},
					"OriginReadTimeout": 30,
					"OriginKeepaliveTimeout": 5
				},
				"ConnectionAttempts": 3,
				"ConnectionTimeout": 10,
				"OriginShield": {
					"Enabled": false
				}
			}
		]
	},
	"OriginGroups": {
		"Quantity": 0
	},
	"DefaultCacheBehavior": {
		"TargetOriginId": "cloudconformity.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": "cloudconformity.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": false
}

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. 5 to enable and configure the access logging for the selected CloudFront distribution. Use the S3 bucket created at the previous steps for log files storage. Save the document with the modified distribution configuration (highlighted) to a JSON file named enable-access-logging.json:

{
	"CallerReference": "abcd1234-abcd-1234-abcd-1234abcd1234",
	"Aliases": {
		"Quantity": 0
	},
	"DefaultRootObject": "",
	"Origins": {
		"Quantity": 1,
		"Items": [
			{
				"Id": "cloudconformity.com",
				"DomainName": "cloudconformity.com",
				"OriginPath": "",
				"CustomHeaders": {
					"Quantity": 0
				},
				"CustomOriginConfig": {
					"HTTPPort": 80,
					"HTTPSPort": 443,
					"OriginProtocolPolicy": "http-only",
					"OriginSslProtocols": {
						"Quantity": 3,
						"Items": [
							"TLSv1",
							"TLSv1.1",
							"TLSv1.2"
						]
					},
					"OriginReadTimeout": 30,
					"OriginKeepaliveTimeout": 5
				},
				"ConnectionAttempts": 3,
				"ConnectionTimeout": 10,
				"OriginShield": {
					"Enabled": false
				}
			}
		]
	},
	"OriginGroups": {
		"Quantity": 0
	},
	"DefaultCacheBehavior": {
		"TargetOriginId": "cloudconformity.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": "cloudconformity.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": true,
		"IncludeCookies": true,
		"Bucket": "cc-cloudfront-access-logs.s3.amazonaws.com",
		"Prefix": "cloudconformity.com"
	},
	"PriceClass": "PriceClass_100",
	"Enabled": true,
	"ViewerCertificate": {
		"CloudFrontDefaultCertificate": true,
		"MinimumProtocolVersion": "TLSv1",
		"CertificateSource": "cloudfront"
	},
	"Restrictions": {
		"GeoRestriction": {
			"RestrictionType": "none",
			"Quantity": 0
		}
	},
	"WebACLId": "",
	"HttpVersion": "http1.1",
	"IsIPV6Enabled": false
}

09 Run update-distribution command (OSX/Linux/UNIX) using the document modified at the previous step (i.e. enable-access-logging.json) as the distribution configuration document, to reconfigure the selected Amazon CloudFront distribution in order to enable access logging. --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-access-logging.json
  --query 'Distribution.Status'

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

"InProgress"

11 Repeat steps no. 4 – 10 to enable access (standard) logging for each Amazon CloudFront distribution deployed in your AWS cloud account.

References

Publication date Aug 27, 2016