この記事は公開されてから1年以上経過しています。情報が古い可能性がありますので、ご注意ください。
こんにちは、森田です。
本記事では、AWS WAFv2 のフィルタリング形式(ブラックリスト・ホワイトリスト)切り替えを CloudFormation を使って実現する方法をご紹介します。
やりたいこと
- 通常はブラックリスト形式でWAFを利用し、アプリケーションのメンテナンスに応じてホワイトリスト形式へ切り替える
- CloudFormationのパラメータを変えることでブラックリスト・ホワイトリスト形式へ切り替えを行う
今回実現するブラックリスト形式(Default Action = ALLOW)の WAF でのIPアドレス制限については以下の記事が参考となります。
CloudFormationテンプレート
waf.yml
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 の評価の動作を理解したい方はぜひ以下をご参照ください。
その他参考記事
芦沢さんの記事を多く参考にしております(ありがとうございます)