WAF Web ACLをAPI Gatewayに適用する

WAF Web ACLをAPI Gatewayに適用する

WAF Web ACLをAPI Gatewayに適用する

AWS WAFは以下の4種類のリソースに適用することができます。

  • ALB
  • CloudFront
  • API Gateway
  • AppSync

今回はAPI Gatewayに適用する方法を確認します。

なおWAFをALBに適用する方法については、以下のページをご確認ください。

あわせて読みたい
CFNでWAF Web ACL入門 – ALB向け 【CloudFormationを使用してWAF Web ACLを作成する】 AWS WAF(Web Application Firewall)はAWSが提供するセキュリティサービスです。WAFはいくつかのサービスで構成され...

WAFをCloudFrontに適用する方法については、以下のページをご確認ください。

あわせて読みたい
WAF Web ACLをCloudFrontに適用する 【WAF Web ACLをCloudFrontに適用する】 AWS WAFは以下の4種類のリソースに適用することができます。 ALB CloudFront API Gateway AppSync 今回はCloudFrontに適用する...

WAFをAppSyncに適用する方法については、以下のページをご確認ください。

あわせて読みたい
WAF Web ACLをAppSyncに適用する 【WAF Web ACLをAppSyncに適用する】 AWS WAFは以下の4種類のリソースに適用することができます。 ALB CloudFront API Gateway AppSync 今回はAppSyncに適用する方法を...

構築する環境

Diagram of apply WAF Web ACL to API Gateway

WAF Web ACLを作成します。
地理制限を行います。
具体的にはルールグループを自作し、その中に日本(JP)からのアクセスをブロックするルールを設定します。
作成したWeb ACLをAPI Gatewayに適用します。

API Gatewayを作成し、バックエンドにLambdaを配置します。
ユーザからHTTPリクエストを受けた場合、API Gatewayがエンドポイントとなって、代わりにLambda関数を呼び出し、同関数の実行結果をユーザに返すというシンプルな構成です。
API GatewayはREST APIタイプで作成します。

Lambda関数のランタイム環境はPython3.8とします。
関数の動作ですが、実行すると「Hello form Awstut !」という文字列を返すという単純な内容とします。

CloudFormationテンプレートファイル

上記の構成をCloudFormationで構築します。
以下のURLにCloudFormationテンプレートを配置しています。

https://github.com/awstut-an-r/awstut-fa/tree/main/053

テンプレートファイルのポイント解説

本ページでは、CloudFrontにWAFを適用する方法を中心に取り上げます。

WAFの基本的な事項については、以下のページをご確認ください。

あわせて読みたい
CFNでWAF Web ACL入門 – ALB向け 【CloudFormationを使用してWAF Web ACLを作成する】 AWS WAF(Web Application Firewall)はAWSが提供するセキュリティサービスです。WAFはいくつかのサービスで構成され...

WAFで地理制限する方法については、以下のページをご確認ください。

あわせて読みたい
WAF Web ACLで地理制限 【WAF Web ACLのルールグループを自作して地理制限する】 WAF Web ACLでは様々な条件でルールを設定することができます。今回は地理制限に関するルールグループを自作し...

REST APIタイプのAPI Gatewayに関する基本的な事項については、以下のページをご確認ください。

あわせて読みたい
CFNを使ってREST APIタイプのAPI Gatewayを構築 【CloudFormationを使ってREST APIタイプのAPI Gatewayを構築】 以下のページで、HTTP APIタイプのAPI Gatewayについて取り上げました。 https://awstut.com/2021/12/03...

(参考)REST APIタイプのAPI Gatewayリソース

以下のAWS公式サイトで言及されている通り、WAFを適用できるAPI GatewayのタイプはREST APIタイプです。

https://docs.aws.amazon.com/ja_jp/apigateway/latest/developerguide/http-api-vs-rest.html

Resources:
  RestApi:
    Type: AWS::ApiGateway::RestApi
    Properties:
      EndpointConfiguration:
        Types:
          - EDGE
      Name: !Ref Prefix

  Deployment:
    Type: AWS::ApiGateway::Deployment
    DependsOn:
      - Method
    Properties:
      RestApiId: !Ref RestApi

  Resource:
    Type: AWS::ApiGateway::Resource
    Properties:
      ParentId: !GetAtt RestApi.RootResourceId
      PathPart: !Sub "${Prefix}-resource"
      RestApiId: !Ref RestApi

  Stage:
    Type: AWS::ApiGateway::Stage
    Properties:
      DeploymentId: !Ref Deployment
      RestApiId: !Ref RestApi
      StageName: !Sub "${Prefix}-stage"

  Method:
    Type: AWS::ApiGateway::Method
    Properties:
      AuthorizationType: NONE
      HttpMethod: GET
      Integration:
        ConnectionType: INTERNET
        Credentials: !GetAtt ApiGatewayRole.Arn
        IntegrationHttpMethod: POST
        Type: AWS_PROXY
        Uri: !Sub "arn:aws:apigateway:${AWS::Region}:lambda:path/2015-03-31/functions/${FunctionArn}/invocations"
      ResourceId: !Ref Resource
      RestApiId: !Ref RestApi
Code language: YAML (yaml)

特別な設定は不要です。
リソースの定義において、URLのPATHの一部を「fa-053-resource」と設定します。
ステージの定義において、ステージ名を「fa-053-stage」と設定します。

Web ACL

Resources:
  WebACL:
    Type: AWS::WAFv2::WebACL
    Properties:
      DefaultAction:
        Allow: {}
      Name: !Sub "${Prefix}-WebACL"
      Rules:
        - Name: !Sub "${Prefix}-WebACL-GeoRestriction"
          OverrideAction:
            None: {}
          Priority: 0
          Statement:
            RuleGroupReferenceStatement:
              Arn: !GetAtt RuleGroup.Arn
          VisibilityConfig:
            CloudWatchMetricsEnabled: true
            MetricName: !Sub "${Prefix}-WebACL-GeoRestriction"
            SampledRequestsEnabled: true
      Scope: REGIONAL
      VisibilityConfig:
        CloudWatchMetricsEnabled: true
        MetricName: !Ref Prefix
        SampledRequestsEnabled: true
Code language: YAML (yaml)

Scopeプロパティがポイントです。
Web ACLをCloudFrontに適用する場合は「CLOUDFRONT」、それ以外のリソースの場合は「REGIONAL」となります。
今回はAPI Gatewayですから後者となります。

Resources:
  WebACLAssociation:
    Type: AWS::WAFv2::WebACLAssociation
    Properties:
      ResourceArn: !Sub "arn:aws:apigateway:${AWS::Region}::/restapis/${RestApi}/stages/${StageName}"
      WebACLArn: !GetAtt WebACL.Arn
Code language: YAML (yaml)

API GatewayにWAFを適用するためのリソースです。
ResourceArnプロパティで、WAFを適用するAPI Gatewayを指定します。
指定方法は以下のように説明されています。

For an Amazon API Gateway REST API: arn:aws:apigateway:region::/restapis/api-id/stages/stage-name

AWS::WAFv2::WebACLAssociation

ですから上記の要件を満たすために、組み込み関数Fn::Subを使用して、APIのIDとステージ名を埋め込んで設定します。

環境構築

CloudFormationを使用して、本環境を構築し、実際の挙動を確認します。

CloudFormationスタックを作成し、スタック内のリソースを確認する

CloudFormationスタックを作成します。
スタックの作成および各スタックの確認方法については、以下のページをご確認ください。

あわせて読みたい
CloudFormationのネストされたスタックで環境を構築する 【CloudFormationのネストされたスタックで環境を構築する方法】 CloudFormationにおけるネストされたスタックを検証します。 CloudFormationでは、スタックをネストす...

各スタックのリソースを確認した結果、今回作成された主要リソースの情報は以下の通りです。

  • API Gatewayの名前:fa-053
  • API Gatewayのエンドポイント:https://dv68zdrmge.execute-api.ap-northeast-1.amazonaws.com/
  • API Gatewayのステージ名:fa-053-stage
  • API Gatewayのリソース名:fa-053-resource
  • WAFの名前:fa-053-WebACL

AWS Management Consoleからもリソースを確認します。
まずAPI Gatewayを確認します。

The Detail of API Gateway.

ステージのページを見えると、WAFが適用されていることがわかります。

次にWeb ACLを確認します。

The detail of WAF Web ACL.

Web ACL側からも、このACLがAPI Gatewayに適用されていることがわかります。

動作確認

準備が整いましたので、日本からCloudFrontにアクセスします。
今回アクセスするべきURLは、リソースとステージの情報を組み合わせて定まります。
具体的には以下のURLとなります。

https://dv68zdrmge.execute-api.ap-northeast-1.amazonaws.com/fa-053-stage/fa-053-resource/

Access to API Gateway was blocked by the WAF Web ACL.

アクセスが拒否されました。
日本からアクセスしたため、API Gatewayに到達する前に、WAF Web ACLによってブロックされたということです。

確認のために、地理制限のアクションを変更します。

Changed WAF Web ACL rules from blocking to counting.

ルールのアクションをブロックからカウント、つまりルールは生かしつつ、ルールに該当するトラフィック数を数えるだけに変更しました。

改めてAPI Gatewayにアクセスします。

Access to API Gateway was counted by the WAF Web ACL.

API Gatewayにアクセスできるようになりました。
ルールのアクションがブロックからカウントだけになり、アクセスが可能になったためです。

まとめ

WAF ACLをAPI Gatewayに適用する方法を確認しました。