AWS WAF + ALB ハンズオン

Web Application Firewall で ALB を保護し、SQL インジェクション・XSS・レート制限を実装する

AWS WAF Application Load Balancer マネコン操作 中級 所要時間 60〜75 分 v1.0

📋 概要

このハンズオンでは、AWS WAF (Web Application Firewall) を使用して Application Load Balancer (ALB) を保護します。マネージドルールグループによる SQL インジェクション・XSS 対策と、カスタムのレートベースルールによるブルートフォース攻撃対策を実装し、実際に curl コマンドで攻撃リクエストがブロックされることを確認します。

項目内容
所要時間60〜75 分
難易度中級
主要サービスAWS WAF v2、Application Load Balancer
前提リソースEC2 + ALB + RDS ハンズオンで作成した handson-alb
課金目安WebACL の月額 + 追加した各ルール/ルールグループの月額 + 処理リクエスト数の従量課金。AWS マネージドルールに別途ライセンス料はなし(検証後すぐ削除推奨。最新単価はWAF 料金ページ
ℹ️ AWS WAF v2 について

このハンズオンでは AWS WAF v2(現行バージョン)を使用します。コンソールでは「WAF & Shield」と表示されます。旧バージョン(AWS WAF Classic)とは別サービスのため、コンソールで「WAF Classic に切り替え」が表示された場合は無視してください。

🏗️ 構成図

🌐 インターネット(ブラウザ / curl)
↓ HTTP/HTTPS
🛡️ AWS WAF WebACL
マネージドルール(SQLi / CRS)+ レートベースルール
↓ 許可されたリクエストのみ通過
⚖️ handson-alb(Application Load Balancer)
🖥️ handson-webap-1a / handson-webap-1c(EC2)

WAF は ALB の前段で動作し、悪意あるリクエストをブロックします。ブロックされたリクエストには HTTP 403 Forbidden が返されます。

✅ 前提条件

⚠️ ALB が存在しない場合

handson-alb がない場合は、EC2 + ALB + RDS ハンズオンを先に実施するか、テスト用 ALB を別途作成してください。WAF は ALB なしでも WebACL 単体で作成できますが、動作確認にはアタッチ先が必要です。

🔧 ステップ 1: WAF WebACL の作成

WebACL(Web Access Control List)は WAF のルールセットの単位です。まず空の WebACL を作成します。

1-1. WAF & Shield コンソールを開く

手順
  1. AWS マネジメントコンソールで「WAF」を検索して WAF & Shield を開く
  2. 左メニューから 「Web ACLs」 をクリック
  3. 右上のリージョンが 「Asia Pacific (Tokyo)」 になっていることを確認
  4. 「Create web ACL」 をクリック
⚠️ リージョン選択に注意

WAF コンソールは「Global(CloudFront 用)」と「リージョン別(ALB / API Gateway 用)」を切り替えられます。ALB に適用する場合は必ずリージョンを アジアパシフィック(東京) に設定してください。CloudFront 用の場合は「Global」を選択します。

1-2. WebACL の基本設定

手順:Describe web ACL and associate it to AWS resources
Resource type
Regional resources (ALB, API GW, AppSync, Cognito, App Runner, Verified Access)
Region
Asia Pacific (Tokyo)
Name
handson-webacl
Description(任意)
Hands-on WAF for ALB protection
CloudWatch metric name
handson-webacl(自動入力される)

1-3. Associated AWS resources(ALB との関連付け)

手順
  1. 「Add AWS resources」 をクリック
  2. リソースタイプ: Application Load Balancer を選択
  3. 一覧から handson-alb にチェックを入れる
  4. 「Add」 をクリック
ℹ️ 後からアタッチも可能

この手順では作成と同時に ALB を関連付けますが、Step 4 で改めてアタッチする方法も手順として記載します。作成時のリソース関連付けはスキップしても問題ありません。

設定を確認し 「Next」 をクリックします(ルール追加は次のステップで行います)。

🔧 ステップ 2: マネージドルールグループの追加

AWS が管理するルールセット(マネージドルールグループ)を追加します。このハンズオンでは AWS マネージドルールを使います。AWS マネージドルールは AWS Marketplace のサードパーティ製ルールと違い別途のライセンス料金(サブスクリプション料)がかかりませんが、「無料」ではありません ── WebACL にルールグループを追加すると、標準の AWS WAF 課金(後述)が発生します。

⚠️ 「追加料金なし」=「無料」ではない

AWS マネージドルールにサードパーティへのライセンス料はかかりませんが、WebACL に追加した各ルールグループは標準の AWS WAF 料金体系の対象です(WebACL の月額・ルール/ルールグループの月額・処理リクエスト数)。詳細は AWS WAF 料金ページを参照してください。

2-1. ルールの追加(Add rules and rule groups)

手順
  1. 「Add rules」ボタン → 「Add managed rule groups」 を選択
  2. 「AWS managed rule groups」セクションを展開
  3. 以下の 2 つのルールグループを 「Add to web ACL」 で有効化する

追加するマネージドルールグループ

ルールグループ名説明WCU
AWSManagedRulesCommonRuleSet一般的な Web 攻撃(XSS、LFI、RFI など)をブロック。OWASP Top 10 対応700
AWSManagedRulesSQLiRuleSetSQL インジェクション攻撃パターンを検出・ブロック200
ℹ️ WCU(Web ACL Capacity Unit)について

WebACL には WCU の上限(デフォルト 1500 WCU)があります。このハンズオンで使う 2 つのルールグループの合計は 900 WCU のため問題ありません。WCU が足りない場合は Service Quotas から上限緩和申請が必要です。

2-2. ルールアクションの確認

手順
  1. 各ルールグループの右側にある「Edit」をクリック
  2. ルール一覧が表示される。デフォルトは 「Use rule group base action」(ルールグループの設定に従う)
  3. 通常はデフォルトのままで OK。特定ルールだけ「Count」モード(カウントのみ・ブロックしない)に変更することも可能
  4. 「Save rule」→ 「Next」でルール優先度設定へ進む

2-3. ルールの優先度設定(Set rule priority)

優先度は数字が小さいほど先に評価されます。マネージドルールを先に評価し、その後カスタムルールを評価する順序にします。

優先度ルール名
1AWSManagedRulesCommonRuleSet
2AWSManagedRulesSQLiRuleSet

(カスタムルールは次のステップで追加します。優先度 3 以降に自動で追加されます)

🔧 ステップ 3: レートベースルール(カスタムルール)の追加

特定の IP アドレスから短時間に大量リクエストが来た場合にブロックするレートベースルールを追加します。DDoS・ブルートフォース攻撃対策に有効です。

3-1. カスタムルールの追加

手順
  1. ルール一覧画面で「Add rules」→ 「Add my own rules and rule groups」 を選択
  2. Rule type: 「Rate-based rule」 を選択

3-2. レートベースルールの設定

設定値
Name
handson-rate-limit
Rate limit
100
Evaluation window
5 minutes(5 分間で 100 リクエスト超過でブロック)
Request aggregation key
Source IP address
Action
Block
ℹ️ Rate limit の値について

このハンズオンでは動作確認しやすいように 100 req/5min という低い値を設定します。本番環境では通常のアクセスパターンに合わせて 1000〜10000 程度の値を設定してください。低すぎると正当なユーザーがブロックされます。

3-3. IPセット(拒否リスト)のオプション追加

特定の IP アドレスを明示的にブロックしたい場合は IP セットを作成してルールに追加できます。このハンズオンではスキップしますが、手順を記載します。

IP セット作成(任意)
  1. WAF コンソール左メニュー → 「IP sets」「Create IP set」
  2. IP set name: handson-blocklist
  3. Region: Asia Pacific (Tokyo)
  4. IP addresses: ブロックしたい IP を CIDR 形式で入力(例: 198.51.100.0/24
  5. WebACL のルール追加で「IP set」タイプのルールを作成し、この IP セットを参照する

ルール設定完了後、「Next」 → CloudWatch メトリクス確認 → 「Next」「Create web ACL」 をクリックします。

✅ 確認

WebACL 詳細ページが表示され、ルール一覧に AWSManagedRulesCommonRuleSet、AWSManagedRulesSQLiRuleSet、handson-rate-limit の 3 つが表示されていれば作成成功です。

🔧 ステップ 4: WebACL を ALB にアタッチする

Step 1 で ALB を関連付けた場合はこの手順は確認のみです。関連付けていない場合は以下の手順でアタッチします。

4-1. Associated resources の確認・設定

手順
  1. WebACL 詳細ページの 「Associated AWS resources」 タブをクリック
  2. handson-alb が表示されていれば関連付け済み → Step 5 へ進む
  3. 表示されていない場合は 「Add AWS resources」 をクリック
  4. 「Application Load Balancer」を選択し、handson-alb を選んで 「Add」
✅ 確認

「Associated AWS resources」タブに handson-alb が表示されていれば WAF の保護が有効になっています。ALB 側からも確認できます(EC2 → Load Balancers → handson-alb → 「Integrated services」タブに WAF が表示される)。

ℹ️ WAF は即時反映

ALB への WAF アタッチは数秒〜数分で反映されます。作成直後は WAF のルール評価が開始されるまで若干のウォームアップ時間がかかる場合があります。

🔧 ステップ 5: 動作確認

curl コマンドで WAF のブロック動作を確認します。ALB の DNS 名を手元に用意してください(EC2 コンソール → ロードバランサー → handson-alb の「DNS name」)。

5-1. 正常リクエストの確認

まず通常のリクエストが通ることを確認します。

curl -o /dev/null -s -w "%{http_code}" http://<ALB_DNS_NAME>/
✅ 期待結果

HTTP 200 が返ればアプリが正常に動作しています。

5-2. SQL インジェクション試験

SQL インジェクションパターンを含むリクエストを送信し、WAF がブロックすることを確認します。

curl -o /dev/null -s -w "%{http_code}" "http://<ALB_DNS_NAME>/?id=1'+OR+'1'%3D'1"

または以下でも確認できます:

curl -v "http://<ALB_DNS_NAME>/?search=<script>alert(1)</script>"
✅ 期待結果

HTTP 403 Forbidden が返ればブロック成功です。レスポンスボディに「403 Forbidden」と表示されます。

5-3. レートベースルールの試験(任意)

短時間に 100 リクエストを超えるとブロックされます。以下のコマンドで試験できます(Windows の場合は PowerShell で実行)。

# Linux / macOS for i in $(seq 1 120); do curl -o /dev/null -s -w "[$i] %{http_code}\n" "http://<ALB_DNS_NAME>/"; done # Windows PowerShell 1..120 | ForEach-Object { $code = (Invoke-WebRequest -Uri "http://<ALB_DNS_NAME>/" -UseBasicParsing).StatusCode; Write-Host "[$_] $code" }
✅ 期待結果

最初の数十リクエストは 200 が返り、100 を超えたあたりから 403 が返るようになります。5 分が経過するとレートカウンターがリセットされ再び 200 が返ります。

5-4. WAF コンソールでリクエストを確認

手順
  1. WAF コンソール → handson-webacl を開く
  2. 「Overview」 タブ → 「Sampled requests」セクションを確認
  3. ブロックされたリクエストの詳細(送信元 IP、マッチしたルール、URI など)が確認できる
  4. 「Traffic overview」 タブでは CloudWatch グラフでリクエスト数の推移を視覚的に確認できる
ℹ️ Sampled requests の遅延

「Sampled requests」は最大 3 時間分のサンプルを表示しますが、反映に数分かかることがあります。リアルタイムに近い確認は「Traffic overview」タブの CloudWatch メトリクスで行えます。

🧹 クリーンアップ

⚠️ 課金に注意

AWS WAF は WebACL ごとの月額に加え、WebACL に追加した各ルールおよび各ルールグループ(AWS マネージドルールグループを含む)ごとの月額、さらに処理リクエスト数に応じた従量課金が発生します。このハンズオンではマネージドルールグループ 2 つ + レートベースルール 1 つを追加しているため、その分の月額がかかります。完了後は必ず削除してください。
※ 単価はリージョンで変動します。最新の料金は AWS WAF 料金ページを参照してください。

削除手順(逆順で実施)

  1. ALB との関連付けを解除
    WAF コンソール → handson-webacl → 「Associated AWS resources」タブ → handson-alb を選択 → 「Disassociate」
  2. WebACL を削除
    WAF コンソール → Web ACLs → handson-webacl にチェック → 「Delete」
    関連付けが残っていると削除できません。先に Disassociate してください。
  3. IP セットを削除(作成した場合)
    WAF コンソール → IP sets → handson-blocklist → Delete
✅ 削除確認

WAF コンソールの「Web ACLs」一覧から handson-webacl が消えていれば削除完了です。ALB に WAF の保護がなくなりますが、Security Group と ALB 自体は引き続き動作します。