AWS WAFのアプリケーションレイヤーでのDDoS保護をIaCで実装する

AWS WAFのアプリケーションレイヤーでのDDoS保護をIaCで実装する

目次

    はじめに

    2025年6月に、AWS WAFがアプリケーションレイヤー(L7)のDDoS保護を実現するAWSマネージドグループのサポートを開始しました。サポートの開始から日数が経過していますが、CloudFormationテンプレートを作成する際に参考にできる記事が見当たらなかったので、今回作成しました。IaCでの記述方法に困っている方の助けになれば幸いです。

    AWS WAF L7 DDoS保護の概要

    本記事では具体的なルールの内容には触れませんので、詳細については以下の公式ドキュメントをご参照ください。

    実装

    前提

    実装するコードの前提は以下のとおりです。

    • CloudFrontに割り当てるWAFとして作成する。
    • 記載方法の比較のため、AWSManagedRulesCommonRuleSetの作成も含める。
    • 各IaCサービスで作成されるリソースのプロパティは、すべて同一になるよう記述する。

    CloudFormationでの実装

    Resources:
    WebACL:
    Type: AWS::WAFv2::WebACL
    Properties:
    Name: anti-ddos-test
    DefaultAction:
    Allow: {}
    Scope: CLOUDFRONT
    VisibilityConfig:
    CloudWatchMetricsEnabled: true
    MetricName: anti-ddos-test
    SampledRequestsEnabled: true
    Rules:
    - Name: AWS-AWSManagedRulesAntiDDoSRuleSet
    OverrideAction:
    None: {}
    Priority: 0
    Statement:
    ManagedRuleGroupStatement:
    VendorName: AWS
    Name: AWSManagedRulesAntiDDoSRuleSet
    ManagedRuleGroupConfigs:
    - AWSManagedRulesAntiDDoSRuleSet:
    ClientSideActionConfig:
    Challenge:
    ExemptUriRegularExpressions:
    - \/api\/|\.(acc|avi|css|gif|jpe?g|js|mp[34]|ogg|otf|pdf|png|tiff?|ttf|webm|webp|woff2?)$
    Sensitivity: HIGH
    UsageOfAction: ENABLED
    SensitivityToBlock: LOW
    VisibilityConfig:
    CloudWatchMetricsEnabled: true
    MetricName: AWS-AWSManagedRulesAntiDDoSRuleSet
    SampledRequestsEnabled: true
    - Name: AWS-AWSManagedRulesCommonRuleSet
    OverrideAction:
    None: {}
    Priority: 1
    Statement:
    ManagedRuleGroupStatement:
    VendorName: AWS
    Name: AWSManagedRulesCommonRuleSet
    VisibilityConfig:
    CloudWatchMetricsEnabled: true
    MetricName: AWS-AWSManagedRulesCommonRuleSet
    SampledRequestsEnabled: true

    Terraformでの実装

    注意点として、AWSプロバイダーのversion6.2.0以上を使用する必要があります。また、regex_stringのバックスラッシュの部分でエスケープシーケンスが必要です。

    resource "aws_wafv2_web_acl" "example" {
    name = "anti-ddos-test"
    scope = "CLOUDFRONT"
    default_action {
    allow {}
    }
    rule {
    name = "AWS-AWSManagedRulesAntiDDoSRuleSet"
    priority = 0
    override_action {
    none {}
    }
    statement {
    managed_rule_group_statement {
    name = "AWSManagedRulesAntiDDoSRuleSet"
    vendor_name = "AWS"
    managed_rule_group_configs {
    aws_managed_rules_anti_ddos_rule_set {
    client_side_action_config {
    challenge {
    exempt_uri_regular_expression {
    regex_string = "\\/api\\/|\\.(acc|avi|css|gif|jpe?g|js|mp[34]|ogg|otf|pdf|png|tiff?|ttf|webm|webp|woff2?)$"
    }
    sensitivity = "HIGH"
    usage_of_action = "ENABLED"
    }
    }
    }
    }
    }
    }
    visibility_config {
    cloudwatch_metrics_enabled = true
    metric_name = "AWS-AWSManagedRulesAntiDDoSRuleSet"
    sampled_requests_enabled = true
    }
    }
    rule {
    name = "AWS-AWSManagedRulesCommonRuleSet"
    priority = 1
    override_action {
    none {}
    }
    statement {
    managed_rule_group_statement {
    name = "AWSManagedRulesCommonRuleSet"
    vendor_name = "AWS"
    }
    }
    visibility_config {
    cloudwatch_metrics_enabled = true
    metric_name = "AWS-AWSManagedRulesCommonRuleSet"
    sampled_requests_enabled = true
    }
    }
    visibility_config {
    cloudwatch_metrics_enabled = true
    metric_name = "anti-ddos-test"
    sampled_requests_enabled = true
    }
    }

    AWS CDKでの実装

    偏見ですがTypeScriptが最も人気であると想定し、今回はTypeScriptで記述しました。AWS WAFではL2 Constructがないため、コード記述量はCloudFormationとさほど変わりません。

    import * as cdk from 'aws-cdk-lib/core';
    import * as wafv2 from 'aws-cdk-lib/aws-wafv2';
    import { Construct } from 'constructs';

    export class MyAppStack extends cdk.Stack {
    constructor(scope: Construct, id: string, props?: cdk.StackProps) {
    super(scope, id, props);

    const webAcl = new wafv2.CfnWebACL(this, "WebAcl", {
    defaultAction: { allow: {} },
    name: "anti-ddos-test",
    scope: "CLOUDFRONT",
    visibilityConfig: {
    cloudWatchMetricsEnabled: true,
    sampledRequestsEnabled: true,
    metricName: "WebAcl",
    },
    rules: [
    {
    priority: 0,
    name: "AWS-AWSManagedRulesAntiDDoSRuleSet",
    visibilityConfig: {
    cloudWatchMetricsEnabled: true,
    metricName: "AWS-AWSManagedRulesAntiDDoSRuleSet",
    sampledRequestsEnabled: true,
    },
    statement: {
    managedRuleGroupStatement: {
    vendorName: "AWS",
    name: "AWSManagedRulesAntiDDoSRuleSet",
    managedRuleGroupConfigs: [
    {
    awsManagedRulesAntiDDoSRuleSet: {
    clientSideActionConfig: {
    challenge: {
    usageOfAction: 'ENABLED',
    exemptUriRegularExpressions: [{
    regexString: '\/api\/|\.(acc|avi|css|gif|jpe?g|js|mp[34]|ogg|otf|pdf|png|tiff?|ttf|webm|webp|woff2?)$',
    }],
    sensitivity: 'HIGH',
    },
    },
    sensitivityToBlock: 'LOW',
    },
    }
    ]
    }
    },
    overrideAction: { none: {} }
    },
    {
    priority: 1,
    name: "AWS-AWSManagedRulesCommonRuleSet",
    visibilityConfig: {
    cloudWatchMetricsEnabled: true,
    metricName: "AWS-AWSManagedRulesCommonRuleSet",
    sampledRequestsEnabled: true,
    },
    statement: {
    managedRuleGroupStatement: {
    vendorName: "AWS",
    name: "AWSManagedRulesCommonRuleSet",
    },
    },
    overrideAction: { none: {} }
    },
    ],

    });
    }
    }

    最後に

    比較的新しいAWSサービス・機能のIaC対応がまだ浸透していない場合、生成AIによるコード生成はまだ難しい側面があるため、公式ドキュメントを参照することが最も確実です。

    アジアクエスト株式会社では一緒に働いていただける方を募集しています。
    興味のある方は以下のURLを御覧ください。