AWS CDKでWAF(WebACL)を定義する
概要
今回はAWS CDK
でAWS WAF
を設定する方法をまとめます。
AWS WAFとは
AWS WAF
はウェブリクエストの許可・ブロック・監視(カウント)を行うための機能です。
主にCloudFrontやALB、API Gatewayなどのサービスに設定して使用されることが多いです。
ルールについて
AWS WAF
では「特定のIPからのアクセスをブロックする」や「特定の地域からのアクセスをブロックする」といった通信を許可する・しないを定めたルールを組み合わせて使用します。
これはサードパーティが提供しているものもあれば、自作することも可能です。
また、AWSがプリセットとして提供してくれているマネージドルールというものもあります。
今回はマネージドルールを利用します。
使用するルール
今回は5つのマネージドルールを使用します。
ベースラインルールグループからAWSManagedRulesCommonRuleSet
とAWSManagedRulesAdminProtectionRuleSet
とAWSManagedRulesKnownBadInputsRuleSet
を。
IP評価ルールグループからAWSManagedRulesAmazonIpReputationList
とAWSManagedRulesAnonymousIpList
を使用します。
CDK
実際のコードは以下のようになります。
マネージドルールを使用する場合、その名前を設定する方式です。
overrideAction
というプロパティを用いることで、挙動をオーバライドすることが可能です。
import { Stack, StackProps } from 'aws-cdk-lib';
import { Construct } from 'constructs';
import * as wafv2 from 'aws-cdk-lib/aws-wafv2';
export class SampleStack extends Stack {
constructor(scope: Construct, id: string, props?: StackProps) {
super(scope, id, props);
const webAcl = new wafv2.CfnWebACL(this, 'SampleWebAcl', {
// デフォルトではすべてallowにする
defaultAction: {
allow: {}
},
// CloudFrontを対象とする場合は'CLOUDFRONT'それ以外は'REGIONAL'
scope: 'REGIONAL',
// メトリクス等の設定
visibilityConfig: {
cloudWatchMetricsEnabled: true,
metricName: 'SampleMetric',
sampledRequestsEnabled: true,
},
// WAFルール設定
rules: [
{
name: "AWSManagedRulesCommonRuleSet",
priority: 1,
statement: {
managedRuleGroupStatement: {
vendorName: "AWS",
name: "AWSManagedRulesCommonRuleSet",
},
},
// アクションの上書き設定
// overrideAction: { none: {} }とした場合は何も上書きしない=ルールの設定に従う
// overrideAction: { count: {} }とした場合はブロックせずに集計だけする
overrideAction: { none: {} },
visibilityConfig: {
cloudWatchMetricsEnabled: true,
sampledRequestsEnabled: true,
metricName: "AWSManagedRulesCommonRuleSet",
},
},
{
name: "AWSManagedRulesAdminProtectionRuleSet",
priority: 2,
statement: {
managedRuleGroupStatement: {
vendorName: "AWS",
name: "AWSManagedRulesAdminProtectionRuleSet",
},
},
overrideAction: { none: {} },
visibilityConfig: {
cloudWatchMetricsEnabled: true,
sampledRequestsEnabled: true,
metricName: "AWSManagedRulesAdminProtectionRuleSet",
},
},
{
name: "AWSManagedRulesKnownBadInputsRuleSet",
priority: 3,
statement: {
managedRuleGroupStatement: {
vendorName: "AWS",
name: "AWSManagedRulesKnownBadInputsRuleSet",
},
},
overrideAction: { none: {} },
visibilityConfig: {
cloudWatchMetricsEnabled: true,
sampledRequestsEnabled: true,
metricName: "AWSManagedRulesKnownBadInputsRuleSet",
},
},
{
name: "AWSManagedRulesAmazonIpReputationList",
priority: 4,
statement: {
managedRuleGroupStatement: {
vendorName: "AWS",
name: "AWSManagedRulesAmazonIpReputationList",
},
},
overrideAction: { none: {} },
visibilityConfig: {
cloudWatchMetricsEnabled: true,
sampledRequestsEnabled: true,
metricName: "AWSManagedRulesAmazonIpReputationList",
},
},
{
name: "AWSManagedRulesAnonymousIpList",
priority: 5,
statement: {
managedRuleGroupStatement: {
vendorName: "AWS",
name: "AWSManagedRulesAnonymousIpList",
},
},
overrideAction: { none: {} },
visibilityConfig: {
cloudWatchMetricsEnabled: true,
sampledRequestsEnabled: true,
metricName: "AWSManagedRulesAnonymousIpList",
},
},
],
});
// リソースとの紐付け
new wafv2.CfnWebACLAssociation(this, 'WafAssociation', {
resourceArn: "【ALBなどのリソースのARN】",
webAclArn: webAcl.attrArn
});
}
}
まとめ
ここまでの内容でWAFの設定自体はできると思います。
今回使ったのはマネージドルールですが、それをいきなり適用すると通常のリクエストにも関わらず思わぬ箇所がブロックされることがあるようです。
なので最初はCountモードで設定して、各種リクエストがルールに抵触していないかを監視しながら運用をスタートさせるのがおすすめです。
Discussion