Apply WAF Web ACL to CloudFront

TOC

Apply WAF Web ACL to CloudFront

AWS WAF can be applied to the following four types of resources

  • ALB
  • CloudFront
  • API Gateway
  • AppSync

In this article, we will check how to apply WAF to CloudFront.

For details on how to apply WAF to ALB, please refer to the following page.

あわせて読みたい
Introduction to WAF Web ACL with CNF – ALB Ver. 【Creating WAF Web ACL with CloudFormation】 AWS WAF (Web Application Firewall) is a security service provided by AWS.WAF consists of several services, but t...

For information on how to apply WAF to API Gateway, please see the following page

あわせて読みたい
Create REST API type API Gateway using CFN 【Create REST API type API Gateway using CloudFormation】 The following page covers the HTTP API type API Gateway. https://awstut.com/en/2021/12/11/serverles...

For information on how to apply WAF to AppSync, please refer to the following page

あわせて読みたい
Apply WAF Web ACL to AppSync 【Apply WAF Web ACL to AppSync】 AWS WAF can be applied to the following four types of resources ALB CloudFront API Gateway AppSync In this article, we will ...

Environment

Diagram of applying WAF Web ACL to CloudFront.

Create a WAF Web ACL.
Restrict geography.
Specifically, create your own rule group and set a rule to block access from Japan (JP) in it.
Apply the created Web ACL to CloudFront.

Create a CloudFront distribution.
Specify an S3 bucket as the origin.
Create an OAI in CloudFront and restrict the S3 bucket policy to allow access only from the OAI.

Create a Lambda function.
Configure this function as a CloudFormation custom resource.
The function’s function is to automatically create and delete objects in the bucket when creating and deleting stacks.
The object to be created is index.html for static website hosting.
The runtime for the function is Python 3.8.

CloudFormation template files

The above configuration is built using CloudFormation.
The CloudFormation templates are located at the following URL

https://github.com/awstut-an-r/awstut-fa/tree/main/051

Explanation of key points of template files

This page focuses on how to apply WAF to CloudFront.

For basic information on WAF, please refer to the following page

あわせて読みたい
Introduction to WAF Web ACL with CNF – ALB Ver. 【Creating WAF Web ACL with CloudFormation】 AWS WAF (Web Application Firewall) is a security service provided by AWS.WAF consists of several services, but t...

For information on how to restrict geography with WAF, please refer to the following page

あわせて読みたい
Geographic Restrictions using WAF Web ACL 【Create your own rule groups in WAF Web ACL to restrict geography】 WAF Web ACL allows you to set up rules with various conditions.In this article, we will ...

For information on how to specify an S3 bucket as the origin of CloudFront and use OAI, please refer to the following page

あわせて読みたい
S3 content delivery via CloudFront – OAI ver 【Restricting access to origin with OAI when delivering S3 content from CloudFront】 The following page shows how to restrict access to origin by using the R...

For information on custom resources in CloudFormation, please refer to the following page

あわせて読みたい
Create and Delete S3 Object by CFN Custom Resource 【How to create/delete S3 objects during stack creation/deletion with CloudFormation custom resources】 CloudFormation custom resources can perform any actio...

Region to create WAF to be applied to CloudFront

When applying WAF to CloudFront, the first point to be considered is the region where the WAF will be created.

For CLOUDFRONT, you must create your WAFv2 resources in the US East (N. Virginia) Region, us-east-1.

AWS::WAFv2::WebACL

Please note that there are region restrictions when applying WAF to CloudFront as described above.

Web ACL

Resources:
  RuleGroup:
    Type: AWS::WAFv2::RuleGroup
    Properties:
      Capacity: 10
      Name: !Sub "${Prefix}-GeoRestrictionRuleGroup"
      Rules:
        - Action:
            Block: {}
          Name: !Sub "${Prefix}-GeoRestrictionRule"
          Priority: 0
          Statement:
            GeoMatchStatement:
              CountryCodes:
                - JP
          VisibilityConfig:
            CloudWatchMetricsEnabled: true
            MetricName: !Sub "${Prefix}-GeoRestrictionRule"
            SampledRequestsEnabled: true
      Scope: CLOUDFRONT
      VisibilityConfig:
        CloudWatchMetricsEnabled: true
        MetricName: !Sub "${Prefix}-GeoRestrictionRuleGroup"
        SampledRequestsEnabled: true

  WebACL:
    Type: AWS::WAFv2::WebACL
    Properties:
      DefaultAction:
        Allow: {}
      Name: !Sub "${Prefix}-WebACL"
      Rules:
        - Name: !Sub "${Prefix}-WebACL-GeoRestriction"
          OverrideAction:
            None: {}
          Priority: 0
          Statement:
            RuleGroupReferenceStatement:
              Arn: !GetAtt RuleGroup.Arn
          VisibilityConfig:
            CloudWatchMetricsEnabled: true
            MetricName: !Sub "${Prefix}-WebACL-GeoRestriction"
            SampledRequestsEnabled: true
      Scope: CLOUDFRONT
      VisibilityConfig:
        CloudWatchMetricsEnabled: true
        MetricName: !Ref Prefix
        SampledRequestsEnabled: true
Code language: YAML (yaml)

Define rule groups for Web ACLs and ACLs and set geo-restrictions.
The key point is the Scope property for both resources.
Instructions on how to set this property are provided below.

Specifies whether this is for an Amazon CloudFront distribution or for a regional application. A regional application can be an Application Load Balancer (ALB), an Amazon API Gateway REST API, or an AWS AppSync GraphQL API. Valid Values are CLOUDFRONT and REGIONAL.

AWS::WAFv2::WebACL

This time, WAF will be applied to CloudFront, so set “CLOUDFRONT” to this property.

CloudFront

Resources:
  Distribution:
    Type: AWS::CloudFront::Distribution
    Properties:
      DistributionConfig:
        DefaultCacheBehavior:
          AllowedMethods:
            - GET
            - HEAD
          CachedMethods:
            - GET
            - HEAD
          Compress: true
          ForwardedValues:
            Cookies:
              Forward: none
            QueryString: false
          TargetOriginId: !Ref BucketName
          ViewerProtocolPolicy: allow-all
        DefaultRootObject: index.html
        Enabled: true
        Origins:
          - DomainName: !Ref BucketRegionalDomainName
            Id: !Ref BucketName
            S3OriginConfig:
              OriginAccessIdentity: !Sub "origin-access-identity/cloudfront/${OAI}"
        PriceClass: PriceClass_All
        WebACLId: !Ref WebACLArn
Code language: YAML (yaml)

The key point is the WebACLId property.
Specify the ARN of the WAF mentioned above for this property.

When applying WAF to ALB, we associated it by creating an AWS::WAFv2::WebACLAssociation resource and specifying both ARNs for it.
Please note that this resource is not used for CloudFront, as quoted below.

For Amazon CloudFront, don’t use this resource. Instead, use your CloudFront distribution configuration. To associate a web ACL with a distribution, provide the Amazon Resource Name (ARN) of the AWS::WAFv2::WebACL to your CloudFront distribution configuration.

AWS::WAFv2::WebACLAssociation

Architecting

Use CloudFormation to build this environment and check the actual behavior.

Create CloudFormation stacks and check resources in stacks

Create a CloudFormation stacks.
For information on how to create stacks and check each stack, please refer to the following page

あわせて読みたい
CloudFormation’s nested stack 【How to build an environment with a nested CloudFormation stack】 Examine nested stacks in CloudFormation. CloudFormation allows you to nest stacks. Nested ...

This time, be careful which region you create the stack in.
When creating a stack with the AWS CLI, specify the us-east-1 region in the region option as shown in the command below.

aws cloudformation create-stack \
--stack-name [stack-name]
--template-url https://[bucket-name].s3.[region].amazonaws.com/[folder-name]/fa-051.yaml
--capabilities CAPABILITY_IAM
--region us-east-1
Code language: Bash (bash)

After checking the resources in each stack, the following is the information on the main resources created in this case.

  • S3 bucket: fa-051
  • CloudFront distribution domain: https://d1pvh6f3ahqkqz.cloudfront.net/
  • Name of WAF: fa-051-WebACL

The resources are also checked from the AWS Management Console.
First is CloudFront.

WAF Web ACLs are applied to CloudFront.

We can see that the CloudFront distribution has been created and AWS WAF has been applied.

Next, check the Web ACL.

WAF for CloudFront is created in the Global region.

The key point is that the Web ACL is created in the “Global (CloudFront)” region.
Note that it is not in us-east-1, where the CloudFormation stack was created.

WAF Web ACLs are applied to CloudFront.

From the Web ACL side, you can also see that this ACL is applied to CloudFront.

Checking action

Now that everything is ready, access CloudFront from Japan.

Access to CloudFront was blocked.

Access was denied.
Because you accessed from Japan, the WAF Web ACL filtered the access before it reached CloudFront.

To confirm, change the action of the geo-restriction.

WAF action changed from block to count.

We changed the rule action from blocking to counting, i.e., keeping the rule alive but only counting the number of traffic that corresponds to the rule.

Access CloudFront again.

CloudFront was accessible.

You can now access CloudFront.
This is because the rule action has been changed from block to count only, and access is now possible.

Summary

We have seen how to apply WAF ACLs to CloudFront.

TOC