WAF Web ACLをCloudFrontに適用する
AWS WAFは以下の4種類のリソースに適用することができます。
- ALB
- CloudFront
- API Gateway
- AppSync
今回はCloudFrontに適用する方法を確認します。
なおWAFをALBに適用する方法については、以下のページをご確認ください。
WAFをAPI Gatewayに適用する方法については、以下のページをご確認ください。
WAFをAppSyncに適用する方法については、以下のページをご確認ください。
構築する環境
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の基本的な事項については、以下のページをご確認ください。
WAFで地理制限する方法については、以下のページをご確認ください。
CloudFrontのオリジンにS3バケットを指定し、OAIを使用する方法については、以下のページをご確認ください。
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スタックを作成します。
スタックの作成および各スタックの確認方法については、以下のページをご確認ください。
今回はスタックを作成するリージョンに気をつけてください。
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です。
CloudFrontディストリビューションが作成され、AWS WAFが適用されていることがわかります。
次にWeb ACLを確認します。
Web ACLが「Global(CloudFront)」のリージョンに作成されている点がポイントです。
CloudFormationスタックを作成したus-east-1ではありませんのでご注意ください。
Web ACL側からも、このACLがCloudFrontに適用されていることがわかります。
動作確認
準備が整いましたので、日本からCloudFrontにアクセスします。
アクセスが拒否されました。
日本からアクセスしたため、CloudFrontに到達する前に、WAF Web ACLによってフィルタリングされたということです。
確認のために、地理制限のアクションを変更します。
ルールのアクションをブロックからカウント、つまりルールは生かしつつ、ルールに該当するトラフィック数を数えるだけに変更しました。
改めてCloudFrontにアクセスします。
CloudFrontにアクセスできるようになりました。
ルールのアクションがブロックからカウントだけになり、アクセスが可能になったためです。
まとめ
WAF ACLをCloudFrontに適用する方法を確認しました。