AWS WAFv2をCDKで構築してみた

2020.03.31

CX事業部の太田です。

AWS初心者ですが、CDKを使ってWAFv2を作りましたので紹介いたします。

WAFの構築

まずは、@aws-cdk/aws-wafv2をインストールします。

npm install --save @aws-cdk/aws-wafv2

あとは、@aws-cdk/aws-wafv2.CfnWebACLを使って実装します。
CDKを使ったWAFv2のソースは以下です。

import * as cdk from "@aws-cdk/core";
import * as wafv2 from "@aws-cdk/aws-wafv2";

export class SampleWafStack extends cdk.Stack {
  constructor(scope: cdk.Construct, id: string, props?: cdk.StackProps) {
    super(scope, id, props);

    // WebACLを作成
    const webAcl = new wafv2.CfnWebACL(this, "SampleWafAcl", {
      defaultAction: { allow: {} },
      name: "sample-waf-web-acl",
      rules: [
        {
          priority: 1,
          overrideAction: { none: {} },
          visibilityConfig: {
            sampledRequestsEnabled: true,
            cloudWatchMetricsEnabled: true,
            metricName: "AWS-AWSManagedRulesSQLiRuleSet"
          },
          name: "AWS-AWSManagedRulesSQLiRuleSet",
          statement: {
            managedRuleGroupStatement: {
              vendorName: "AWS",
              name: "AWSManagedRulesSQLiRuleSet"
            }
          }
        }
      ],
      scope: "REGIONAL",
      visibilityConfig: {
        cloudWatchMetricsEnabled: true,
        metricName: "sample-waf-web-acl",
        sampledRequestsEnabled: true
      }
    });
  }
}

指定するパラメーターの詳細は以下のページで確認できます。
AWS::WAFv2::WebACL
AWS::WAFv2::WebACL Rule
WS::WAFv2::WebACL ManagedRuleGroupStatement

あとは、ビルドしてデプロイすればOK

$ npm run build
$ cdk deploy
SampleWafStack: deploying...
SampleWafStack: creating CloudFormation changeset...
 0/3 | 2:45:13 PM | CREATE_IN_PROGRESS   | AWS::WAFv2::WebACL | SampleWafAcl 
 0/3 | 2:45:13 PM | CREATE_IN_PROGRESS   | AWS::CDK::Metadata | CDKMetadata 
 0/3 | 2:45:15 PM | CREATE_IN_PROGRESS   | AWS::WAFv2::WebACL | SampleWafAcl Resource creation Initiated
 0/3 | 2:45:15 PM | CREATE_IN_PROGRESS   | AWS::CDK::Metadata | CDKMetadata Resource creation Initiated
 1/3 | 2:45:15 PM | CREATE_COMPLETE      | AWS::CDK::Metadata | CDKMetadata 
 2/3 | 2:45:15 PM | CREATE_COMPLETE      | AWS::WAFv2::WebACL | SampleWafAcl 
 3/3 | 2:45:17 PM | CREATE_COMPLETE      | AWS::CloudFormation::Stack | SampleWafStack 

 ✅  SampleWafStack

Stack ARN:
arn:aws:cloudformation:ap-northeast-1:123456789012:stack/SampleWafStack/12345678-1234-1234-1234-123456789012

AWSコンソールを見ると、WebACLができてました。

対応時にハマったところがあったので紹介します。

overrideAction

AWS::WAFv2::WebACL Ruleには、ルールに一致した場合の動作を決めるactionoverrideActionという2つのプロパティがあり、どちらかを指定する必要があります。
指定するルールに合わせて指定する必要があり、今回はmanagedRuleGroupStatementを使用しているのでoverrideActionを指定する必要があるのですが、最初はそれに気づかずactionを指定してしまってデプロイができませんでした。
どちらを指定するかはAWS::WAFv2::WebACL Ruleに記載されているので、単純に私の英語力の問題でしたが・・

vendorNameとname

WS::WAFv2::WebACL ManagedRuleGroupStatementには、適用するマネージドルールを特定するためにvendorNamenameを指定する必要があります。
AWSで提供されているマネージドルールはここを見るとわかるのですが、AWS Marketplaceで購入したものを使いたい場合に少し悩みました。

利用可能なマネージドルールはAWS CLIで取得できるので、あとは使いたいルールのvendorNamenameを利用すればOKです。

$ aws wafv2 list-available-managed-rule-groups --scope REGIONAL
{
    "ManagedRuleGroups": [
        {
            "Description": "Contains rules that allow you to block request patterns associated with exploitation of SQL databases, like SQL injection attacks. This can help prevent remote injection of unauthorized queries.", 
            "VendorName": "AWS", 
            "Name": "AWSManagedRulesSQLiRuleSet"
        }, 
        ... 省略
    ]
}

関連付け

WAFv2ALBAPI GatewayCloudFrontと関連付けて使うことになりますが、wafv2.CfnWebACLには設定するプロパティ等が用意されておらず出来ませんでした。
なので、今回はAWS CLIを使って関連付けを行いました。

aws wafv2 associate-web-acl \
 --web-acl-arn <WAFv2のARN> \
 --resource-arn <関連付けたいリソースのARN>

最後に

AWSを初めてまともに触りましたが、個人的にはコンソール上で操作するよるよりはCDKで構築できるのは敷居が下がった気がしました。
WAFv2もまだパブリックベータなので、今後のアップデートなどで関連付の部分などが便利になったりするといいなと思いました。

最後までご覧いただきありがとうございました。