AWS WAFをALB・CloudFrontの前段に置く多層防御設計|マネージドルールの選定と誤検知の調整

宮崎智広 この記事の監修:宮崎智広(Linux実務・教育歴20年以上・受講者3,100名超)
HOMELinux技術 リナックスマスター.JP(Linuxマスター.JP)AWS(Amazon Linux) > AWS WAFをALB・CloudFrontの前段に置く多層防御設計|マネージドルールの選定と誤検知の調整
「WAFをALBの前段に置いたが、CloudFrontも使っているのでWAFを二重に設定しなければならないのか」「どのマネージドルールを選べばいいか判断できない」「本番に適用したら正規ユーザーのリクエストまでブロックされた」

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でルール単位に細かく調整できる


「このままじゃマズい」と感じていませんか?
参考書を開く気力もない、同年代に取り残される不安——
でも安心してください。プロのエンジニアはコマンドを暗記していません。
「現場で使える型」を効率よく使いこなしているだけです。
姓・名・メールの3つだけ/30秒/解除は3秒 / 詳細はこちら

なぜ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

作成後、CloudFrontディストリビューションの「Security」タブで上記WebACLを選択して関連付けます。

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

WebACLを作成したら、ALBと紐付けます。ALBのARNを取得してから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モードで追加する場合は、OverrideActionCountを指定します(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" } }

上記の例では、XSSパターン(CrossSiteScripting_URIPATH)にマッチしてCountされています。このリクエストが正規のものでなければBlockモードへの切り替えが適切です。一方、正規のフォームデータ(例: リッチテキストエディタの入力)がマッチしていた場合は、誤検知として除外設定が必要です。

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" } }

作成したIP SetをWebACLのPriority: 1(最優先)のAllowルールとして追加します。これにより、許可リストのIPは後続のマネージドルールの評価なしにスルーされます。

トラブルシュート

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だけでなく、VPC設計・IAMポリシー・CloudTrailログ収集など複数の層が絡み合います。WAFはあくまでアプリケーション層(L7)の防御の1つとして位置付け、NW層・認証層と組み合わせた縦深防御を意識して設計してください。AWS・Linuxサーバーの基礎から体系的に学びたい方はこちらの無料PDFページも参考にしてください。

AWS WAF設計を「実務の型」として身につけませんか?

WAFのルール設定方法はAWSドキュメントに書いてあります。でも「ALBとCloudFrontのどちらにWAFを置くべきか」「誤検知が出たとき最初に何を確認するのか」をとっさに答えられますか?
現場で通用する安全なLinuxサーバー構築の「型」を体系的に身につけたい方へ、『Linuxサーバー構築入門マニュアル(図解60P)』を完全無料でプレゼントしています。

「独学の時間がもったいない」「プロから直接、現場の技術を最短で学びたい」という本気の方には、2日で実務レベルのスキルが身につく【初心者向けハンズオンセミナー】も開催しています。

無料メルマガで学習を続ける

Linuxの実践スキルをメールで毎週お届け。
登録は30秒、解除もいつでも可。

登録無料・いつでも解除できます

暗記不要・1時間後にはサーバーが動く

3,100名以上が実践した「型」を無料で公開中

プロのエンジニアはコマンドを暗記していません。
「現場で使える型」を効率よく使いこなしているだけです。
その「型」を図解60Pにまとめた入門マニュアルを、完全無料でプレゼントしています。

姓・名・メールの3つだけ/30秒/解除は3秒 / 詳細はこちら

Linux無料マニュアル(図解60P) 名前とメールで30秒登録
宮崎 智広

この記事を書いた人

宮崎 智広(みやざき ともひろ)

株式会社イーネットマーキュリー代表。現役のLinuxサーバー管理者として20年以上の実務経験を持ち、これまでに累計3,100名以上のエンジニアを指導してきたLinux教育のプロフェッショナル。「現場で本当に使える技術」を体系的に伝えることをモットーに、実践型のLinuxセミナーの開催や無料マニュアルの配布を通じてLinux人材の育成に取り組んでいる。

趣味は、キャンプにカメラ、トラウト釣り。好きな食べ物は、ラーメンにお酒。休肝日が作れない、酒量を減らせないのが悩み。最近、ドラマ「フライトエンジェル」を観て涙腺が崩壊しました。