CloudFormation のパラメータに応じて AWS WAF のフィルタリング形式切り替えを実現させる
こんにちは、森田です。
本記事では、AWS WAFv2 のフィルタリング形式(ブラックリスト・ホワイトリスト)切り替えを CloudFormation を使って実現する方法をご紹介します。
やりたいこと
- 通常はブラックリスト形式でWAFを利用し、アプリケーションのメンテナンスに応じてホワイトリスト形式へ切り替える
- CloudFormationのパラメータを変えることでブラックリスト・ホワイトリスト形式へ切り替えを行う
今回実現するブラックリスト形式(Default Action = ALLOW)の WAF でのIPアドレス制限については以下の記事が参考となります。
CloudFormationテンプレート
AWSTemplateFormatVersion: '2010-09-09' Parameters: Prefix: Type: String Default: sample Description: "Fill in the name of the system name." Env: Type: String Default: dev Description: "Fill in the name of the environment." Scope: Type: String Default: REGIONAL AllowedValues: ["REGIONAL", "CLOUDFRONT"] Description: "Fill in the scope of waf" WebAclAssociationResourceArn: Type: String Default: "arn:aws:elasticloadbalancing:ap-northeast-1:XXXXXXXXXXXX:loadbalancer/app/XXXXXXXXXXXX" Description: Enter RegionalResource(ALB,APIGateway,AppSync) ARN or CloudFront ARN to associate with WEBACL. MaintenanceMode: Type: String AllowedValues: ["on", "off"] BlackListIP: Description: IP list to deny access. Type: CommaDelimitedList WhiteListIP: Description: IP list to allow access. Type: CommaDelimitedList Conditions: Maintenance: !Equals ["on", !Ref MaintenanceMode] Resources: # ------------------------------------------------------------# # WAF v2 # ------------------------------------------------------------# WebAcl: Type: AWS::WAFv2::WebACL Properties: Name: !Sub ${Env}-${Prefix}-web-acl Scope: !Ref Scope DefaultAction: Allow: {} CustomResponseBodies: CustomResponseBody: Content: "<h1>Blocked!!</h1>" ContentType: "TEXT_HTML" VisibilityConfig: CloudWatchMetricsEnabled: true SampledRequestsEnabled: true MetricName: !Sub ${Env}-${Prefix}-web-acl Rules: # ------------------------------------------------------------# # MaintenanceMode OFF Rule # ------------------------------------------------------------# - Name: Blacklist-Rule Action: Block: CustomResponse: ResponseCode: 403 CustomResponseBodyKey: CustomResponseBody Priority: 1 Statement: IPSetReferenceStatement: Arn: !GetAtt WAFv2BlackIPSet.Arn VisibilityConfig: CloudWatchMetricsEnabled: false MetricName: !Sub ${Env}-${Prefix}-All-Allow SampledRequestsEnabled: false # ------------------------------------------------------------# # MaintenanceMode ON Rule # ------------------------------------------------------------# - !If - Maintenance - Name: Whitelist-Rule Action: Block: CustomResponse: ResponseCode: 403 CustomResponseBodyKey: CustomResponseBody Priority: 0 Statement: NotStatement: Statement: IPSetReferenceStatement: Arn: !GetAtt WAFv2WhiteIPSet.Arn VisibilityConfig: CloudWatchMetricsEnabled: false MetricName: !Sub ${Env}-${Prefix}-Whitelist SampledRequestsEnabled: false - Ref: AWS::NoValue WebACLAssociation: Type: AWS::WAFv2::WebACLAssociation Properties: ResourceArn: !Ref WebAclAssociationResourceArn WebACLArn: !GetAtt WebAcl.Arn WAFv2WhiteIPSet: Type: "AWS::WAFv2::IPSet" Properties: Addresses: !Ref WhiteListIP IPAddressVersion: IPV4 Name: !Sub ${Env}-${Prefix}-whitelist-ips Scope: !Ref Scope WAFv2BlackIPSet: Type: "AWS::WAFv2::IPSet" Properties: Addresses: !Ref BlackListIP IPAddressVersion: IPV4 Name: !Sub ${Env}-${Prefix}-blacklist-ips Scope: !Ref Scope
このテンプレートのポイントとしては、76~94行目にて入力されたパラメータに応じてホワイトリスト形式のルールの作成を行います。
まず、入力されたMaintenanceModeのパラメータがonの場合は、ホワイトリストのルールがPriority: 0(最大の優先度)で作成されることになり、ホワイトリスト形式の振る舞いをするWAFとなります。
(ホワイトリストのルールが最優先して評価され、他のルールは評価されません。)
一方で、MaintenanceModeのパラメータがoffの場合は、58~72行目のルールが適用され、ブラックリスト形式の振る舞いをするWAFとなります。
(条件関数で AWS::NoValue
が選択されることになり、ホワイトリストのルール作成されません。)
なお、MaintenanceModeのパラメータがoffの場合でルールの追加を行う場合が、ホワイトリストのルールでPriority: 0が使用されるため、それ以外のPriorityで指定する必要があります。
WAF の評価の動作を理解したい方はぜひ以下をご参照ください。
その他参考記事
芦沢さんの記事を多く参考にしております(ありがとうございます)