CloudFront + WAF vs ALB + WAF 構成比較・検討結果
文書情報
| 項目 | 内容 |
|---|---|
| 作成日 | 2026-06-08 |
| 関連Issue | mental-online-karte#11667 |
| 関連ドキュメント | WAF 移行設計書, WAF 切り替え計画書 |
経緯
当初の方針
CloudFlare Proxy 障害(2026-05-21)を受け、CloudFlare から AWS CloudFront + WAF への完全移行を計画。全サービスで CloudFront + WAF(CLOUDFRONT スコープ)に統一する設計を策定した。
staging 検証で判明した問題
fd-system staging(backend-stg.fstdr.jp)で CloudFront + WAF を導入した際、以下の問題が発生した。
1. GET + body で 403(CloudFront 仕様)
member-service → FDM(backend-stg.fstdr.jp)のサービス間通信で、GET リクエストにリクエストボディ(data: {})を含めて送信しているケースがあり、CloudFront が 403 Forbidden (InvalidRequest) を返した。
- AWS 公式ドキュメントに明記された仕様: 「If a viewer GET request includes a body, CloudFront returns an HTTP status code 403 (Forbidden) to the viewer.」
- ALB 直接では GET + body を許容するため問題は発生しなかった
- CloudFront Functions / Lambda@Edge での回避は不可能(AWS サポート確認済み)
- アプリ修正(
callFdApiで GET の場合dataを渡さない)が必要だが、影響範囲の洗い出し・改修にコストがかかる
2. ALB 証明書の追加が必要
CloudFront の Origin Request Policy AllViewer を使用すると、Host ヘッダーの値が SNI として ALB に送信される。ALB に該当ドメインの証明書がないと SSL ハンドシェイクが失敗し 502 になった。
3. CloudFront 固有の制約の多さ
AWS 公式ドキュメントに記載されている制約が多数あり、既存アプリとの互換性検証が必要:
| 制約 | 影響 |
|---|---|
| GET + body → 403 | 今回の問題の原因 |
| リクエスト最大長 32,768 bytes | 大量のヘッダーや長い Cookie で到達し得る |
| URL 最大長 8,192 bytes | 長いクエリストリングで到達し得る |
| Origin レスポンスタイムアウト最大 60 秒 | 長時間処理の API で 504 になるリスク |
| User-Agent の書き換え | デフォルトで Amazon CloudFront に置換 |
| 一部ヘッダーの削除・変更 | Expect, Proxy-*, X-Real-IP 等を削除 |
| Authorization ヘッダーの削除(GET/HEAD) | Origin Request Policy で明示転送が必要 |
| X-Forwarded-For の追記 | hop 数が変わりアプリの IP 取得ロジックに影響 |
| Origin への転送は HTTP/1.1 | HTTP/2 で受けても Origin へは常に HTTP/1.1 |
| Cookie 転送時の条件付きリクエスト非サポート | If-Modified-Since / If-None-Match が使えない |
| リクエスト結合(Request Collapsing) | リアルタイム性が必要な API で意図しない遅延の可能性 |
比較表
前提
- 構成A: 全サービス CloudFront + WAF(CLOUDFRONT スコープ)
- 構成B: 全サービス ALB + WAF(REGIONAL スコープ)
1. 構築
| 観点 | 構成A(CloudFront + WAF) | 構成B(ALB + WAF) |
|---|---|---|
| Terraform モジュール | cloudfront-waf 1系統で統一 | ALB 用 WAF モジュールが必要 |
| ACM 証明書 | us-east-1 に必要。SANs 証明書の例外対応あり | ALB リージョンの既存証明書をそのまま利用 |
| DNS 切替 | CNAME 変更が必要 | 不要 |
| ALB SG / 証明書追加 | SG 制限 + 証明書追加が必要 | 不要 |
| 評価 | 構築工数が大きい | 構築工数が小さい |
2. 運用管理
| 観点 | 構成A(CloudFront + WAF) | 構成B(ALB + WAF) |
|---|---|---|
| WAF 管理 | CLOUDFRONT スコープで統一 | REGIONAL スコープで統一 |
| 共有 IP セット | CLOUDFRONT スコープで1セット | REGIONAL スコープで1セット |
| 評価 | 同等 | 同等 |
3. 制約
| 観点 | 構成A(CloudFront + WAF) | 構成B(ALB + WAF) |
|---|---|---|
| CloudFront 固有の制約 | 多数あり(上記一覧参照)。既存アプリとの互換性検証が必要 | なし。ALB は HTTP 仕様に寛容 |
| 評価 | 制約が多くブロッカーになり得る | 制約が少ない |
4. コスト
| 観点 | 構成A(CloudFront + WAF) | 構成B(ALB + WAF) |
|---|---|---|
| CloudFront 料金 | データ転送 + リクエスト料金が追加 | なし |
| WAF 料金 | 同等 | 同等 |
| キャッシュ効果 | 有効化すれば Origin 負荷軽減 | なし(必要時に後から CloudFront 追加) |
| 評価 | CloudFront 料金が追加。キャッシュで相殺可能 | CloudFront 料金なし |
5. セキュリティ
| 観点 | 構成A(CloudFront + WAF) | 構成B(ALB + WAF) |
|---|---|---|
| DDoS 保護 | Shield Standard(L3/L4/L7) | Shield Standard(L3/L4)+ WAF Rate-based(L7) |
| バイパス耐性 | ALB SG 制限が必要 | WAF が ALB に直接統合。バイパス不可能(検証済み・SA確認済み) |
| 評価 | 保護は強いが SG 制限が必要 | バイパス耐性が構造的に高い |
6. 拡張性
| 観点 | 構成A(CloudFront + WAF) | 構成B(ALB + WAF) |
|---|---|---|
| 新サービス追加 | Distribution + WAF + DNS + 証明書確認が必要 | ALB に WAF をアタッチするだけ |
| CloudFront Functions / Lambda@Edge | 利用可能 | 利用不可 |
| キャッシュ導入 | いつでも有効化可能 | 後から CloudFront 追加が必要 |
| 評価 | 拡張機能は豊富だが追加手順が多い | 追加が簡単だが機能は限定的 |
7. パフォーマンス
| 観点 | 構成A(CloudFront + WAF) | 構成B(ALB + WAF) |
|---|---|---|
| レイテンシ | CloudFront Edge → Origin の hop 追加 | 追加のレイテンシなし |
| キャッシュ | 有効化すれば高速化 | なし |
| 圧縮 | gzip/br 圧縮可能 | ALB 単体では圧縮なし |
| Origin タイムアウト | 最大 60 秒の制約 | 制約なし |
| 評価 | キャッシュ有効化後は恩恵大。ただし制約あり | 制約がなくシンプル |
8. 将来性
| 観点 | 構成A(CloudFront + WAF) | 構成B(ALB + WAF) |
|---|---|---|
| CloudFlare 完全代替 | CloudFront で全サービスカバー | CDN なし。必要時に追加 |
| マルチリージョン | CloudFront はグローバル対応 | リージョン固定 |
| 評価 | 将来の拡張余地が大きい | 現時点では十分 |
9. 監視
| 観点 | 構成A(CloudFront + WAF) | 構成B(ALB + WAF) |
|---|---|---|
| リアルタイムログ | CloudFront Real-time Logs → Datadog で準リアルタイム分析可能 | 不可。ALB は CloudWatch + S3 ログのみ |
| WAF ログ | Firehose → Datadog(同等) | Firehose → Datadog(同等) |
| 評価 | リアルタイム分析が充実 | WAF ログで通常運用は十分。必要時は S3 + Athena |
ALB + WAF 構成でリアルタイムログがないことについて:
- バイパス攻撃は構成上発生しない(WAF が ALB に直接統合されるため、検証済み・SA 確認済み)ので、リアルタイムログでの即座のバイパス検知は不要
- リアルタイムログは傾向分析をするときにあれば便利な程度で、常時必要なものではない
- 通常の運用は WAF ログ(Firehose → Datadog)で十分に賄える
- 詳細な分析が必要な場合は S3 に保管された WAF ログを Athena で SQL 検索して対応可能
バイパス耐性の検証
検証内容(infra-dev 環境)
- default action を
Blockにした WAF Web ACL を作成 fd-app-bffALB にアタッチ- ALB の DNS 名 / IP アドレスに直接アクセス → どちらも 403(WAF Block)
AWS SA への確認結果
以下の前提条件で WAF バイパスの可能性を確認:
構成:
Internet → ALB(WAF アタッチ済み)→ ECS(Fargate)
前提条件:
- AWS WAF(REGIONAL)は ALB に直接関連付け
- ECS は Private Subnet に配置
- ECS の assign_public_ip = false(パブリック IP なし)
- ECS Security Group は ALB Security Group からの通信のみ許可
- インターネットに公開されている入口は ALB のみその構成であれば基本的にバイパスはされなさそうです。ECS が Private で ALB 経由でしか通信を許していない以上、特に意図しない設定漏れや外部からの設定変更などの侵害がない限り(ECS へ外部から通信する場合は ALB を必ず通ることが保証されている場合)WAF は通るものと思われます。
ECS の配置確認
全 ECS サービスの Terraform コードを確認した結果、パブリックサブネットに配置されている ECS サービスは存在しない。全て Private Subnet + assign_public_ip = false。
GET + body 問題の対応検討
根本対応(アプリ修正)
member-service の callFdApi(src/lib/call-fd-api.ts)で GET リクエスト時に data: {} を渡さないよう修正すれば、CloudFront + WAF 構成でも問題は解消する。
// 修正案(1行変更)
data: method === 'GET' ? undefined : snakeBody,ただし、以下の理由からアプリ修正ではなくインフラ側で回避する方針とした:
- 修正範囲・影響範囲が読めない:
callFdApiはmember-service以外のサービスでも同様のパターンで使われている可能性があり、全サービスの洗い出しが必要 - アプリ側の修正・テスト・リリース工数がかかる: 認証・ログイン周りに影響するため慎重なテストが必要
- セキュリティリスク軽減が最優先: アプリ修正を待っていると WAF 導入が遅れる
CloudFront Functions / Lambda@Edge での回避検討
CloudFront 側で GET リクエストの body を除去できないか検討した。
| 方法 | 結果 |
|---|---|
| CloudFront Functions(Viewer Request) | リクエスト body にアクセスする機能自体がなく、対応不可 |
| Lambda@Edge(Origin Request) | GET/HEAD リクエストでは body にアクセスできない(AWS 制約)。対応不可 |
さらに CloudFront が WAF や Lambda@Edge より手前で GET + body を 403 で拒否する ため、これらの機能が実行される前にリクエストが弾かれることを AWS サポートにも確認した。
AWS サポート回答: 「手元で試したところ Lambda@Edge より前に CloudFront 側で 403 でエラーを返してしまうので、Lambda@Edge による対処は難しそうです。」
結論: CloudFront + WAF 構成を使う限り、GET + body 問題のインフラ側回避策は存在しない。
結論
採用する構成
全サービス ALB + WAF(REGIONAL)を採用する。CloudFront は使わない。
判断理由
- セキュリティリスクの軽減が最優先: 現在 CloudFlare Proxy OFF で WAF 保護がない状態の解消が急務。ALB + WAF なら DNS 切替やSG制限が不要で、迅速に導入できる
- CloudFront 固有の制約がブロッカー: GET + body 問題に代表される制約が多く、既存アプリとの互換性検証に時間がかかる。FE/API の分類・洗い出しも必要になり、導入が遅れる。アプリ修正は修正範囲・影響範囲が読めず、工数もかかるため現時点では見送る
- CloudFront 側での回避策が存在しない: CloudFront Functions / Lambda@Edge のいずれも GET + body の除去に対応できず、AWS サポートからも確認済み
- バイパス耐性が構造的に高い: WAF が ALB に直接統合されるため、SG 制限なしでバイパスが不可能
- 構築・運用がシンプル: DNS 切替、ALB SG 制限、ACM 証明書(us-east-1)等の追加作業が不要
今後の検討事項
- CloudFront のキャッシュによるパフォーマンス向上・コスト削減は今後検討課題として残す
- WAF 導入が安定した後、トラフィック分析の結果を踏まえて、キャッシュが効果的なサービスから CloudFront の追加を検討する
- その際は、今回判明した CloudFront 固有の制約への対応(アプリ修正含む)を事前に実施する
変更履歴
| 日付 | 内容 | 担当 |
|---|---|---|
| 2026-06-08 | 初版作成 | 大賀 |