AWS WAFはCloudFront・ALB(Application Load Balancer)のいずれにも紐付けられますが、スコープ(グローバル/リージョナル)が異なるため、両方を正しく設計しないと防御の抜け穴が生まれます。CloudFrontだけに適用したWAFは、ALBに直接アクセスするトラフィック(社内ツール・API Gateway経由の呼び出しなど)をカバーしません。
この記事では、CloudFrontとALBの両前段にAWS WAFを配置する多層防御設計の考え方と具体的な手順を解説します。マネージドルールグループの選定ポイントと、本番適用前にCountモードで誤検知を洗い出す方法もあわせて紹介します。
動作確認環境: AWS WAF v2(WAFV2)/ ALB(ap-northeast-1)/ CloudFront(OAC構成)
この記事のポイント
・CloudFront前段WAF(スコープ: CLOUDFRONT)はus-east-1で作成する
・ALB前段WAF(スコープ: REGIONAL)はALBと同一リージョンで作成する
・マネージドルール追加後はCountモードで正規リクエストへの影響を確認する
・誤検知はRuleActionOverrideでルール単位に細かく調整できる
でも安心してください。プロのエンジニアはコマンドを暗記していません。
「現場で使える型」を効率よく使いこなしているだけです。
なぜALBとCloudFrontの両方にWAFを置くのか
CloudFront前段にWAFを配置すると、エッジロケーション(AWSのCDN世界拠点)でリクエストをフィルタリングでき、悪意あるトラフィックが東京リージョンのALBに到達する前に遮断できます。しかしこれだけでは不十分です。ALBはCloudFront以外からも直接アクセスされることがあります。たとえば:
・社内の管理ツールがALBエンドポイントを直接呼び出す
・API GatewayのVPC LinkがVPC内のALBを呼ぶ
・監視サーバーからのヘルスチェックツール
このようなケースでは、CloudFront前段WAFのフィルタリングをすり抜けてALBに到達します。ALBにもWAFを紐付けることで、アクセス経路に依存しない防御層が完成します。
| 配置場所 | スコープ | 作成リージョン | 主な役割 |
|---|---|---|---|
| CloudFront前段 | CLOUDFRONT | us-east-1(バージニア北部)固定 | エッジでのIP評判フィルタ・地域制限・DDoS緩和 |
| ALB前段 | REGIONAL | ALBと同一リージョン | アプリ層防御(SQLi/XSS)・レート制限・直接アクセス遮断 |
WAF WebACLの作成とスコープの違い
1. CloudFront用WebACL(スコープ: CLOUDFRONT)を作成する
CloudFront向けのWAF WebACLは、必ずバージニア北部(us-east-1)で作成する必要があります。これはAWSの仕様であり、他のリージョンで作成したWebACLはCloudFrontに紐付けられません。マネジメントコンソールを使う場合はリージョンを「米国東部 (バージニア北部)」に切り替えてからWAF画面を開いてください。AWS CLIで作成する場合:
# CloudFront用WebACL作成(us-east-1を必ず指定) aws wafv2 create-web-acl --name "cloudfront-waf-acl" --scope CLOUDFRONT --default-action Allow={} --visibility-config SampledRequestsEnabled=true,CloudWatchMetricsEnabled=true,MetricName=cloudfront-waf --region us-east-1
2. ALB用WebACL(スコープ: REGIONAL)を作成する
ALB向けのWebACLはALBと同一リージョン(例: ap-northeast-1)で作成します。スコープはREGIONALです:# ALB用WebACL作成(ap-northeast-1) aws wafv2 create-web-acl --name "alb-waf-acl" --scope REGIONAL --default-action Allow={} --visibility-config SampledRequestsEnabled=true,CloudWatchMetricsEnabled=true,MetricName=alb-waf --region ap-northeast-1
associate-web-aclコマンドで関連付けます:# ALBのARNを取得 ALB_ARN= # WebACLをALBに紐付け(WebACLのARNは create-web-acl の出力から取得) aws wafv2 associate-web-acl --web-acl-arn arn:aws:wafv2:ap-northeast-1:123456789012:regional/webacl/alb-waf-acl/abcd1234-5678-90ab-cdef-1234567890ab --resource-arn --region ap-northeast-1
マネージドルールグループの選定
1. 全構成で入れるべきベースルール
CloudFront・ALBの両WebACLに共通して追加を推奨するマネージドルールグループは以下の3つです:・AWSManagedRulesCommonRuleSet: OWASP Top 10対応のコアルールセット。XSS・SQLi・パストラバーサルなど主要な攻撃パターンを網羅する。優先度低め(例: Priority 20)で追加
・AWSManagedRulesAmazonIpReputationList: AWSが管理する既知の悪意あるIPアドレスリスト。DDoSボット・匿名プロキシを遮断。最初に評価したいため優先度高め(例: Priority 5)で追加
・AWSManagedRulesKnownBadInputsRuleSet: Log4Shell・Spring4Shell等の既知エクスプロイトパターンを遮断する
注意: ルールグループを追加するほどリクエスト評価コスト(WCU: WAF Capacity Unit)が増加します。1つのWebACLの上限は5,000WCUです。マネジメントコンソールでルール追加時に消費WCUが表示されるので確認してください。
2. アプリケーションの特性に応じたルール追加
ベースルールに加えて、アプリケーションの技術スタックに合わせて以下を追加します:・AWSManagedRulesSQLiRuleSet: SQLインジェクション特化。データベースを持つアプリケーション全般に推奨
・AWSManagedRulesPHPRuleSet: PHPアプリ固有の攻撃パターン(WordPressサイト等)
・AWSManagedRulesLinuxRuleSet: Linuxサーバー向け攻撃(LFI等)に対応
ルールグループの選定後、後述するCountモードで動作確認してからBlockに切り替えてください。いきなりBlockで追加するのは避けましょう。
CountモードによるFalse Positiveの事前確認
1. 新規マネージドルールをCountモードで追加する
マネージドルールを最初からBlockモードで追加すると、正規ユーザーのリクエストも遮断してしまうリスクがあります。まずCountモード(ブロックせず計測のみ)で追加し、影響を確認してからBlockに切り替えるのが安全な進め方です。マネジメントコンソールでのCount設定:
・WAFコンソール → 対象WebACL → 「Rules」タブ → 「Add rules」→「Add managed rule groups」
・ルール追加時に「Set rules action to Count」のチェックをオンにする
CLIでルールグループをCountモードで追加する場合は、
OverrideActionにCountを指定します(OverrideAction: Noneがルール本来のアクション=Blockで動作):# update-web-acl で使用するルール定義JSON(抜粋) # OverrideAction: Count = グループ全体をCountモードに強制 { "Name": "AWSManagedRulesCommonRuleSet", "Priority": 20, "OverrideAction": {"Count": {}}, "Statement": { "ManagedRuleGroupStatement": { "VendorName": "AWS", "Name": "AWSManagedRulesCommonRuleSet" } }, "VisibilityConfig": { "SampledRequestsEnabled": true, "CloudWatchMetricsEnabled": true, "MetricName": "AWSManagedRulesCommonRuleSet" } }
2. CloudWatch MetricsとWAFサンプルリクエストで影響を確認する
Countモードで1~3日間運用して、以下の指標を確認します:・CloudWatch Metrics: WAFメトリクス(CountedRequests)でカウントされたリクエスト数を監視する
・WAFサンプルリクエスト: コンソールの「Sampled requests」タブで、どのルールがどのリクエストにマッチしたか確認できる
・WAFログ(Kinesis Firehose→S3): 詳細ログを有効化すると、マッチしたルールIDとリクエストの詳細を取得できる
WAFログの実際の出力例(S3に保存されるJSONL形式のサンプル):
{ "timestamp": 1693800123456, "formatVersion": 1, "webaclId": "arn:aws:wafv2:ap-northeast-1:123456789012:regional/webacl/alb-waf-acl/abcd1234-...", "terminatingRuleId": "NONE", "action": "COUNT", "httpSourceName": "ALB", "ruleGroupList": [ { "ruleGroupId": "AWS#AWSManagedRulesCommonRuleSet", "nonTerminatingMatchingRules": [ { "ruleId": "CrossSiteScripting_URIPATH", "action": "COUNT" } ] } ], "httpRequest": { "clientIp": "203.0.113.55", "country": "JP", "uri": "/api/v1/search", "args": "q=%3Cscript%3Ealert(1)%3C%2Fscript%3E", "method": "GET" } }
3. 問題なければBlockモードへ切り替える
CountモードでFalse Positiveがないことを確認したら、ルールグループのOverrideActionをNoneに変更してルール本来のBlock動作に戻します:コンソール: 対象ルールグループの「Edit」→「Override all rule actions in this rule group」のチェックを外す → 保存
CLIの場合は
update-web-aclコマンドでOverrideActionをNoneに変更します。LockTokenが必要なので、事前にget-web-aclで取得してください:# LockTokenを取得してからupdate-web-aclで切り替え LOCK_TOKEN= echo "LockToken: " # LockToken: a1b2c3d4-e5f6-7890-abcd-ef1234567890
誤検知が出た場合の除外設定
1. ルール単位のオーバーライドで特定リクエストを除外する
マネージドルールグループ内の特定のルールだけをCountまたはAllowに変更したい場合は、RuleActionOverrideを使います。グループ全体ではなく問題のあるルールIDだけを上書きできるため、他のルールの防御を維持したまま誤検知を解消できます。# AWSManagedRulesCommonRuleSet内の特定ルールをCountに変更する設定例 # RuleActionOverrides で問題ルールIDだけ上書き(他ルールはBlock維持) { "Name": "AWSManagedRulesCommonRuleSet", "Priority": 20, "OverrideAction": {"None": {}}, "Statement": { "ManagedRuleGroupStatement": { "VendorName": "AWS", "Name": "AWSManagedRulesCommonRuleSet", "RuleActionOverrides": [ { "Name": "CrossSiteScripting_URIPATH", "ActionToUse": {"Count": {}} } ] } }, "VisibilityConfig": { "SampledRequestsEnabled": true, "CloudWatchMetricsEnabled": true, "MetricName": "AWSManagedRulesCommonRuleSet" } }
2. IP Setで正規送信元を許可リストに登録する
自社オフィスや監視サービスのIPアドレスが誤検知される場合は、IP Setを作成して優先度の高いAllowルールで除外します。このルールを最も優先度が高い位置(Priority: 1)に配置することで、後続のマネージドルールの評価前に通過させられます:# IP Set作成(自社オフィスIPを許可リストに登録) aws wafv2 create-ip-set --name "office-allowlist" --scope REGIONAL --ip-address-version IPV4 --addresses "203.0.113.1/32" "198.51.100.0/24" --region ap-northeast-1 # 出力例 { "Summary": { "Name": "office-allowlist", "Id": "11223344-aaaa-bbbb-cccc-556677889900", "ARN": "arn:aws:wafv2:ap-northeast-1:123456789012:regional/ipset/office-allowlist/11223344-...", "LockToken": "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx" } }
トラブルシュート
Q: WAFを有効にしたらHTTPレスポンスが200から403に変わったが、どのルールがブロックしたか分からないA: WAFのサンプルリクエスト(コンソール→対象WebACL→「Sampled requests」タブ)でブロックされたリクエストの詳細を確認してください。「Matching rule」列に該当ルールIDが表示されます。WAFログ(S3)を有効化している場合は
terminatingRuleIdフィールドをJSONで確認します。Q: CloudFrontのWAFはブロックしているが、ALBに直接アクセスすると通ってしまう
A: ALBにREGIONALスコープのWebACLを別途紐付けてください。また、ALBのセキュリティグループでCloudFrontからのアクセスのみを許可する設定(AWSマネージドプレフィックスリスト
pl-58a04531を使用)と組み合わせると、CloudFrontをバイパスした直接アクセスをNWレイヤーでも遮断できます。Q: マネージドルールを追加したらアプリのレスポンスが遅くなった
A: WAFのルール評価でレイテンシが増加した可能性があります。追加したルールグループのWCUをコンソールで確認し、不要なルールグループを削除してください。CloudFront+ALB構成では、WAF評価時間がCloudFrontのオリジンタイムアウト設定に影響するため、タイムアウト値の見直しも検討してください。
本記事のまとめ
| 設計要素 | 推奨設定 |
|---|---|
| CloudFront前段WAF | スコープ: CLOUDFRONT / 作成リージョン: us-east-1 |
| ALB前段WAF | スコープ: REGIONAL / 作成リージョン: ALBと同一 |
| ベースルール(全構成共通) | CommonRuleSet + IpReputationList + KnownBadInputsRuleSet |
| 新規ルール追加時 | Countモードで1~3日観察後にBlockへ切替 |
| 誤検知ルールの調整 | RuleActionOverrideで問題ルールIDのみCountに変更 |
| 正規送信元の除外 | IP Setを高優先度(Priority: 1)のAllowルールに登録 |
AWS WAF設計を「実務の型」として身につけませんか?
WAFのルール設定方法はAWSドキュメントに書いてあります。でも「ALBとCloudFrontのどちらにWAFを置くべきか」「誤検知が出たとき最初に何を確認するのか」をとっさに答えられますか?
現場で通用する安全なLinuxサーバー構築の「型」を体系的に身につけたい方へ、『Linuxサーバー構築入門マニュアル(図解60P)』を完全無料でプレゼントしています。
「独学の時間がもったいない」「プロから直接、現場の技術を最短で学びたい」という本気の方には、2日で実務レベルのスキルが身につく【初心者向けハンズオンセミナー】も開催しています。
3,100名以上が実践した「型」を無料で公開中
プロのエンジニアはコマンドを暗記していません。
「現場で使える型」を効率よく使いこなしているだけです。
その「型」を図解60Pにまとめた入門マニュアルを、完全無料でプレゼントしています。
姓・名・メールの3つだけ/30秒/解除は3秒 / 詳細はこちら

無料メルマガで学習を続ける
Linuxの実践スキルをメールで毎週お届け。
登録は30秒、解除もいつでも可。
登録無料・いつでも解除できます