WAF Web ACLをCloudFrontに適用する

WAF Web ACLをCloudFrontに適用する

WAF Web ACLをCloudFrontに適用する

AWS WAFは以下の4種類のリソースに適用することができます。

  • ALB
  • CloudFront
  • API Gateway
  • AppSync

今回はCloudFrontに適用する方法を確認します。

なおWAFをALBに適用する方法については、以下のページをご確認ください。

あわせて読みたい
CFNでWAF Web ACL入門 – ALB向け 【CloudFormationを使用してWAF Web ACLを作成する】 AWS WAF(Web Application Firewall)はAWSが提供するセキュリティサービスです。WAFはいくつかのサービスで構成され...

WAFをAPI Gatewayに適用する方法については、以下のページをご確認ください。

あわせて読みたい
WAF Web ACLをAPI Gatewayに適用する 【WAF Web ACLをAPI Gatewayに適用する】 AWS WAFは以下の4種類のリソースに適用することができます。 ALB CloudFront API Gateway AppSync 今回はAPI Gatewayに適用す...

WAFをAppSyncに適用する方法については、以下のページをご確認ください。

あわせて読みたい
WAF Web ACLをAppSyncに適用する 【WAF Web ACLをAppSyncに適用する】 AWS WAFは以下の4種類のリソースに適用することができます。 ALB CloudFront API Gateway AppSync 今回はAppSyncに適用する方法を...

構築する環境

Diagram of applying WAF Web ACL to CloudFront.

WAF Web ACLを作成します。
地理制限を行います。
具体的にはルールグループを自作し、その中に日本(JP)からのアクセスをブロックするルールを設定します。
作成したWeb ACLをCloudFrontに適用します。

CloudFrontディストリビューションを作成します。
オリジンにS3バケットを指定します。
CloudFrontにOAIを作成し、S3バケットポリシーでOAIからのアクセスのみを許可する制限を行います。

Lambda関数を作成します。
この関数をCloudFormationカスタムリソースとして設定します。
この関数の働きですが、スタック生成・削除時に、自動的にバケットにオブジェクト生成・削除を実行するように設定します。
生成するオブジェクトは静的ウェブサイトホスティング用のindex.htmlとします。
関数のランタイムはPython3.8とします。

CloudFormationテンプレートファイル

上記の構成をCloudFormationで構築します。
以下のURLにCloudFormationテンプレートを配置しています。

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

テンプレートファイルのポイント解説

本ページでは、CloudFrontにWAFを適用する方法を中心に取り上げます。

WAFの基本的な事項については、以下のページをご確認ください。

あわせて読みたい
CFNでWAF Web ACL入門 – ALB向け 【CloudFormationを使用してWAF Web ACLを作成する】 AWS WAF(Web Application Firewall)はAWSが提供するセキュリティサービスです。WAFはいくつかのサービスで構成され...

WAFで地理制限する方法については、以下のページをご確認ください。

あわせて読みたい
WAF Web ACLで地理制限 【WAF Web ACLのルールグループを自作して地理制限する】 WAF Web ACLでは様々な条件でルールを設定することができます。今回は地理制限に関するルールグループを自作し...

CloudFrontのオリジンにS3バケットを指定し、OAIを使用する方法については、以下のページをご確認ください。

あわせて読みたい
OAIを使用してCloudFront経由でS3コンテンツを配信する 【CloudFrontからS3コンテンツを配信する際に、OAIでオリジンへのアクセスを制限する】 以下のページで、S3バケットのコンテンツをCloudFrontから配信する際に、Referer...

CloudFormationのカスタムリソースについては、以下のページをご確認ください。

あわせて読みたい
CFNカスタムリソースでS3オブジェクトを作成・削除する 【CloudFormationカスタムリソースを使って、スタック生成/削除時にS3オブジェクトを作成/削除する方法】 CloudFormationカスタムリソースはスタック操作(作成、更新、...

CloudFrontに適用するWAFを作成するリージョン

CloudFrontにWAFを適用する際に、最初に気をつけるべきポイントはWAFを作成するリージョンです。

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

AWS::WAFv2::WebACL

上記の通り、CloudFrontにWAFを適用する場合は、リージョンに制限がありますのでご注意ください。

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)

Web ACLとACL用のルールグループを定義し、地理制限を設定します。
ポイントは両リソースのScopeプロパティです。
このプロパティの設定方法については、以下の通りに説明されています。

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

今回はCloudFrontにWAFを適用しますので、本プロパティに「CLOUDFRONT」を設定します。

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)

ポイントはWebACLIdプロパティです。
このプロパティに先述のWAFのARNを指定します。

ALBに対してWAFを適用する際は、AWS::WAFv2::WebACLAssociationリソースを作成し、これに両者のARNを指定する方法で関連付けました。
以下の引用の通り、CloudFrontの場合はこのリソースは使用しませんのでご注意ください。

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

環境構築

CloudFormationを使用して、本環境を構築し、実際の挙動を確認します。

CloudFormationスタックを作成し、スタック内のリソースを確認する

CloudFormationスタックを作成します。
スタックの作成および各スタックの確認方法については、以下のページをご確認ください。

あわせて読みたい
CloudFormationのネストされたスタックで環境を構築する 【CloudFormationのネストされたスタックで環境を構築する方法】 CloudFormationにおけるネストされたスタックを検証します。 CloudFormationでは、スタックをネストす...

今回はスタックを作成するリージョンに気をつけてください。
AWS CLIでスタックを作成する場合、以下で示したコマンドの通り、regionオプションでus-east-1リージョンを指定してください。

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)

各スタックのリソースを確認した結果、今回作成された主要リソースの情報は以下の通りです。

  • S3バケット:fa-051
  • CloudFrontディストリビューションのドメイン:https://d1pvh6f3ahqkqz.cloudfront.net/
  • WAFの名前:fa-051-WebACL

AWS Management Consoleからもリソースを確認します。
まずCloudFrontです。

WAF Web ACLs are applied to CloudFront.

CloudFrontディストリビューションが作成され、AWS WAFが適用されていることがわかります。

次にWeb ACLを確認します。

WAF for CloudFront is created in the Global region.

Web ACLが「Global(CloudFront)」のリージョンに作成されている点がポイントです。
CloudFormationスタックを作成したus-east-1ではありませんのでご注意ください。

WAF Web ACLs are applied to CloudFront.

Web ACL側からも、このACLがCloudFrontに適用されていることがわかります。

動作確認

準備が整いましたので、日本からCloudFrontにアクセスします。

Access to CloudFront was blocked.

アクセスが拒否されました。
日本からアクセスしたため、CloudFrontに到達する前に、WAF Web ACLによってフィルタリングされたということです。

確認のために、地理制限のアクションを変更します。

WAF action changed from block to count.

ルールのアクションをブロックからカウント、つまりルールは生かしつつ、ルールに該当するトラフィック数を数えるだけに変更しました。

改めてCloudFrontにアクセスします。

CloudFront was accessible.

CloudFrontにアクセスできるようになりました。
ルールのアクションがブロックからカウントだけになり、アクセスが可能になったためです。

まとめ

WAF ACLをCloudFrontに適用する方法を確認しました。