𝕏 f B! L
案件・求人数 12,345
案件を探す(準備中) エージェントを探す(準備中) お役立ち情報 ログイン
案件・求人数 12,345
AWS WAF & Shield完全ガイド|SESエンジニアが知るべきWebセキュリティ防御の実装方法

AWS WAF & Shield完全ガイド|SESエンジニアが知るべきWebセキュリティ防御の実装方法

AWSWAFShieldセキュリティSESDDoS防御
目次
⚡ 3秒でわかる!この記事のポイント
  • AWS WAFでOWASP Top 10攻撃を防御するルール設定を網羅的に解説
  • AWS Shieldでレイヤー3/4のDDoS攻撃を自動検知・緩和する仕組み
  • SES案件で即活用できるセキュリティ実装パターンとコスト最適化の手法

「Webアプリケーションのセキュリティ対策を任されたけど、何から手を付ければいいかわからない」「WAFの設定が難しそうで手が出ない」——SES案件でセキュリティ要件に直面するエンジニアにとって、AWS WAFとShieldの理解は必須スキルになりつつあります。

結論から言えば、AWS WAFとShieldを組み合わせれば、SQLインジェクション・XSS・DDoS攻撃といったWebアプリケーションへの主要な脅威を包括的に防御できます。 特にAWSマネージドルールを活用すれば、セキュリティの専門知識がなくても基本的な防御体制を短期間で構築可能です。

この記事では、AWS WAFとShieldの基本概念から実践的な設定手順、SES案件で活用するためのノウハウまで詳しく解説します。

AWS WAF & Shield セキュリティ防御の全体像

AWS WAFとは?基本概念を理解する

AWS WAFの役割

AWS WAF(Web Application Firewall)は、Webアプリケーションに到達するHTTP/HTTPSリクエストをフィルタリングするサービスです。

インターネット → CloudFront/ALB → AWS WAF → アプリケーション

                               ルール評価
                               ├── 許可 (Allow)
                               ├── ブロック (Block)
                               ├── カウント (Count)
                               └── CAPTCHA

WAFの主要コンポーネント

コンポーネント説明用途
Web ACLルールのコンテナリソース(ALB/CloudFront)に関連付け
ルール個別の検査条件SQLi検出、XSS検出、IPブロック
ルールグループルールの集合マネージドルールの単位
ステートメント条件式マッチ条件の定義
アクション許可/拒否/カウントマッチ時の動作

AWS Shield Standard vs Shield Advanced

機能Shield StandardShield Advanced
料金無料(自動適用)$3,000/月 + データ転送
保護レイヤーL3/L4L3/L4/L7
DDoS検知自動自動 + リアルタイム可視化
応答チームなしAWS Shield Response Team (SRT)
コスト保護なしDDoS起因のスケーリングコスト補償
WAF統合なしWAFルール自動適用

AWS WAFの実装手順

ステップ1: Web ACLの作成

# AWS CLIでWeb ACLを作成
aws wafv2 create-web-acl \
  --name "ses-base-web-acl" \
  --scope REGIONAL \
  --default-action '{"Allow": {}}' \
  --visibility-config '{
    "SampledRequestsEnabled": true,
    "CloudWatchMetricsEnabled": true,
    "MetricName": "ses-base-waf-metrics"
  }' \
  --rules file://waf-rules.json

ステップ2: AWSマネージドルールの設定

AWSが提供するマネージドルールグループを活用すれば、最小限の設定でOWASP Top 10攻撃を防御できます。

{
  "Rules": [
    {
      "Name": "AWS-AWSManagedRulesCommonRuleSet",
      "Priority": 1,
      "Statement": {
        "ManagedRuleGroupStatement": {
          "VendorName": "AWS",
          "Name": "AWSManagedRulesCommonRuleSet"
        }
      },
      "OverrideAction": {"None": {}},
      "VisibilityConfig": {
        "SampledRequestsEnabled": true,
        "CloudWatchMetricsEnabled": true,
        "MetricName": "CommonRuleSet"
      }
    },
    {
      "Name": "AWS-AWSManagedRulesSQLiRuleSet",
      "Priority": 2,
      "Statement": {
        "ManagedRuleGroupStatement": {
          "VendorName": "AWS",
          "Name": "AWSManagedRulesSQLiRuleSet"
        }
      },
      "OverrideAction": {"None": {}},
      "VisibilityConfig": {
        "SampledRequestsEnabled": true,
        "CloudWatchMetricsEnabled": true,
        "MetricName": "SQLiRuleSet"
      }
    },
    {
      "Name": "AWS-AWSManagedRulesKnownBadInputsRuleSet",
      "Priority": 3,
      "Statement": {
        "ManagedRuleGroupStatement": {
          "VendorName": "AWS",
          "Name": "AWSManagedRulesKnownBadInputsRuleSet"
        }
      },
      "OverrideAction": {"None": {}},
      "VisibilityConfig": {
        "SampledRequestsEnabled": true,
        "CloudWatchMetricsEnabled": true,
        "MetricName": "KnownBadInputsRuleSet"
      }
    }
  ]
}

推奨マネージドルールグループ一覧

ルールグループ名保護対象月額コスト
AWSManagedRulesCommonRuleSetOWASP共通攻撃$1.00
AWSManagedRulesSQLiRuleSetSQLインジェクション$1.00
AWSManagedRulesKnownBadInputsRuleSet既知の悪意ある入力$1.00
AWSManagedRulesLinuxRuleSetLinux固有の脆弱性$1.00
AWSManagedRulesAmazonIpReputationList悪意あるIPアドレス$1.00
AWSManagedRulesBotControlRuleSetBot管理$10.00

ステップ3: カスタムルールの作成

レートリミットルール

{
  "Name": "RateLimitRule",
  "Priority": 10,
  "Statement": {
    "RateBasedStatement": {
      "Limit": 2000,
      "AggregateKeyType": "IP"
    }
  },
  "Action": {"Block": {}},
  "VisibilityConfig": {
    "SampledRequestsEnabled": true,
    "CloudWatchMetricsEnabled": true,
    "MetricName": "RateLimitRule"
  }
}

地理的制限ルール

{
  "Name": "GeoRestrictionRule",
  "Priority": 5,
  "Statement": {
    "NotStatement": {
      "Statement": {
        "GeoMatchStatement": {
          "CountryCodes": ["JP", "US", "SG"]
        }
      }
    }
  },
  "Action": {"Block": {}},
  "VisibilityConfig": {
    "SampledRequestsEnabled": true,
    "CloudWatchMetricsEnabled": true,
    "MetricName": "GeoRestriction"
  }
}

特定パスの保護(管理画面等)

{
  "Name": "AdminProtection",
  "Priority": 4,
  "Statement": {
    "AndStatement": {
      "Statements": [
        {
          "ByteMatchStatement": {
            "SearchString": "/admin",
            "FieldToMatch": {"UriPath": {}},
            "TextTransformations": [
              {"Priority": 0, "Type": "LOWERCASE"}
            ],
            "PositionalConstraint": "STARTS_WITH"
          }
        },
        {
          "NotStatement": {
            "Statement": {
              "IPSetReferenceStatement": {
                "ARN": "arn:aws:wafv2:ap-northeast-1:123456789012:regional/ipset/office-ips/xxx"
              }
            }
          }
        }
      ]
    }
  },
  "Action": {"Block": {}},
  "VisibilityConfig": {
    "SampledRequestsEnabled": true,
    "CloudWatchMetricsEnabled": true,
    "MetricName": "AdminProtection"
  }
}

Terraformによるインフラコード化

WAF構成のTerraform化

実際のSES案件では、WAF構成をコード管理するのがベストプラクティスです。

# waf.tf
resource "aws_wafv2_web_acl" "main" {
  name        = "ses-base-web-acl"
  description = "SES BASE Web ACL"
  scope       = "REGIONAL"

  default_action {
    allow {}
  }

  # OWASP Common Rule Set
  rule {
    name     = "AWSManagedRulesCommonRuleSet"
    priority = 1

    override_action {
      none {}
    }

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

        # 特定ルールのカウントモード(誤検知対策)
        rule_action_override {
          action_to_use {
            count {}
          }
          name = "SizeRestrictions_BODY"
        }
      }
    }

    visibility_config {
      cloudwatch_metrics_enabled = true
      metric_name               = "CommonRuleSet"
      sampled_requests_enabled   = true
    }
  }

  # SQLインジェクション防御
  rule {
    name     = "AWSManagedRulesSQLiRuleSet"
    priority = 2

    override_action {
      none {}
    }

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

    visibility_config {
      cloudwatch_metrics_enabled = true
      metric_name               = "SQLiRuleSet"
      sampled_requests_enabled   = true
    }
  }

  # レートリミット
  rule {
    name     = "RateLimitPerIP"
    priority = 10

    action {
      block {}
    }

    statement {
      rate_based_statement {
        limit              = 2000
        aggregate_key_type = "IP"
      }
    }

    visibility_config {
      cloudwatch_metrics_enabled = true
      metric_name               = "RateLimitPerIP"
      sampled_requests_enabled   = true
    }
  }

  # IPレピュテーションリスト
  rule {
    name     = "AWSManagedRulesAmazonIpReputationList"
    priority = 0

    override_action {
      none {}
    }

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

    visibility_config {
      cloudwatch_metrics_enabled = true
      metric_name               = "IpReputationList"
      sampled_requests_enabled   = true
    }
  }

  visibility_config {
    cloudwatch_metrics_enabled = true
    metric_name               = "ses-base-waf"
    sampled_requests_enabled   = true
  }

  tags = {
    Environment = "production"
    Project     = "ses-base"
  }
}

# ALBとの関連付け
resource "aws_wafv2_web_acl_association" "alb" {
  resource_arn = aws_lb.main.arn
  web_acl_arn  = aws_wafv2_web_acl.main.arn
}

Shield Advancedの設定(大規模案件向け)

# shield.tf
resource "aws_shield_protection" "alb" {
  name         = "ses-base-alb-protection"
  resource_arn = aws_lb.main.arn

  tags = {
    Environment = "production"
  }
}

resource "aws_shield_protection_group" "main" {
  protection_group_id = "ses-base-protection-group"
  aggregation         = "MAX"
  pattern             = "ALL"
}

監視とアラート設定

CloudWatchダッシュボード

resource "aws_cloudwatch_dashboard" "waf" {
  dashboard_name = "WAF-Security-Dashboard"
  dashboard_body = jsonencode({
    widgets = [
      {
        type   = "metric"
        x      = 0
        y      = 0
        width  = 12
        height = 6
        properties = {
          metrics = [
            ["AWS/WAFV2", "BlockedRequests", "WebACL", "ses-base-web-acl", "Region", "ap-northeast-1", "Rule", "ALL"],
            ["AWS/WAFV2", "AllowedRequests", "WebACL", "ses-base-web-acl", "Region", "ap-northeast-1", "Rule", "ALL"]
          ]
          period = 300
          stat   = "Sum"
          region = "ap-northeast-1"
          title  = "WAF リクエスト数(許可/ブロック)"
        }
      },
      {
        type   = "metric"
        x      = 12
        y      = 0
        width  = 12
        height = 6
        properties = {
          metrics = [
            ["AWS/WAFV2", "BlockedRequests", "WebACL", "ses-base-web-acl", "Region", "ap-northeast-1", "Rule", "RateLimitPerIP"],
            ["AWS/WAFV2", "BlockedRequests", "WebACL", "ses-base-web-acl", "Region", "ap-northeast-1", "Rule", "SQLiRuleSet"],
            ["AWS/WAFV2", "BlockedRequests", "WebACL", "ses-base-web-acl", "Region", "ap-northeast-1", "Rule", "CommonRuleSet"]
          ]
          period = 300
          stat   = "Sum"
          region = "ap-northeast-1"
          title  = "ルール別ブロック数"
        }
      }
    ]
  })
}

SNSアラートの設定

resource "aws_cloudwatch_metric_alarm" "waf_high_block_rate" {
  alarm_name          = "waf-high-block-rate"
  comparison_operator = "GreaterThanThreshold"
  evaluation_periods  = 2
  metric_name         = "BlockedRequests"
  namespace           = "AWS/WAFV2"
  period              = 300
  statistic           = "Sum"
  threshold           = 1000
  alarm_description   = "WAFブロック数が5分間で1000を超えました"

  dimensions = {
    WebACL = "ses-base-web-acl"
    Region = "ap-northeast-1"
    Rule   = "ALL"
  }

  alarm_actions = [aws_sns_topic.security_alerts.arn]
}

WAFログの分析

S3へのログ出力設定

# WAFログをS3に出力
aws wafv2 put-logging-configuration \
  --logging-configuration '{
    "ResourceArn": "arn:aws:wafv2:ap-northeast-1:123456789012:regional/webacl/ses-base-web-acl/xxx",
    "LogDestinationConfigs": [
      "arn:aws:s3:::ses-base-waf-logs"
    ],
    "RedactedFields": [
      {"SingleHeader": {"Name": "authorization"}}
    ]
  }'

Athenaでのログ分析

-- ブロックされたリクエストの分析
SELECT
  timestamp,
  httprequest.clientip,
  httprequest.uri,
  httprequest.httpmethod,
  terminatingruleid,
  action
FROM waf_logs
WHERE action = 'BLOCK'
  AND day = '2026/03/15'
ORDER BY timestamp DESC
LIMIT 100;

-- 攻撃元IPのTop 10
SELECT
  httprequest.clientip,
  COUNT(*) as block_count,
  ARRAY_AGG(DISTINCT terminatingruleid) as rules
FROM waf_logs
WHERE action = 'BLOCK'
  AND day >= '2026/03/08'
GROUP BY httprequest.clientip
ORDER BY block_count DESC
LIMIT 10;

-- SQLインジェクション試行の傾向
SELECT
  DATE_FORMAT(FROM_UNIXTIME(timestamp/1000), '%Y-%m-%d %H:00') as hour,
  COUNT(*) as sqli_attempts
FROM waf_logs
WHERE terminatingruleid = 'AWS-AWSManagedRulesSQLiRuleSet'
  AND day >= '2026/03/01'
GROUP BY DATE_FORMAT(FROM_UNIXTIME(timestamp/1000), '%Y-%m-%d %H:00')
ORDER BY hour;

SES案件でのセキュリティスキル活用

スキルシートに記載できるセキュリティ経験

スキル記載例単価インパクト
WAF設計・運用「AWS WAFでOWASP Top 10防御を構築」+5-10万/月
DDoS対策「Shield Advanced導入、SRTとの連携」+10-15万/月
セキュリティ監視「CloudWatch + Athena でWAFログ分析基盤構築」+5-10万/月
IaC化「Terraform でWAF構成をコード管理」+5-10万/月
インシデント対応「WAFルールの緊急適用でゼロデイ対応」+10-15万/月

セキュリティ関連の資格

SES案件でのアピール力を高めるセキュリティ資格も紹介します。

  • AWS Certified Security - Specialty: WAF/Shield/GuardDuty/IAM の総合知識
  • AWS Certified Solutions Architect - Professional: セキュリティを含む全体アーキテクチャ
  • CompTIA Security+: セキュリティの基礎概念(ベンダー非依存)

コスト最適化

WAFコストの内訳

項目単価月間見積もり(中規模サイト)
Web ACL$5.00/月$5.00
ルール$1.00/ルール/月$6.00(6ルール)
リクエスト$0.60/100万リクエスト$6.00(1000万リクエスト)
マネージドルール$1.00-$10.00/月$15.00
合計約$32.00/月

コスト削減のポイント

  1. カウントモードの活用: 新ルール追加時はまずカウントモードで誤検知を確認
  2. 不要なルールの整理: 定期的にルールの有効性を評価
  3. リクエストサンプリング: 全リクエストではなく、サンプリングでログコストを削減
  4. CloudFrontとの組み合わせ: エッジでブロックすることでオリジンへの負荷を軽減

まとめ: AWS WAF & Shieldでセキュリティスキルを強化

AWS WAFとShieldの活用は、SESエンジニアにとって以下の3つの大きな価値をもたらします。

  1. 即実践可能な防御体制: AWSマネージドルールで最短即日のセキュリティ強化
  2. 可視化と分析: CloudWatchとAthenaを組み合わせたセキュリティインサイトの構築
  3. キャリアアップ: セキュリティスキルは希少価値が高く、月額10万円以上の単価アップが見込める

セキュリティは「やらなければいけないこと」ではなく、「できれば大きな武器になること」です。AWS WAFとShieldを使いこなし、SES案件でのセキュリティ人材としてのポジションを確立しましょう。

関連記事

SES案件をお探しですか?

SES記事をもっと読む →
🏗️

SES BASE 編集長

SES業界歴10年以上のメンバーが在籍する編集チーム。SES企業での営業・エンジニア経験、フリーランス独立経験を持つメンバーが、業界のリアルな情報をお届けします。

📊 業界データに基づく記事制作 🔍 IPA・経済産業省データ参照 💼 SES実務経験者が執筆・監修