はじめに
この記事の概要
今回社内製品のために立てた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について、ステージの詳細から「編集」をクリック
- スロットリングをONにし、レートとバーストに任意の値を設定して「保存」
- 例ではレートを1、バーストを1としていますが、この時点で「APIは2リクエスト/秒を許可、2リクエスト/秒の状態が続くと秒間3リクエスト目以降が拒否される」が実現されます
- レートやバーストの意味は公式にてご確認ください
2. WAF
STEP1
- 任意の名称 (Name) とCloudWatchのメトリクス名 (CloudWatch metric name) を入力
- 「ADD AWS Resources」をクリック (ポップアップウィンドウが開きます)
- (今回はREST APIに制限を掛けたいので) Resource TypeにAmazon API Gateway REST APIを選択
- 対象としたいAPIにチェックを入れ、「Add」をクリック (ポップアップウィンドウが閉じます)
- 「Next」をクリックしてSTEP2へ
STEP2
- 「Add Rules」をクリックし、「Add my own rules and rule groups」を選択 (STEP2がAdd my own rules and rule groupsに切り替わります)
- Rule typeに「Rule builder」を選択しNameに任意の名前を入力、Typeは「Rate-based rule」を選択
- Rate limitに「100」を入力、Request aggregationに「Source IP address」、Scope of inspection and rate limitingに「Consider all requests」を選択
- 最後のActionでBlockを選択し、「Add rule」をクリック (元のSTEP2へ戻ります)
- Default web ACL action for requests that don't match any rulesで「Allow」を選択し、「Next」をクリックしてSTEP3へ
STEP3~5
- デフォルトのまま「Next」をクリック、最後にSTEP5で「Create Web ACL」をクリックして完了
- この時点で「5分以内に同一IPから100を超えるリクエストがあった場合、当該IPからのリクエストをブロック」が実現されます
ログ出力の有効化
- STEP1~5の間でログ出力の設定ができないため、作成されたWeb ACLのNameリンクをクリックして詳細画面を開き「Logging and metrics」タブを表示後「Enable」をクリック
- Enable loggingの画面が表示されるので「CloudWatch Logs log group」を選択し、プリフィックスに aws-waf-logs- が付いたロググループを選択
- 適当なロググループがない場合は「Create New」から作成してください
- 必ずプリフィックスに aws-waf-logs- を付けるようにします (付いていないと選択肢としてそもそも表示されません)
- 適当なロググループがない場合は「Create New」から作成してください
- その他デフォルトのまま「Save」をクリック
3. CloudWatch ログ
ステップ1
ステップ 2~3
- 以下を入力し、「Next」をクリック
- 最後にステップ3で「メトリクスフィルターを作成」をクリック
4. CloudWatch アラーム
以降の手順にはログストリームが生成されている必要があるため、まだログストリームが生成されていないようであればこの時点で一度はAPI Gatewayを叩いておくことをオススメします。
ステップ1
- 「メトリクスの選択」をクリック
- CloudWatch ログの手順で作成したメトリクスにチェックを入れ、「メトリクスの選択」をクリック (メトリクスと条件の指定に進みます)
- 統計に「合計」を指定
- 条件を次の通り指定し、「次へ」をクリック
ステップ2
ステップ3~4
おわりに
一連の仕組みが出来上がったら、負荷テストをしてみましょう。私は普段使いのPostmanを利用しました。実際に送付されるメールはこんなイメージです。
少し手順は多いですが、それでもWeb APIのセキュリティ対策が手軽にできるというのはありがたいですね。何かのご参考になれば幸いです。