AWS WAF v2 ManagedRulesの個別設定をコード化してみた

初めまして。2020年にラボに入社したモチです。
いくつかAWSインフラを構築させて頂いたので、AWS WAFについてブログを書いてみます。
※ 当時使用していたslsの抜粋です。
背景
アプリケーションの仕様上、AWSManagedRulesの一部ルールだけブロックさせたくない、という要件が多々あります。
AWS CloudFormation(以下CFn)で設定する例があまりなく、AWSサポートにCLIかCFnで設定できますか?と聞いてみました。”AWS::WAFv2::WEbACL”では、ExcludedRulesを使用すると指定が可能とのこと。
公式ガイドにもちゃんと書いてありました。
基本はブロックで、一部ルールだけカウントに変更することができます。
“
https://docs.aws.amazon.com/ja_jp/AWSCloudFormation/latest/UserGuide/aws-properties-wafv2-webacl-managedrulegroupstatement.html#cfn-wafv2-webacl-managedrulegroupstatement-excludedrulesExcludedRules
The rules whose actions are set toCOUNT
by the web ACL, regardless of the action that is configured in the rule. This effectively excludes the rule from acting on web requests. “
やりたいこと
AWSManagedRulesCommonRuleSetを基本ブロック、SizeRestrictions_BODYのみをカウントにしたい。
↓こうしたい

CloudFormationで書いてみる
ManagedRuleGroupStatementのExcludedRulesで設定します。
WAFv2RuleWithAWSManagedRules:
Type: AWS::WAFv2::WebACL
Properties:
Name: WAFv2_WebACL
Scope: REGIONAL
Description: This is a WAFv2 WebACL
DefaultAction:
Allow: {}
VisibilityConfig:
CloudWatchMetricsEnabled: true
SampledRequestsEnabled: true
MetricName: WAFv2_WebACLMetric
Rules:
- Name: AWS-AWSManagedRulesCommonRuleSet
Priority: 0
Statement:
ManagedRuleGroupStatement:
VendorName: AWS
Name: AWSManagedRulesCommonRuleSet
ExcludedRules:
- SizeRestrictions_BODY
OverrideAction:
None: {}
VisibilityConfig:
CloudWatchMetricsEnabled: true
SampledRequestsEnabled: true
MetricName: AWSManagedRulesCommonRuleSet
簡単にできちゃいました!
ついでにScopeDownStatementも試してみる①
特定のパス(以下の例は/admin)を許可する場合
※ ②では複数パスの指定方法をご紹介します
WAFv2RuleWithAWSManagedRules:
Type: AWS::WAFv2::WebACL
Properties:
Name: WAFv2_WebACL
Scope: REGIONAL
Description: This is a WAFv2 WebACL
DefaultAction:
Allow: {}
VisibilityConfig:
CloudWatchMetricsEnabled: true
SampledRequestsEnabled: true
MetricName: WAFv2_WebACLMetric
Rules:
- Name: AWS-AWSManagedRulesCommonRuleSet
Priority: 0
Statement:
ManagedRuleGroupStatement:
VendorName: AWS
Name: AWSManagedRulesCommonRuleSet
ExcludedRules:
- SizeRestrictions_BODY
ScopeDownStatement:
NotStatement:
Statement:
ByteMatchStatement:
FieldToMatch:
UriPath: {}
PositionalConstraint: STARTS_WITH
SearchString: "/admin/"
TextTransformations:
- Priority: 0
Type: NONE
OverrideAction:
None: {}
VisibilityConfig:
CloudWatchMetricsEnabled: true
SampledRequestsEnabled: true
MetricName: AWSManagedRulesCommonRuleSet
これもできました!
※ この設定はルールの編集画面でしか見れないようです

ついでにScopeDownStatementも試してみる②
上記設定後に、許可したいパスが増えました。
、、が、上記画面の通り、①の設定方法だとパスを1つしか指定できません。困った。
そこでまたAWSサポートに問い合わせてみたところ、ラベルを使用すれば実現できるとのこと。
さすがAWSさん、拡張性を考えてくれていました。
タグではなくラベルなんですね。
/admin及び/testを許可する場合、
- /adminをカウントするRuleを作成、ラベルを付与
- /testをカウントするRuleを作成、adminと同じラベルを付与
- AWSManagedRulesCommonRuleSetでこのラベルを許可するよう設定
WAFv2RuleWithAWSManagedRules:
Type: AWS::WAFv2::WebACL
Properties:
Name: WAFv2_WebACL
Scope: REGIONAL
Description: This is a WAFv2 WebACL
DefaultAction:
Allow: {}
VisibilityConfig:
CloudWatchMetricsEnabled: true
SampledRequestsEnabled: true
MetricName: WAFv2_WebACLMetric
Rules:
# /admin/配下を対象外とする
- Name: admin-Exclusion
Priority: 0
Statement:
NotStatement:
Statement:
ByteMatchStatement:
FieldToMatch:
UriPath: {}
PositionalConstraint: STARTS_WITH
SearchString: "/admin/"
TextTransformations:
- Priority: 0
Type: NONE
Action:
Count: {}
VisibilityConfig:
CloudWatchMetricsEnabled: false
SampledRequestsEnabled: false
MetricName: adminExclusion
RuleLabels:
- Name: Exclusion
# /test/配下を対象外とする
- Name: compound-Exclusion
Priority: 1
Statement:
NotStatement:
Statement:
ByteMatchStatement:
FieldToMatch:
UriPath: {}
PositionalConstraint: STARTS_WITH
SearchString: "/test/"
TextTransformations:
- Priority: 0
Type: NONE
Action:
Count: {}
VisibilityConfig:
CloudWatchMetricsEnabled: false
SampledRequestsEnabled: false
MetricName: compoundExclusion
RuleLabels:
- Name: Exclusion
# AWSManagedRulesCommonRuleSet
- Name: AWS-AWSManagedRulesCommonRuleSet
Priority: 100
Statement:
ManagedRuleGroupStatement:
VendorName: AWS
Name: AWSManagedRulesCommonRuleSet
ExcludedRules:
- SizeRestrictions_BODY
ScopeDownStatement:
NotStatement:
Statement:
LabelMatchStatement:
Scope: LABEL
Key: Exclusion
OverrideAction:
None: {}
VisibilityConfig:
CloudWatchMetricsEnabled: false
SampledRequestsEnabled: true
MetricName: AWSManagedRulesCommonRuleSet
これもできました!
同じことで悩んでいる方のお力になれますように!