😽

AWS学びなおし(+TF)_WAF

2025/03/02に公開

AWS WAF (Web Application Firewall) とは

AWS WAFは、Webアプリケーションを悪意のある攻撃から保護するマネージド型のWeb Application Firewallサービスです。SQLインジェクション、クロスサイトスクリプティング(XSS)、DDoS攻撃など、一般的なWeb攻撃からアプリケーションを防御します。

WAFの主な役割

  • 悪意のあるトラフィックのフィルタリング: 事前に定義したルールに基づいて、悪意のあるリクエストを検出し、ブロックまたは許可します。
  • 脆弱性対策: アプリケーションの脆弱性を悪用した攻撃を防御します。
  • セキュリティルールの集中管理: 複数のWebアプリケーションに対するセキュリティルールを一元的に管理できます。
  • 可視性の向上: Webトラフィックの監視とログ記録により、セキュリティ状況の可視性を向上させます。
  • コンプライアンス対応: PCI DSSなどのコンプライアンス要件を満たすためのセキュリティ対策として利用できます。

WAFの構成要素

  • Web ACL (Web Access Control List): WAFのルールを定義し、どのAWSリソース (例: Application Load Balancer, API Gateway, CloudFront) に適用するかを決定するコンテナです。
  • ルール (Rule): 具体的なトラフィック検査の条件と、条件に一致した場合のアクション (許可、ブロック、カウント) を定義します。
    • マネージドルール: AWSやAWS Marketplaceのセキュリティベンダーが提供する、事前定義済みのルールセットです。一般的な攻撃パターンに対応しており、手軽に導入できます。
    • カスタムルール: ユーザーが独自に定義するルールです。特定のアプリケーションや要件に合わせて、柔軟なルールを作成できます。
      • ルールタイプ:
        • 正規表現一致 (Regex match): リクエストヘッダー、URI、ボディなどを正規表現で検査します。
        • SQLインジェクション一致 (SQL injection match): SQLインジェクション攻撃を検出します。
        • クロスサイトスクリプティング一致 (XSS match): XSS攻撃を検出します。
        • 地理的照合 (Geo match): リクエストの発信元国に基づいてフィルタリングします。
        • IPアドレス一致 (IP address match): 特定のIPアドレスまたはIPアドレス範囲からのリクエストを許可またはブロックします。
        • サイズ制限 (Size constraint): リクエストのサイズに基づいてフィルタリングします。
        • レートベースルール (Rate-based rule): 特定のIPアドレスからのリクエストレートを制限し、DDoS攻撃などを緩和します。
        • HTTPヘッダー一致 (HTTP header match): 特定のリクエストヘッダーに基づいてフィルタリングします。
        • HTTPメソッド一致 (HTTP method match): 特定のHTTPメソッド (GET, POSTなど) に基づいてフィルタリングします。
        • パス一致 (Path match): リクエストパスに基づいてフィルタリングします。
        • クエリ文字列一致 (Query string match): クエリ文字列に基づいてフィルタリングします。
        • ボディ一致 (Body match): リクエストボディに基づいてフィルタリングします。
        • JSONボディ一致 (JSON body match): JSON形式のリクエストボディに基づいてフィルタリングします。
        • カスタムペイロード一致 (Custom payload match): カスタムペイロードに基づいてフィルタリングします。
        • ルールグループ参照ステートメント (Rule group reference statement): 別のルールグループを参照します。
        • AWS Managed Rules参照ステートメント (AWS Managed Rules reference statement): AWSマネージドルールを参照します。
        • ボット制御 (Bot Control): ボットによるアクセスを制御します。
        • アカウント乗っ取り防止 (Account Takeover Prevention): アカウント乗っ取りを試みるアクセスを制御します。
  • ルールグループ (Rule group): 複数のルールをまとめて管理するためのグループです。再利用性や管理性を向上させることができます。マネージドルールもルールグループの一種です。
  • アクション (Action): ルールに一致したリクエストに対して実行する処理を定義します。
    • 許可 (Allow): リクエストを許可します。
    • ブロック (Block): リクエストをブロックし、エラーレスポンス (HTTPステータスコード403など) を返します。
    • カウント (Count): リクエストを許可しますが、ルールに一致した回数をカウントします。ルールのテストや監視に利用できます。
    • CAPTCHA: CAPTCHAチャレンジを送信し、人間によるアクセスであることを確認します。ボット対策に有効です。
    • Challenge: クライアントにチャレンジを送信し、クライアントがJavaScriptまたはクッキーをサポートしているかを確認します。CAPTCHAよりも透過的なボット対策として利用できます。

WAFの種類

  • リージョナルWAF: Application Load Balancer、API Gateway、AWS AppSyncなどのリージョンサービスを保護します。
  • CloudFront WAF: CloudFrontディストリビューションを保護します。グローバルに分散されたエッジロケーションでトラフィックを検査するため、低レイテンシで広範囲な防御が可能です。
  • AWS Shield Advanced: DDoS攻撃対策に特化したサービスで、WAFの機能も包含しています。より高度なDDoS攻撃防御が必要な場合に利用されます。

WAFの料金体系

AWS WAFの料金は、主に以下の要素で構成されます。

  • Web ACLの数: 作成したWeb ACLの数に応じて課金されます。
  • ルールの数: Web ACLに設定したルールの数に応じて課金されます。マネージドルールグループを利用する場合は、追加料金が発生します。
  • 処理されたWebリクエスト数: WAFで検査されたWebリクエストの数に応じて課金されます。

詳細な料金については、AWSの公式ドキュメントを参照してください。

WAFのメリット

  • Webアプリケーションのセキュリティ強化: 多様な攻撃からアプリケーションを保護し、セキュリティリスクを低減します。
  • 運用の簡素化: マネージドサービスのため、WAFの構築、運用、メンテナンスをAWSに任せることができます。
  • 柔軟なルール設定: カスタムルールにより、アプリケーションの特性に合わせたきめ細かい防御が可能です。
  • 可視性の向上: ログと監視機能により、セキュリティ状況を把握し、迅速な対応を支援します。
  • スケーラビリティ: トラフィックの増減に応じて自動的にスケールするため、パフォーマンスへの影響を最小限に抑えられます。

WAFのデメリット

  • 設定の複雑さ: 高度な防御を実現するためには、ルールの設計と設定に専門知識が必要となる場合があります。
  • 過剰検知 (False Positive) の可能性: 誤って正常なリクエストをブロックしてしまう可能性があります。適切なルール設計とテストが必要です。
  • 料金: 利用状況によっては、コストが大きくなる可能性があります。料金体系を理解し、適切な設定を行うことが重要です。

WAFの導入手順 (例: Application Load Balancer + リージョナルWAF)

  1. Web ACLの作成: AWS WAF & ShieldコンソールまたはAWS CLI/SDKからWeb ACLを作成します。リージョンを選択し、Web ACLの名前や説明を入力します。
  2. ルールの追加: Web ACLにルールを追加します。マネージドルールまたはカスタムルールを選択し、必要な設定を行います。ルールのアクション (許可、ブロック、カウント) を設定します。ルールの優先順位を設定します。
  3. AWSリソースとの関連付け: 作成したWeb ACLをApplication Load Balancerに関連付けます。ALBの設定画面からWAFを選択し、作成したWeb ACLを選択します。
  4. テストと調整: WAFを有効化し、実際にWebアプリケーションへのアクセスを試して、WAFの動作を確認します。ログとメトリクスを監視し、過剰検知や検知漏れがないか確認し、必要に応じてルールを調整します。
  5. 運用: WAFのログとメトリクスを継続的に監視し、新たな攻撃や脆弱性に対応するために、ルールを定期的に見直し、更新します。

【実務レベルの内容と重要事項】

実務におけるWAF設計・運用のポイント

  • 防御対象の明確化: WAFで何を防御したいのか、具体的な脅威とリスクを明確に定義します。
  • 段階的な導入: 最初から全てのルールを適用するのではなく、まずはCountモードで運用を開始し、ログを分析しながら徐々にBlockモードに移行するなど、段階的な導入を検討します。
  • False Positive対策: 過剰検知 (False Positive) を最小限に抑えるために、ルールの精度を高めることが重要です。正規表現の最適化、ホワイトリストの活用、ルールごとのテストなどを実施します。
  • False Negative対策: 検知漏れ (False Negative) を防ぐために、最新の脅威情報に基づいてルールを定期的に更新します。AWSマネージドルールやAWS Marketplaceのルールセットを活用することも有効です。
  • ログと監視: WAFのログ (CloudWatch Logs, S3) を適切に設定し、攻撃の兆候や異常なトラフィックを早期に検知できるように監視体制を構築します。CloudWatchメトリクスやアラームも活用します。
  • WAFルールのバージョン管理: TerraformなどのIaCツールを利用して、WAFルールをコードとして管理し、変更履歴を追跡できるようにします。
  • 運用体制の確立: WAFの運用担当者を明確にし、インシデント発生時の対応手順やルール更新のプロセスを定義します。
  • パフォーマンスへの影響: WAFによるレイテンシ増加を最小限に抑えるために、ルールの最適化やWAFの適切な配置 (CloudFront WAFの利用など) を検討します。
  • コスト最適化: 不要なルールやWeb ACLを削除するなど、定期的にWAFの設定を見直し、コストを最適化します。
  • WAFのテスト: WAF導入前、ルール変更時、定期的に、ペネトレーションテストや脆弱性診断を実施し、WAFの効果を検証します。
  • 緊急時の対応: 大規模な攻撃が発生した場合に備えて、WAFの緊急遮断手順や、AWSサポートとの連携体制を確立しておきます。
  • AWS Shield Advancedとの連携: DDoS攻撃対策を強化したい場合は、AWS Shield Advancedの導入を検討し、WAFと連携させることで、より強固な防御体制を構築できます。
  • Bot対策の強化: Bot Controlマネージドルールや、CAPTCHA/Challengeアクションを活用して、悪意のあるボットからのアクセスを効果的に防御します。
  • APIセキュリティ: API GatewayとWAFを連携させることで、APIに対する攻撃 (API Gatewayの脆弱性を狙った攻撃や、不正なAPIリクエストなど) を防御します。JSONボディインスペクションなどの機能を活用します。
  • DevSecOps: WAFの設定をIaCで管理し、CI/CDパイプラインに組み込むことで、セキュリティを開発プロセスに統合するDevSecOpsを実現します。

重要事項

  • WAFは万能ではない: WAFはWebアプリケーションのセキュリティを大幅に向上させますが、WAFだけで全ての攻撃を防げるわけではありません。アプリケーション自体の脆弱性対策や、他のセキュリティ対策 (IDS/IPS, ファイアウォール, 脆弱性診断など) との組み合わせが重要です。
  • 継続的な運用と改善: WAFは導入して終わりではなく、継続的な運用と改善が必要です。脅威の変化やアプリケーションの変更に合わせて、ルールを定期的に見直し、最適化していく必要があります。
  • 最新情報のキャッチアップ: AWS WAFは常に進化しており、新機能やマネージドルールが追加されています。AWSの最新情報を常にキャッチアップし、WAFの機能を最大限に活用することが重要です。

【実務でどの程度使用されるのか】

AWS WAFは、実務で非常に広く利用されています。 特に、以下のようなケースでは、WAFの導入がほぼ必須と言えるでしょう。

  • インターネット公開されているWebアプリケーション: 顧客向けWebサイト、ECサイト、Web APIなど、インターネット経由でアクセス可能なWebアプリケーションは、常に外部からの攻撃リスクにさらされています。WAFはこれらのアプリケーションを保護するための重要なセキュリティ対策となります。
  • 機密情報や個人情報を扱うWebアプリケーション: 金融機関、医療機関、ECサイトなど、機密情報や個人情報を扱うWebアプリケーションは、セキュリティ侵害による影響が大きいため、WAFによる強固な防御が不可欠です。
  • コンプライアンス要件があるWebアプリケーション: PCI DSS、GDPR、HIPAAなどのコンプライアンス要件を満たすためには、WAFのようなWebアプリケーションファイアウォールの導入が求められる場合があります。
  • DDoS攻撃対策を強化したいWebアプリケーション: DDoS攻撃は、Webアプリケーションの可用性を著しく損なう可能性があります。WAFのレートベースルールやAWS Shield Advancedと組み合わせることで、DDoS攻撃対策を強化できます。
  • ボット対策を強化したいWebアプリケーション: 不正なボットによるアクセスは、Webアプリケーションのリソースを浪費したり、不正な行為 (アカウント作成、情報収集など) を引き起こす可能性があります。WAFのBot ControlマネージドルールやCAPTCHA/Challengeアクションを活用することで、ボット対策を強化できます。

利用頻度の肌感覚

私の経験上、中規模以上の企業で、インターネット公開されているWebアプリケーションを運用している場合、AWS WAF (または同等のWAFサービス) を導入しているケースが非常に多い です。特に、セキュリティ意識の高い企業や、コンプライアンス要件のある企業では、WAFは必須のセキュリティ対策として認識されています。

近年、Webアプリケーションに対する攻撃は高度化・巧妙化しており、WAFの重要性はますます高まっています。クラウド環境でWebアプリケーションを構築・運用する際には、AWS WAFの導入を検討することを強く推奨します。

ただし、中小規模の企業や、社内ネットワーク内でのみ利用するWebアプリケーションの場合は、WAFの導入優先度が下がる場合もあります。しかし、セキュリティリスクを考慮すると、可能な限りWAFの導入を検討することが望ましいと言えるでしょう。

【terraformのコードで記述する場合の基本的内容と実務レベルの内容】

terraformのコードで記述する場合の基本的内容

resource "aws_wafv2_web_acl" "example" {
  name  = "example-web-acl"
  scope = "REGIONAL" # or "CLOUDFRONT"

  default_action {
    allow {}
  }

  rule {
    name     = "AWS-AWSManagedRulesCommonRuleSet"
    priority = 0

    statement {
      managed_rule_group_statement {
        name        = "AWSManagedRulesCommonRuleSet"
        vendor_name = "AWS"
      }
    }

    action {
      block {}
    }
    visibility_config {
      cloudwatch_metrics_enabled = false
      metric_name              = "AWS-AWSManagedRulesCommonRuleSet"
      sampled_requests_enabled = false
    }
  }

  visibility_config {
    cloudwatch_metrics_enabled = true
    metric_name              = "web-acl-metric"
    sampled_requests_enabled = true
  }
}

resource "aws_wafv2_web_acl_association" "example" {
  resource_arn = aws_lb.example.arn # 保護対象のリソース (ALB, API Gatewayなど)
  web_acl_arn  = aws_wafv2_web_acl.example.arn
}

コードの説明 (基本)

  • resource "aws_wafv2_web_acl" "example": Web ACLを定義するリソースです。
    • name: Web ACLの名前。
    • scope: スコープ ("REGIONAL" または "CLOUDFRONT")。保護対象のリソースの種類に合わせて選択します。
    • default_action: デフォルトアクション (ルールに一致しなかったリクエストに対する処理)。ここでは allow {} (許可) を設定しています。
    • rule: ルールを定義するブロック。
      • name: ルールの名前。
      • priority: ルールの優先順位 (小さいほど優先度が高い)。
      • statement: ルールステートメント (ルール条件)。ここでは managed_rule_group_statement を使用して、AWSマネージドルールグループ "AWSManagedRulesCommonRuleSet" を指定しています。
      • action: ルールアクション (ルールに一致した場合の処理)。ここでは block {} (ブロック) を設定しています。
      • visibility_config: 可視性設定 (CloudWatchメトリクス、サンプルリクエスト)。
    • visibility_config (Web ACL全体): Web ACL全体の可視性設定。
  • resource "aws_wafv2_web_acl_association" "example": Web ACLとAWSリソースを関連付けるリソースです。
    • resource_arn: 保護対象のAWSリソースのARN (例: Application Load BalancerのARN)。
    • web_acl_arn: 作成したWeb ACLのARN。

実務レベルの内容 (Terraform)

# 変数定義 (variables.tf)
variable "web_acl_name" {
  type    = string
  default = "my-web-acl"
}

variable "scope" {
  type    = string
  default = "REGIONAL"
  validation {
    condition     = contains(["REGIONAL", "CLOUDFRONT"], var.scope)
    error_message = "Scope must be either REGIONAL or CLOUDFRONT."
  }
}

variable "alb_arn" {
  type    = string
  description = "ARN of the Application Load Balancer to protect"
}

variable "managed_rule_groups" {
  type = list(object({
    name        = string
    vendor_name = string
    action_type = string # "BLOCK" or "COUNT"
    priority    = number
  }))
  default = [
    {
      name        = "AWSManagedRulesCommonRuleSet"
      vendor_name = "AWS"
      action_type = "BLOCK"
      priority    = 0
    },
    {
      name        = "AWSManagedRulesSQLInjectionRuleSet"
      vendor_name = "AWS"
      action_type = "BLOCK"
      priority    = 1
    }
  ]
}

# WAFモジュール (waf.tf)
resource "aws_wafv2_web_acl" "main" {
  name  = var.web_acl_name
  scope = var.scope

  default_action {
    allow {}
  }

  dynamic "rule" {
    for_each = var.managed_rule_groups
    content {
      name     = rule.value.name
      priority = rule.value.priority

      statement {
        managed_rule_group_statement {
          name        = rule.value.name
          vendor_name = rule.value.vendor_name
        }
      }

      action {
        block {} # デフォルトはブロック。必要に応じてrule.value.action_typeで切り替え可能
      }
      visibility_config {
        cloudwatch_metrics_enabled = false
        metric_name              = rule.value.name
        sampled_requests_enabled = false
      }
    }
  }


  visibility_config {
    cloudwatch_metrics_enabled = true
    metric_name              = "${var.web_acl_name}-metric"
    sampled_requests_enabled = true
  }
}

resource "aws_wafv2_web_acl_association" "main" {
  resource_arn = var.alb_arn
  web_acl_arn  = aws_wafv2_web_acl.main.arn
}

実務レベルの考慮事項 (Terraformコード例)

  • 変数化: Web ACL名、スコープ、保護対象リソースARN、マネージドルールグループなどを変数化することで、コードの再利用性、可読性、保守性を向上させます。variables.tf で変数を定義し、waf.tf で参照します。
  • モジュール化: WAFの設定をモジュール化することで、さらに再利用性を高め、コードを整理できます。上記の例は簡単なモジュール構成になっています。
  • 動的ルール定義 (dynamic block): dynamic "rule" ブロックを使用して、変数のリスト (managed_rule_groups) に基づいて複数のルールを動的に生成します。これにより、ルールの追加・変更が容易になります。
  • ルールの設定柔軟性: マネージドルールグループのアクション (Block/Count) を変数で制御できるようにすることで、ルールの適用を柔軟に調整できます (例: action_type 変数)。
  • 検証 (validation): 変数の値が想定される範囲内であることを検証する validation ブロックを追加することで、設定ミスを早期に検出し、コードの信頼性を向上させます。
  • 命名規則: リソース名、変数名、ルール名などに一貫性のある命名規則を適用することで、コードの可読性を高めます。
  • コメント: コード中に適切なコメントを追加することで、コードの意図や設定内容を明確にし、保守性を向上させます。
  • backend設定: Terraform stateをリモートで管理するために、terraform { backend "s3" { ... } } などのbackend設定を記述します。
  • providers設定: AWSプロバイダーの設定 (provider "aws" { ... }) を記述し、AWSリージョンなどを指定します。

実務でのTerraform WAFコード運用

  • Gitリポジトリで管理: TerraformコードをGitリポジトリでバージョン管理し、変更履歴を追跡できるようにします。
  • CI/CDパイプライン: Terraformコードの変更を自動的にデプロイするために、CI/CDパイプライン (例: GitHub Actions, AWS CodePipeline) を構築します。
  • 環境分離: 開発環境、ステージング環境、本番環境など、環境ごとにTerraform stateを分離し、設定を管理します。
  • コードレビュー: Terraformコードの変更をデプロイする前に、必ずコードレビューを実施し、設定ミスやセキュリティリスクを早期に検出します。
  • 定期的な見直し: WAFルールやTerraformコードを定期的に見直し、最新の脅威情報やAWSのベストプラクティスに合わせて、設定を最適化します。

上記のTerraformコード例はあくまで基本的なものであり、実際の運用環境では、さらに複雑なルールや設定が必要となる場合があります。しかし、Terraformを活用することで、WAFの設定をコードとして管理し、効率的かつ安全にWAFを運用することが可能になります。

Discussion