ALB 用 AWS WAF v1 (Classic) に CloudFormation でルール適用

2020年5月3日

概要

やりたいこと

  • AWS WAF を CloudFormation から適用したい
  • AWS WAF は ALB に紐付ける
  • AWS WAF は Classic (v1) を利用する;;

CloudFormation 概要

CloudFormation は JSON/YAML 形式のテキストから AWS 上にリソースを展開・更新・削除ができる。

手順は以下

  1. CloudFormation Template を作成し
  2. aws cli から CloudFormation Template をデプロイ
  3. GUI から確認

CloudFormation Template 概要

CloudFormation Template は、下記のようにいくつかのセッションに分かれています。

CloudFormation Template の形式。

AWSTemplateFormatVersion: '2010-09-09'
Resources:
  FirstVPC:
    Type: AWS::EC2::VPC
    Properties:
      CidrBlock: 10.0.0.0/16

各用語は AWS CloudFormation テンプレートの用語を参照。

  • AWSTemplateFormatVersion : テンプレートの形式を指定、現在は2010-09-09のみ利用可能
  • Resources : テンプレートにおいて唯一必須のセッション。スタックに含める、VPCやEC2インスタンスやS3バケットなどのリソースを宣言

Resources の形式。

Resources:
  Logical ID
  Type: Resource type
    Properties:
    Set of properties...

用語は公式のResourcesの用語を参照。

  • Logical ID : テンプレート内で一意なID。テンプレートの中で、他のリソースを参照する場合などは、このIDを利用
  • Resource type : 実際に作成するリソースのタイプ。AWS リソースプロパティタイプのリファレンス参照
  • Resource properties : 各リソースの作成時に指定するプロパティです。リソースタイプによって利用できるプロパティは異なる

Resource type 識別子の形式は下記。

service-provider::service-name::data-type-name

CloudFormation WAF Template 概要

CloudFormation の AWS WAF のリソースタイプは 3種類ある。
AWS WAF の紐付け先リソースが Regional かどうかと、バージョンが異なるため。

  • AWS::WAF  ->  CloudFront (Regionなし)
  • AWS::WAFRegional  ->  ALB, API Gateway (Regionあり)
  • AWS::WAFv2 -> AWS WAF v2

今回は ALB に紐付けた AWS WAF に適用するため、 AWS::WAFResional を利用する。

補足として、AWS WAF の CloudFormation用テンプレートは、公式サイトで提供されている。
ALB 用と CloudFront 用で記述が違うための2種類のテンプレートがネストされたテンプレートなので、必要な部分だけ切り出してデプロイする必要がある。

実践

準備

aws cloudformation コマンドを利用するため、 こちらを参照し aws cli を使えるようにしておく。

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

$ mkdir awswaf_v1
$ cd awswaf_v1
$ touch create_waf_v1_rate.yaml

スタックを作成。

$ aws cloudformation create-stack --stack-name web-acl-test --region ap-northeast-1 --template-body file://create_waf_v1_rate.yaml

空の AWS WAF ACL を作成

空の AWS WAF ACL を作成する。
“AWS::WAFRegional::WebACL” を利用する。

vi create_waf_v1_rate.yaml
AWSTemplateFormatVersion: "2010-09-09"
Resources:
  MyWebACL:
    Type: "AWS::WAFRegional::WebACL"
    Properties:
      Name: "MyWebACL"
      MetricName: "MyWebACL"
      DefaultAction:
        Type: "ALLOW"

デプロイ前にバリデーションで構文を確認。

$ aws cloudformation validate-template --template-body file://create_waf_v1_rate.yaml
{
"Parameters": []
}

デプロイする。Sucessfully と出れば成功。

$ aws cloudformation deploy --stack-name web-acl-test --template-file create_waf_v1_rate.yaml

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

スタックに作成されていることを確認。

AWS WAF Classic コンソールから WebACL が作成されていることを確認できた。

AWS WAF ACL にルールを追加

ACL にIP制限を行うルールを追加する。
“AWS::WAFRegional::Rule”“AWS::WAFRegional::IPSet” を利用する。
“AWS::WAFRegional::WebACL” に Rules プロパティも追加している。

vi create_waf_v1_rate.yaml
AWSTemplateFormatVersion: "2010-09-09"
Resources:
  MyWebACL:
    Type: "AWS::WAFRegional::WebACL"
    Properties:
      Name: "MyWebACL"
      MetricName: "MyWebACL"
      DefaultAction:
        Type: "ALLOW"
      Rules:
        - Action:
            Type: "COUNT"
          Priority: 1
          RuleId: 
            Ref: "MyIPSetRule"
  MyIPSetRule:
    Type: "AWS::WAFRegional::Rule"
    Properties:
      Name: "MyIPSetRule"
      MetricName: "MyIPSetRule"
      Predicates:
        -
          DataId:
            Ref: "MyIPSetBlacklist"
          Negated: false
          Type: IPMatch
  MyIPSetBlacklist: 
    Type: "AWS::WAFRegional::IPSet"
    Properties: 
      Name: "IPSet for blacklisted IP adresses"
      IPSetDescriptors: 
        - 
          Type: "IPV4"
          Value: "192.0.2.44/32"
        - 
          Type: "IPV4"
          Value: "192.0.7.0/24

バリデーション後にデプロイし、GUI上でルール(MyIPSetRule)が作成されていることを確認。

MyIPSetRule 内にはブラックリスト IP が設定されている。

ACL を ALB に紐付ける

最後に、作成した ACL と ALB を紐付ける。
AWS::WAFRegional::WebACLAssociation” を利用する。

MyWebACLAssociation:
  Type: "AWS::WAFRegional::WebACLAssociation"
  Properties:
    ResourceArn:
      Ref: MyLoadBalancerArn
    WebACLId:
      Ref: MyWebACL

検証が終わりリソースが不要になったら削除しておく。

aws cloudformation delete-stack --stack-name web-acl-test

参考

AWS WAF セキュリティオートメーション

CloudFormationからのWAFの設定(CloudFront/APIGateway)

【CloudFormation入門】5分と6行で始めるAWS CloudFormationテンプレートによるインフラ構築