1
2

AWS WAFでほどほどのセキュリティを構築する

Last updated at Posted at 2024-07-23

はじめに

この記事の概要

 今回社内製品のために立てたAPI (非クリティカル) についてセキュリティ対策を行うにあたって、WAFを利用した仕組みを構築してみました。簡単に共有させていただければと思います。
 「ある程度のセキュリティは確保したいけど、あまりガチガチに自動化みたいなところは考えていない」という人の参考になれば、という記事です。
 ※. API GatewayやLambdaの方には詳しく触れません。また個々の用語などについても逐一解説しておりません。

背景

  • API Gateway + Lambdaで、不特定多数のユーザーがアクセスするようなWeb APIを構築
  • APIの用途から想定されるアクセス数はかなり少ない
    • 多くても1時間で100リクエストとかそれぐらい (それくらいアクセスがあれば泣いて喜ぶ)
  • API自体には認証の仕組みを設けない
    • リクエストに特定のヘッダが付いていれば通す、という程度
  • 万が一DDoS攻撃に遭ったりすると嫌なので、様子を見ながらセキュリティ強度を調整したい

得られる結果 (ゴール)

  • APIは2リクエスト/秒を許可、2リクエスト/秒の状態が続くと秒間3リクエスト目以降が拒否される (API Gateway)
  • 5分以内に同一IPから100を超えるリクエストがあった場合、当該IPからのリクエストをブロック (WAF)
  • 上記ブロックが発生した場合、指定したメールアドレスにブロックが発生した旨を通知 (CloudWatch + SNS)
    • ブロックが発生した旨の通知を受け取ったら、必要に応じてブロックされたIPからのリクエストを手動で永続拒否 (WAF)

構成図

シンプル過ぎて書いた意味あったかな?と思いつつ一応構成図を載せておきます。
構成図

手順 (コンソールのUIなどはすべて2024/6/13時点のものです)

1. API Gateway

APIがステージにデプロイされていることが前提です。

  • 該当のAPIについて、ステージの詳細から「編集」をクリック
    image.png
  • スロットリングをONにし、レートとバーストに任意の値を設定して「保存」
    • 例ではレートを1、バーストを1としていますが、この時点で「APIは2リクエスト/秒を許可、2リクエスト/秒の状態が続くと秒間3リクエスト目以降が拒否される」が実現されます
    • レートやバーストの意味は公式にてご確認ください
      image.png

2. WAF

  • AWS WAFから「Create Web ACL」をクリック
    image.png

STEP1

  • 任意の名称 (Name) とCloudWatchのメトリクス名 (CloudWatch metric name) を入力
    image.png
  • 「ADD AWS Resources」をクリック (ポップアップウィンドウが開きます)
    image.png
  • (今回はREST APIに制限を掛けたいので) Resource TypeにAmazon API Gateway REST APIを選択
  • 対象としたいAPIにチェックを入れ、「Add」をクリック (ポップアップウィンドウが閉じます)
    image.png
  • 「Next」をクリックしてSTEP2へ

STEP2

  • 「Add Rules」をクリックし、「Add my own rules and rule groups」を選択 (STEP2がAdd my own rules and rule groupsに切り替わります)
    image.png
  • Rule typeに「Rule builder」を選択しNameに任意の名前を入力、Typeは「Rate-based rule」を選択
    image.png
  • Rate limitに「100」を入力、Request aggregationに「Source IP address」、Scope of inspection and rate limitingに「Consider all requests」を選択
    image.png
  • 最後のActionでBlockを選択し、「Add rule」をクリック (元のSTEP2へ戻ります)
    image.png
  • Default web ACL action for requests that don't match any rulesで「Allow」を選択し、「Next」をクリックしてSTEP3へ
    image.png

STEP3~5

  • デフォルトのまま「Next」をクリック、最後にSTEP5で「Create Web ACL」をクリックして完了
    • この時点で「5分以内に同一IPから100を超えるリクエストがあった場合、当該IPからのリクエストをブロック」が実現されます

ログ出力の有効化

  • STEP1~5の間でログ出力の設定ができないため、作成されたWeb ACLのNameリンクをクリックして詳細画面を開き「Logging and metrics」タブを表示後「Enable」をクリック
    image.png
  • Enable loggingの画面が表示されるので「CloudWatch Logs log group」を選択し、プリフィックスに aws-waf-logs- が付いたロググループを選択
    • 適当なロググループがない場合は「Create New」から作成してください
      • 必ずプリフィックスに aws-waf-logs- を付けるようにします (付いていないと選択肢としてそもそも表示されません)
  • その他デフォルトのまま「Save」をクリック

3. CloudWatch ログ

  • CloudWatchから「ロググループ」を選択し、前の手順で作成したロググループの名称をクリック
    image.png
  • メトリクスフィルタータブを表示し「メトリクスフィルターを作成」をクリック
    image.png

ステップ1

  • フィルターパターンに { $.action = "BLOCK" } を入力し、「Next」をクリック
    • パターンテストは任意でどうぞ
      image.png

ステップ 2~3

  • 以下を入力し、「Next」をクリック
    • フィルター名:任意の名称
    • メトリクス名前空間:既存の適当な名前空間がなければ作成 (例:/Security/WAF など)
    • メトリクス値:1
    • デフォルト値:0
    • Unit:なし
    • ディメンション:なし
      image.png
  • 最後にステップ3で「メトリクスフィルターを作成」をクリック

4. CloudWatch アラーム

以降の手順にはログストリームが生成されている必要があるため、まだログストリームが生成されていないようであればこの時点で一度はAPI Gatewayを叩いておくことをオススメします。

  • CloudWatchの「アラーム状態」 (または「すべてのアラーム」) を選択し、「アラームの作成」をクリック
    image.png

ステップ1

  • 「メトリクスの選択」をクリック
  • CloudWatch ログの手順で作成したメトリクスにチェックを入れ、「メトリクスの選択」をクリック (メトリクスと条件の指定に進みます)
    image.png
  • 統計に「合計」を指定
    image.png
  • 条件を次の通り指定し、「次へ」をクリック
    • しきい値の種類:静的
    • {メトリクス名}が次の時... (アラーム条件):以上
    • ...よりも (しきい値):1
    • アラームを実行するデータポイント:1/1
    • 欠落データの処理
      image.png

ステップ2

  • 以下を選択・入力し「次へ」をクリック
    • アラーム状態トリガー:アラーム状態
    • 次のSNSトピックに通知を送信:任意
      • トピックは必要に応じて新規作成してください
    • 通知以外のアクションについては割愛します
      image.png

ステップ3~4

  • アラーム名を入力、任意で説明を編集して「次へ」をクリック
    image.png
  • ステップ4で作成内容をプレビューし、問題なければ「アラームの作成」をクリック

おわりに

 一連の仕組みが出来上がったら、負荷テストをしてみましょう。私は普段使いのPostmanを利用しました。実際に送付されるメールはこんなイメージです。
image.png
 少し手順は多いですが、それでもWeb APIのセキュリティ対策が手軽にできるというのはありがたいですね。何かのご参考になれば幸いです。

1
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
2