CloudFormation で AWS WAF v2 に AWS Managed Rules を設定する

2020年5月9日

概要

やりたいこと

以前、CloudFormation を利用して AWS WAF v1 (classic) にルールを追加した。今回は CloudFormation を利用して AWS WAF v2 (new) にAWS Managed Rules on AWS WAF を設定する。

Terraform でやりたかったが、Terraform は現在 AWS WAF v2 に未対応。がんばって進行中のようだ。

AWS WAF v2

AWS WAF についてはこの資料が詳しい。

AWS WAF v2 と v1 で主な変更点は以下。今回はマネージドルールを利用するためメインとなるのはルール適用数のほう。

  • ルール適用数(10個 -> 1500WCU)
  • AND/OR/NOT によるルール(Statement)の組み合わせ

v1 では 10 個のルールまでしか適用できなかった。
v2 では個数ではなく重み付けした数値(キャパシティユニット)で制限し、その数は 1500WCU となる。

この値は結構ギリギリで、何も考えないで全ルール適用はできない(後述)。

AWS Managed Rules on AWS WAF

今回は下記で作った環境への防御を考える。

テストのために全てのルールを適用したかったが、合計 capacity が 1975WCU になり、上限の 1500WCU を超えてしまう。
そのため、サービスにあったルールを選別して適用する。

owasp-juice-shop を守ると仮定してルール選定を行う。合計キャパシティは 1475 でギリギリ。

  • Linux(EC2), Node.js で動作
  • DB は存在する
NoRulecapacity使用
1Admin protection100
2Amazon IP reputation list25
3Anonymous IP List50
4Core rule set700
5Known bad inputs200
6Linux operating system200
7PHP application100
8POSIX operating system100
9SQL database200
10Windows operating system200
11WordPress application100

CloudFormation でデプロイ

準備

こちらを参照し、 aws cloudformation コマンドを利用できるようにしておく。

作業ディレクトリと cloudformaion 用のテンプレートファイルを作成。

$ mkdir awswaf_v2
$ cd awswaf_v2
$ touch waf_v2.yaml

スタックを作成。

$ aws cloudformation create-stack --stack-name aws-waf-v2-test --region ap-northeast-1 --template-body file://waf_v2.yaml

AWS WAF v2 用の空の WebACL を作成

AWS::WAFv2::WebACL のサンプルを参考に、空の WebACL を作成。

ALB へアタッチ予定のため、Scope には REGIONAL を指定。

AWSTemplateFormatVersion: 2010-09-09
Description: Create WebACL example
Resources:
  ExampleWebACL:
    Type: AWS::WAFv2::WebACL
    Properties:
      Name: ExampleWebACL
      Scope: REGIONAL
      Description: This is an example WebACL
      DefaultAction:
        Allow: {}
      VisibilityConfig:
        SampledRequestsEnabled: true
        CloudWatchMetricsEnabled: true
        MetricName: ExampleWebACLMetric

構文チェックして問題ないことを確認。

$ aws cloudformation validate-template --template-body file://waf_v2.yaml
{
"Parameters": [],
"Description": "Create WebACL example"
}

反映する。

$ aws cloudformation deploy --stack-name aws-waf-v2-test --template-file waf_v2.yaml

Waiting for changeset to be created..
Waiting for stack create/update to complete
Successfully created/updated stack - web-acl-test

AWS WAF コンソールより Web ACL が作成されていることを確認。

AWS Managed Rules を追加

7 個分の AWS Managed Rules を追加する。
Priority は適当。

AWSTemplateFormatVersion: 2010-09-09
Description: Create WebACL example
Resources:
  ExampleWebACL:
    Type: AWS::WAFv2::WebACL
    Properties:
      Name: ExampleWebACL
      Scope: REGIONAL
      Description: This is an example WebACL
      DefaultAction:
        Allow: {}
      VisibilityConfig:
        SampledRequestsEnabled: true
        CloudWatchMetricsEnabled: true
        MetricName: ExampleWebACLMetric
        - Name: AWSManagedRulesCommonRuleSet
          Priority: 0
          OverrideAction:
            Count: {}
          VisibilityConfig:
            SampledRequestsEnabled: true
            CloudWatchMetricsEnabled: true
            MetricName: AWSManagedRulesCommonRuleSetMetric
          Statement:
            ManagedRuleGroupStatement:
              VendorName: AWS
              Name: AWSManagedRulesCommonRuleSet
              ExcludedRules: []
        - Name: AWSManagedRulesKnownBadInputsRuleSet
          Priority: 1
          OverrideAction:
            Count: {}
          VisibilityConfig:
            SampledRequestsEnabled: true
            CloudWatchMetricsEnabled: true
            MetricName: AWSManagedRulesKnownBadInputsRuleSetMetric
          Statement:
            ManagedRuleGroupStatement:
              VendorName: AWS
              Name: AWSManagedRulesKnownBadInputsRuleSet
              ExcludedRules: []
        - Name: AWSManagedRulesAmazonIpReputationList
          Priority: 2
          OverrideAction:
            Count: {}
          VisibilityConfig:
            SampledRequestsEnabled: true
            CloudWatchMetricsEnabled: true
            MetricName: AWSManagedRulesAmazonIpReputationListMetric
          Statement:
            ManagedRuleGroupStatement:
              VendorName: AWS
              Name: AWSManagedRulesAmazonIpReputationList
              ExcludedRules: []
        - Name: AWSManagedRulesAnonymousIpList
          Priority: 3
          OverrideAction:
            Count: {}
          VisibilityConfig:
            SampledRequestsEnabled: true
            CloudWatchMetricsEnabled: true
            MetricName: AWSManagedRulesAnonymousIpListMetric
          Statement:
            ManagedRuleGroupStatement:
              VendorName: AWS
              Name: AWSManagedRulesAnonymousIpList
              ExcludedRules: []
        - Name: AWSManagedRulesSQLiRuleSet
          Priority: 4
          OverrideAction:
            Count: {}
          VisibilityConfig:
            SampledRequestsEnabled: true
            CloudWatchMetricsEnabled: true
            MetricName: AWSManagedRulesSQLiRuleSetMetric
          Statement:
            ManagedRuleGroupStatement:
              VendorName: AWS
              Name: AWSManagedRulesSQLiRuleSet
              ExcludedRules: []
        - Name: AWSManagedRulesLinuxRuleSet
          Priority: 5
          OverrideAction:
            Count: {}
          VisibilityConfig:
            SampledRequestsEnabled: true
            CloudWatchMetricsEnabled: true
            MetricName: AWSManagedRulesLinuxRuleSetMetric
          Statement:
            ManagedRuleGroupStatement:
              VendorName: AWS
              Name: AWSManagedRulesLinuxRuleSet
              ExcludedRules: []
        - Name: AWSManagedRulesUnixRuleSet
          Priority: 6
          OverrideAction:
            Count: {}
          VisibilityConfig:
            SampledRequestsEnabled: true
            CloudWatchMetricsEnabled: true
            MetricName: AWSManagedRulesUnixRuleSetMetric
          Statement:
            ManagedRuleGroupStatement:
              VendorName: AWS
              Name: AWSManagedRulesUnixRuleSet

構文チェックで問題ないことを確認後、デプロイ。

$ aws cloudformation validate-template --template-body file://waf_v2.yaml
$ aws cloudformation deploy --stack-name aws-waf-v2-test --template-file waf_v2.yaml

Web ACL に 7個のルールが追加されていることを確認。

ALB にアタッチ

AWS::WAFv2::WebACLAssociation を利用する。

WebACL は同じ CloudFormation で管理しているが、ALB は Terraform で管理しているため ARN をベタ書きしている。。

WebACLAssociation:
  Type: AWS::WAFv2::WebACLAssociation
  Properties: 
    ResourceArn: "arn:aws:elasticloadbalancing:ap-northeast-1:657885203613:loadbalancer/app/webserver-alb/3c8d60490de0199e"
    WebACLArn: !GetAtt WebACL.Arn

ALB にアタッチされていることを確認。

ALB 側からも確認できる。

作ったリソースが不要な場合は削除しておく。

aws cloudformation delete-stack --stack-name aws-waf-v2-test

コードは github にアップしといた。

参考

AWS WAFを完全に理解する ~WAFの基礎からv2の変更点まで~

AWS Managed Rules for AWS WAF を構成するCloudFormationテンプレートを作ってみた