Web Application Firewall で ALB を保護し、SQL インジェクション・XSS・レート制限を実装する
このハンズオンでは、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(現行バージョン)を使用します。コンソールでは「WAF & Shield」と表示されます。旧バージョン(AWS WAF Classic)とは別サービスのため、コンソールで「WAF Classic に切り替え」が表示された場合は無視してください。
WAF は ALB の前段で動作し、悪意あるリクエストをブロックします。ブロックされたリクエストには HTTP 403 Forbidden が返されます。
wafv2:*(または AdministratorAccess)権限があることhandson-alb がない場合は、EC2 + ALB + RDS ハンズオンを先に実施するか、テスト用 ALB を別途作成してください。WAF は ALB なしでも WebACL 単体で作成できますが、動作確認にはアタッチ先が必要です。
WebACL(Web Access Control List)は WAF のルールセットの単位です。まず空の WebACL を作成します。
WAF コンソールは「Global(CloudFront 用)」と「リージョン別(ALB / API Gateway 用)」を切り替えられます。ALB に適用する場合は必ずリージョンを アジアパシフィック(東京) に設定してください。CloudFront 用の場合は「Global」を選択します。
この手順では作成と同時に ALB を関連付けますが、Step 4 で改めてアタッチする方法も手順として記載します。作成時のリソース関連付けはスキップしても問題ありません。
設定を確認し 「Next」 をクリックします(ルール追加は次のステップで行います)。
AWS が管理するルールセット(マネージドルールグループ)を追加します。このハンズオンでは AWS マネージドルールを使います。AWS マネージドルールは AWS Marketplace のサードパーティ製ルールと違い別途のライセンス料金(サブスクリプション料)がかかりませんが、「無料」ではありません ── WebACL にルールグループを追加すると、標準の AWS WAF 課金(後述)が発生します。
AWS マネージドルールにサードパーティへのライセンス料はかかりませんが、WebACL に追加した各ルールグループは標準の AWS WAF 料金体系の対象です(WebACL の月額・ルール/ルールグループの月額・処理リクエスト数)。詳細は AWS WAF 料金ページを参照してください。
| ルールグループ名 | 説明 | WCU |
|---|---|---|
| AWSManagedRulesCommonRuleSet | 一般的な Web 攻撃(XSS、LFI、RFI など)をブロック。OWASP Top 10 対応 | 700 |
| AWSManagedRulesSQLiRuleSet | SQL インジェクション攻撃パターンを検出・ブロック | 200 |
WebACL には WCU の上限(デフォルト 1500 WCU)があります。このハンズオンで使う 2 つのルールグループの合計は 900 WCU のため問題ありません。WCU が足りない場合は Service Quotas から上限緩和申請が必要です。
優先度は数字が小さいほど先に評価されます。マネージドルールを先に評価し、その後カスタムルールを評価する順序にします。
| 優先度 | ルール名 |
|---|---|
| 1 | AWSManagedRulesCommonRuleSet |
| 2 | AWSManagedRulesSQLiRuleSet |
(カスタムルールは次のステップで追加します。優先度 3 以降に自動で追加されます)
特定の IP アドレスから短時間に大量リクエストが来た場合にブロックするレートベースルールを追加します。DDoS・ブルートフォース攻撃対策に有効です。
このハンズオンでは動作確認しやすいように 100 req/5min という低い値を設定します。本番環境では通常のアクセスパターンに合わせて 1000〜10000 程度の値を設定してください。低すぎると正当なユーザーがブロックされます。
特定の IP アドレスを明示的にブロックしたい場合は IP セットを作成してルールに追加できます。このハンズオンではスキップしますが、手順を記載します。
handson-blocklist198.51.100.0/24)ルール設定完了後、「Next」 → CloudWatch メトリクス確認 → 「Next」 → 「Create web ACL」 をクリックします。
WebACL 詳細ページが表示され、ルール一覧に AWSManagedRulesCommonRuleSet、AWSManagedRulesSQLiRuleSet、handson-rate-limit の 3 つが表示されていれば作成成功です。
Step 1 で ALB を関連付けた場合はこの手順は確認のみです。関連付けていない場合は以下の手順でアタッチします。
「Associated AWS resources」タブに handson-alb が表示されていれば WAF の保護が有効になっています。ALB 側からも確認できます(EC2 → Load Balancers → handson-alb → 「Integrated services」タブに WAF が表示される)。
ALB への WAF アタッチは数秒〜数分で反映されます。作成直後は WAF のルール評価が開始されるまで若干のウォームアップ時間がかかる場合があります。
curl コマンドで WAF のブロック動作を確認します。ALB の DNS 名を手元に用意してください(EC2 コンソール → ロードバランサー → handson-alb の「DNS name」)。
まず通常のリクエストが通ることを確認します。
curl -o /dev/null -s -w "%{http_code}" http://<ALB_DNS_NAME>/
HTTP 200 が返ればアプリが正常に動作しています。
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」と表示されます。
短時間に 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 が返ります。
「Sampled requests」は最大 3 時間分のサンプルを表示しますが、反映に数分かかることがあります。リアルタイムに近い確認は「Traffic overview」タブの CloudWatch メトリクスで行えます。
AWS WAF は WebACL ごとの月額に加え、WebACL に追加した各ルールおよび各ルールグループ(AWS マネージドルールグループを含む)ごとの月額、さらに処理リクエスト数に応じた従量課金が発生します。このハンズオンではマネージドルールグループ 2 つ + レートベースルール 1 つを追加しているため、その分の月額がかかります。完了後は必ず削除してください。
※ 単価はリージョンで変動します。最新の料金は AWS WAF 料金ページを参照してください。
WAF コンソールの「Web ACLs」一覧から handson-webacl が消えていれば削除完了です。ALB に WAF の保護がなくなりますが、Security Group と ALB 自体は引き続き動作します。