WAFでブルートフォース攻撃を防ぐ|設定方法と運用のポイント

WAF(Web Application Firewall)は、アプリケーション層でブルートフォース攻撃を防御する最前線の砦です。しかし、単にWAFを導入しただけでは十分な防御は実現できません。2024年のデータによると、WAF導入企業の**約40%が設定不備により攻撃を通過**させています。本記事では、WAFでブルートフォース攻撃を効果的に防御するための技術的な設定方法から、誤検知を最小化するチューニング、主要WAF製品の比較、運用の自動化まで、実践的なノウハウを体系的に解説します。AWS WAF、Cloudflare、Akamaiなど主要製品の具体的な設定例を交えながら、セキュリティとユーザビリティのバランスを保つ運用方法を提供します。

WAFによるブルートフォース攻撃防御の仕組み

WAFの基本アーキテクチャ

WAF(Web Application Firewall)は、HTTPSトラフィックを検査し、悪意のあるリクエストをブロックするセキュリティコンポーネントです。ブルートフォース攻撃の仕組みを理解した上で、WAFがどのように防御するかを解説します。

WAFの配置モデル
WAFには3つの主要な配置モデルがある。1) リバースプロキシ型:アプリケーションの前段に配置、2) クラウド型:DNSレベルでトラフィックをルーティング、3) エージェント型:Webサーバー内にモジュールとして組み込み。ブルートフォース攻撃対策では、リバースプロキシ型とクラウド型が主流。
処理フローアーキテクチャ
クライアント → DNS → WAF → ロードバランサー → Webサーバー → アプリケーションの順でトラフィックが流れる。WAFは全HTTPSリクエストをインターセプトし、ルールエンジンで検査後、正常なトラフィックのみを通過させる。

WAFの内部処理ステージ:

ステージ 処理内容 ブルートフォース対策での役割 処理時間目安
1. 接続確立 SSL/TLS終端、TCP接続管理 IP評価、地理的制限 1-5ms
2. リクエスト解析 HTTPヘッダー、ボディのパース User-Agent検査、サイズ制限 2-10ms
3. ルール評価 シグネチャマッチング、レート計算 認証試行回数カウント 5-20ms
4. 機械学習分析 異常検知、スコアリング パターン認識、行動分析 10-50ms
5. アクション実行 許可/ブロック/チャレンジ CAPTCHA表示、一時ブロック 1-3ms
6. ロギング イベント記録、メトリクス更新 分析用データ蓄積 1-2ms

レイヤー7での防御メカニズム

WAFはOSI参照モデルのレイヤー7(アプリケーション層)で動作し、HTTPSプロトコルの内容を理解して防御します。

レイヤー7防御の特徴:

  1. コンテンツ認識型防御

    • URLパス解析(/login、/api/auth等の識別)
    • パラメータ検査(username、password フィールド)
    • クッキー・セッション管理
    • JSONペイロード解析
  2. 認証特化型ルール

    # AWS WAF ルール例
    {
      "Name": "RateLimitLoginEndpoint",
      "Priority": 1,
      "Statement": {
        "RateBasedStatement": {
          "Limit": 100,
          "AggregateKeyType": "IP",
          "ScopeDownStatement": {
            "ByteMatchStatement": {
              "SearchString": "/login",
              "FieldToMatch": {"UriPath": {}},
              "TextTransformations": [{"Priority": 0, "Type": "LOWERCASE"}]
            }
          }
        }
      },
      "Action": {"Block": {}},
      "VisibilityConfig": {
        "SampledRequestsEnabled": true,
        "CloudWatchMetricsEnabled": true,
        "MetricName": "RateLimitLoginEndpoint"
      }
    }
    
  3. セッションベース制御

    • 正常ログイン後のセッション追跡
    • 異常な再認証パターンの検出
    • セッションハイジャック防止

機械学習による攻撃検知

最新のWAFは機械学習(ML)を活用し、従来のシグネチャベース検知では困難だった攻撃を識別します。

教師あり学習モデル
過去の攻撃データでトレーニングされたモデル。ブルートフォース攻撃の特徴(高頻度リクエスト、失敗パターン、時系列特性)を学習し、類似パターンを検出。精度95%以上を達成するが、新しい攻撃手法には弱い。
教師なし学習モデル
正常トラフィックのベースラインを学習し、統計的異常を検出。ユーザーごとの通常の認証パターンを把握し、逸脱を識別。誤検知率は高めだが、ゼロデイ攻撃にも対応可能。

ML検知の実装例(Cloudflare):

ML機能 検知内容 しきい値 誤検知率
異常スコアリング ログイン頻度の異常 スコア75以上 2-3%
ボット検出 自動化ツールの識別 信頼度90%以上 1%未満
行動分析 マウス/キーボード動作 人間らしさ60%未満 5%
時系列分析 アクセスパターン 3σ外れ値 3-4%

主要WAF製品の比較と選定基準

AWS WAF

総当たり攻撃対策において、AWS WAFは最も広く使用されているクラウドWAFの一つです。

AWS WAFの特徴:

項目 詳細 ブルートフォース対策評価
料金体系 $5/月 + $1/100万リクエスト + $1/ルール コスト効率:★★★★☆
レートリミット 最小2,000リクエスト/5分 柔軟性:★★★☆☆
マネージドルール AWS Managed Rules、Marketplace 簡便性:★★★★★
カスタムルール JSON形式、最大1,500WCU カスタマイズ性:★★★★☆
ログ統合 CloudWatch、S3、Kinesis 分析機能:★★★★★
地理的制限 国レベル 精度:★★★☆☆

AWS WAF設定例(ブルートフォース対策):

{
  "Rules": [
    {
      "Name": "LoginRateLimit",
      "Priority": 1,
      "Statement": {
        "RateBasedStatement": {
          "Limit": 100,
          "AggregateKeyType": "IP",
          "ScopeDownStatement": {
            "AndStatement": {
              "Statements": [
                {
                  "ByteMatchStatement": {
                    "SearchString": "/api/login",
                    "FieldToMatch": {"UriPath": {}},
                    "TextTransformations": [{"Priority": 0, "Type": "LOWERCASE"}]
                  }
                },
                {
                  "ByteMatchStatement": {
                    "SearchString": "POST",
                    "FieldToMatch": {"Method": {}},
                    "TextTransformations": [{"Priority": 0, "Type": "NONE"}]
                  }
                }
              ]
            }
          }
        }
      },
      "Action": {
        "Block": {
          "CustomResponse": {
            "ResponseCode": 429,
            "CustomResponseBodyKey": "TooManyRequests"
          }
        }
      }
    }
  ]
}

Cloudflare WAF

Cloudflare WAFは、グローバルなエッジネットワークを活用した高性能WAFです。

Cloudflare WAFの強み:

Super Bot Fight Mode
機械学習ベースのボット検出機能。JavaScriptチャレンジ、CAPTCHAを自動的に適用。ブルートフォース攻撃の自動化ツールを**95%以上の精度**で識別。Proプラン($20/月)から利用可能。
Rate Limiting Rules
複雑な条件式をサポート。IPアドレス、セッション、カスタムヘッダーでの集計が可能。**最小10秒間隔**でのレート制限設定により、きめ細かい制御を実現。

Cloudflare設定コード例:

// Cloudflare Workers でのカスタムロジック
addEventListener('fetch', event => {
  event.respondWith(handleRequest(event.request))
})

async function handleRequest(request) {
  const url = new URL(request.url)
  
  // ログインエンドポイントの検出
  if (url.pathname === '/login' && request.method === 'POST') {
    const ip = request.headers.get('CF-Connecting-IP')
    
    // KVストレージでレート追跡
    const key = `rate_limit:${ip}`
    const count = await RATE_LIMIT.get(key) || 0
    
    if (count > 5) {
      // 5回を超えたらCAPTCHA表示
      return new Response('Too many attempts', {
        status: 429,
        headers: {
          'Retry-After': '300',
          'X-RateLimit-Limit': '5',
          'X-RateLimit-Remaining': '0'
        }
      })
    }
    
    // カウント増加(TTL: 300秒)
    await RATE_LIMIT.put(key, parseInt(count) + 1, {expirationTtl: 300})
  }
  
  return fetch(request)
}

Akamai

Akamai Web Application Protectorは、エンタープライズ向けの包括的なWAFソリューションです。

機能 仕様 ブルートフォース対策での利点
Adaptive Rate Control 動的しきい値調整 正常トラフィック増加時の誤検知防止
Client Reputation 2億以上のIP評価DB 既知の攻撃者を事前ブロック
API Security OpenAPI仕様統合 APIエンドポイント個別保護
Bot Manager デバイスフィンガープリント 高度なボット検出
処理能力 15Tbps以上 DDoS併発時も安定動作

F5 Advanced WAF

F5 Advanced WAF(旧ASM)は、オンプレミスとクラウドのハイブリッド環境に最適化されています。

F5 iRulesでの実装例:

when HTTP_REQUEST {
    # ログインページへのアクセス制限
    if { [HTTP::uri] starts_with "/login" } {
        # テーブルでIP別カウント管理
        set client_ip [IP::client_addr]
        set login_count [table incr -subtable login_attempts $client_ip]
        
        # 5分間で10回を超えたらブロック
        if { $login_count > 10 } {
            # カスタムブロックページ
            HTTP::respond 429 content {
                <html>
                <body>
                <h1>Too Many Login Attempts</h1>
                <p>Please try again after 5 minutes.</p>
                </body>
                </html>
            } "Content-Type" "text/html" "Retry-After" "300"
            
            # ログ記録
            log local0. "Blocked brute force attempt from $client_ip"
            return
        }
        
        # テーブルエントリのTTL設定(300秒)
        table timeout -subtable login_attempts $client_ip 300
    }
}

国産WAF製品

日本市場向けに最適化された国産WAF製品も、独自の強みを持っています。

主要国産WAF比較:

製品名 ベンダー 特徴 料金目安 ブルートフォース対策
SiteGuard ジェイピー・セキュア IPS一体型、日本語UI 月額3万円~ ログイン画面改ざん防止
Scutum セキュアスカイ SaaS型、自動チューニング 月額2.9万円~ 機械学習ベース検知
BLUE Sphere アイロバ CDN統合型 月額5万円~ 地域別アクセス制御
CloudBric クラウドブリック AI自動運用 月額2.8万円~ ゼロデイ攻撃対応

レートベースルールの設定方法

閾値の設計思想

レートベースルールの適切な閾値設定は、誤検知と見逃しのバランスを決定する重要な要素です。

閾値設計の基本原則:

  1. ベースライン測定(最初の2週間)

    • 正常時の最大同時接続数
    • ピーク時のリクエスト頻度
    • ユーザーの再試行パターン
  2. 段階的な閾値設定

    レベル1(観察): ベースライン × 3倍 → ログのみ
    レベル2(警告): ベースライン × 2倍 → CAPTCHA表示
    レベル3(制限): ベースライン × 1.5倍 → 一時ブロック
    レベル4(遮断): ベースライン × 1.2倍 → 恒久ブロック
    
  3. エンドポイント別の個別設定

エンドポイント 閾値(/分) ウィンドウ アクション 根拠
/login 5回 1分 CAPTCHA 人間の限界値
/api/auth 10回 5分 429エラー API利用想定
/password-reset 3回 10分 メール遅延 悪用防止
/register 2回 60分 IPブロック 重複登録防止
/api/* 100回 1分 レート制限 通常利用範囲

ウィンドウサイズの最適化

ウィンドウサイズ(集計期間)の設定は、攻撃検知の精度に直接影響します。

スライディングウィンドウ方式
過去N秒間を常に評価する方式。例:過去60秒間で常に集計。リアルタイム性が高く、攻撃の検知漏れが少ないが、計算負荷が高い。Redis Sorted Setなどで実装。
固定ウィンドウ方式
固定時間枠(例:毎分0秒でリセット)で集計。実装が簡単で負荷が低いが、ウィンドウ境界での攻撃を見逃す可能性がある。カウンタベースで実装。

ウィンドウサイズ選択マトリックス:

攻撃タイプ 推奨サイズ 理由 実装例
高速ブルートフォース 30-60秒 即座に検知必要 スライディング
低速ブルートフォース 5-15分 分散攻撃対応 固定ウィンドウ
パスワードスプレー 60分 長期間追跡 タイムバケット
自動化ツール 10秒 高速検知 リアルタイム

誤検知を減らすチューニング

誤検知は正当なユーザーを締め出し、ビジネスインパクトを与える重大な問題です。

誤検知削減テクニック:

  1. ホワイトリスト管理

    whitelist:
      ip_addresses:
        - 10.0.0.0/8      # 内部ネットワーク
        - 192.168.0.0/16  # VPN経由
        - 203.0.113.0/24  # 信頼できるパートナー
      user_agents:
        - "CompanyApp/1.0"  # 自社アプリ
        - "Monitoring/2.0"  # 監視ツール
      api_keys:
        - "trusted_partner_key_*"
    
  2. 適応型しきい値

    • 時間帯別調整(営業時間:緩和、深夜:厳格)
    • 曜日別調整(平日:標準、週末:厳格)
    • イベント時調整(キャンペーン:緩和)
  3. 多要素スコアリング

要素 重み 正常スコア 異常スコア
IP評判 30% 0-30 31-100
地理的位置 20% 国内:0 海外:50
User-Agent 15% 既知:0 不明:30
リクエスト頻度 25% 低:0 高:75
時間帯 10% 営業時間:0 深夜:20
合計しきい値 - <50:許可 >80:ブロック

IPレピュテーションとジオブロッキング

脅威インテリジェンスの活用

技術的な実装方法と連携し、脅威インテリジェンスを活用したIPレピュテーション評価を実装します。

主要な脅威インテリジェンスソース:

ソース 更新頻度 IPアドレス数 精度 API制限 料金
AbuseIPDB リアルタイム 1億+ 85% 1,000/日(無料) $9~/月
IPQualityScore 1時間 5億+ 90% 5,000/月(無料) $25~/月
Project Honey Pot 日次 3億+ 80% 無制限 無料
Spamhaus 15分 2億+ 95% 300,000/日 $250~/月
AlienVault OTX リアルタイム 1.5億+ 75% 無制限 無料

IPレピュテーション実装例(Python):

import requests
import ipaddress
from functools import lru_cache
from datetime import datetime, timedelta

class IPReputationChecker:
    def __init__(self):
        self.cache = {}
        self.cache_ttl = timedelta(hours=1)
        
    @lru_cache(maxsize=10000)
    def check_abuseipdb(self, ip):
        """AbuseIPDB APIでIP評価"""
        headers = {
            'Accept': 'application/json',
            'Key': 'YOUR_API_KEY'
        }
        params = {
            'ipAddress': ip,
            'maxAgeInDays': 90,
            'verbose': ''
        }
        
        try:
            response = requests.get(
                'https://api.abuseipdb.com/api/v2/check',
                headers=headers,
                params=params,
                timeout=2
            )
            data = response.json()['data']
            
            return {
                'score': data['abuseConfidenceScore'],
                'total_reports': data['totalReports'],
                'is_whitelisted': data['isWhitelisted'],
                'usage_type': data['usageType']
            }
        except:
            return {'score': 0, 'total_reports': 0}
    
    def evaluate_ip(self, ip):
        """総合的なIP評価"""
        # キャッシュチェック
        if ip in self.cache:
            cached_data, timestamp = self.cache[ip]
            if datetime.now() - timestamp < self.cache_ttl:
                return cached_data
        
        # 複数ソースから評価
        abuse_score = self.check_abuseipdb(ip)['score']
        
        # プライベートIPは信頼
        try:
            if ipaddress.ip_address(ip).is_private:
                result = {'trust_level': 100, 'action': 'allow'}
            # 悪意あるIPは即ブロック
            elif abuse_score > 75:
                result = {'trust_level': 0, 'action': 'block'}
            # 疑わしいIPはCAPTCHA
            elif abuse_score > 25:
                result = {'trust_level': 50, 'action': 'challenge'}
            # 正常なIP
            else:
                result = {'trust_level': 80, 'action': 'allow'}
        except:
            result = {'trust_level': 50, 'action': 'challenge'}
        
        # キャッシュ更新
        self.cache[ip] = (result, datetime.now())
        return result

国別アクセス制御の是非

ジオブロッキングは強力な防御手段ですが、ビジネスへの影響を慎重に検討する必要があります。

ジオブロッキングのメリット
攻撃の**70-80%を事前に防御**可能。特に、ビジネス展開していない地域からの攻撃を効率的に遮断。処理負荷も軽減され、WAFのコストも削減できる。
ジオブロッキングのデメリット
正当な海外ユーザーや出張中の社員をブロックする可能性。VPN利用者への影響、SEOへの悪影響、将来的な市場拡大の制約となる場合がある。

段階的ジオブロッキング戦略:

レベル 対象エンドポイント ブロック地域 例外処理
レベル1 管理画面 日本以外すべて VPN許可リスト
レベル2 ログインページ 高リスク20カ国 ビジネスパートナー国は除外
レベル3 API リスクスコア基準 認証済みは除外
レベル4 一般ページ なし 異常パターンのみ

VPN・Tor対策

VPNTor経由のアクセスは、攻撃者が身元を隠すために頻繁に使用されます。

VPN/Tor検出と対策マトリックス:

検出方法 検出率 誤検知率 実装難易度 推奨対応
IPデータベース照合 85% 5% 基本実装
ASN分析 70% 10% 補助的利用
ポート/プロトコル分析 60% 15% 参考情報
タイミング分析 40% 20% 研究段階
WebRTC漏洩 95% 1% 推奨

実装例(nginx設定):

# Tor出口ノードのブロック
geo $is_tor {
    default 0;
    include /etc/nginx/tor-exit-nodes.txt;
}

# VPNプロバイダーのブロック
geo $is_vpn {
    default 0;
    # NordVPN
    185.217.116.0/22 1;
    185.244.214.0/23 1;
    # ExpressVPN
    169.150.196.0/22 1;
    # その他主要VPN...
}

server {
    location /login {
        if ($is_tor) {
            return 403 "Tor access not allowed";
        }
        
        if ($is_vpn) {
            # VPNはCAPTCHAチャレンジ
            return 302 /challenge?return_url=$request_uri;
        }
        
        proxy_pass http://backend;
    }
}

認証エンドポイントの特別保護

ログインページの要塞化

認証エンドポイントは最も攻撃されやすいポイントであり、特別な保護が必要です。

多層防御アーキテクチャ:

  1. 第1層:ネットワークレベル

    • DDoS防御(レート制限:100req/秒
    • GeoIP制限
    • ボットネットIPブロック
  2. 第2層:WAFレベル

    • ログイン試行制限(5回/5分
    • CAPTCHA統合
    • デバイスフィンガープリント
  3. 第3層:アプリケーションレベル

    • アカウントロックアウト
    • 2要素認証
    • ログイン異常検知

Cloudflare Page Rulesでの実装:

// ログインページ専用ルール
{
  "url": "example.com/login*",
  "actions": [
    {
      "id": "browser_check",
      "value": "on"  // ブラウザ整合性チェック
    },
    {
      "id": "security_level",
      "value": "high"  // セキュリティレベル最高
    },
    {
      "id": "cache_level",
      "value": "bypass"  // キャッシュ無効
    },
    {
      "id": "waf",
      "value": "simulate"  // WAFルール有効
    },
    {
      "id": "rate_limit",
      "value": {
        "requests": 5,
        "period": 60,
        "action": "challenge"
      }
    }
  ]
}

APIエンドポイントの防御

APIの不適切な認可(BOLA)対策と連携し、APIエンドポイント固有の防御を実装します。

API保護のベストプラクティス:

対策 実装方法 効果 設定例
APIキー必須化 Headerで検証 不正アクセス95%削減 X-API-Key: required
レート制限 トークンバケット 過負荷防止 1000req/時
JWT検証 署名確認 なりすまし防止 RS256署名
IPホワイトリスト 送信元制限 攻撃面削減 CIDR指定
リクエスト署名 HMAC-SHA256 改ざん防止 タイムスタンプ含む

AWS API Gateway + WAFの設定:

# serverless.yml
functions:
  auth:
    handler: auth.handler
    events:
      - http:
          path: /api/auth
          method: POST
          throttle:
            burstLimit: 10   # バースト上限
            rateLimit: 5     # 持続レート/秒
          private: true      # APIキー必須
          authorizer:        # カスタム認可
            name: apiAuthorizer
            type: request
            identitySource: method.request.header.Authorization

resources:
  Resources:
    ApiGatewayRestApi:
      Type: AWS::ApiGateway::RestApi
      Properties:
        Policy:
          Statement:
            - Effect: Deny
              Principal: "*"
              Action: execute-api:Invoke
              Resource: "*"
              Condition:
                IpAddress:
                  aws:SourceIp:
                    - "192.0.2.0/24"  # 攻撃元IP拒否

パスワードリセット機能の保護

パスワードリセット機能は、アカウント乗っ取りの裏口として悪用されやすい機能です。

列挙攻撃への対策
メールアドレスの存在確認を防ぐため、登録の有無に関わらず同一メッセージを返す。「パスワードリセットメールを送信しました」と常に表示。実際の送信はバックグラウンドで非同期処理。
トークンの安全性確保
リセットトークンは**最低32文字**の暗号学的に安全な乱数を使用。有効期限は**15分**に制限。使用後は即座に無効化。トークンはハッシュ化して保存。

リセット機能の段階的制限:

試行回数 制限内容 解除条件 通知
1-2回 なし - なし
3回目 5分待機 時間経過 なし
4-5回目 メール認証追加 メールリンククリック ユーザー通知
6回以上 24時間ブロック 管理者解除 管理者通知

ログ分析と可視化

攻撃パターンの識別

WAFログから攻撃パターンを識別することは、防御ルールの改善に不可欠です。

典型的な攻撃パターンと特徴:

パターン ログ特徴 識別クエリ例 対策優先度
高速ブルートフォース 同一IP、短時間、連続失敗 status:401 AND time:<1s
分散ブルートフォース 複数IP、同一パスワード password_hash:same 最高
辞書攻撃 共通パスワードリスト password IN (common_list)
タイミング攻撃 レスポンス時間の分析 response_time GROUP BY result
セッション固定 同一セッションID再利用 session_id COUNT > 10

ログ分析スクリプト例(Python):

import pandas as pd
from datetime import datetime, timedelta
import json

class WAFLogAnalyzer:
    def __init__(self, log_file):
        self.df = self.parse_logs(log_file)
    
    def parse_logs(self, log_file):
        """WAFログのパース"""
        logs = []
        with open(log_file, 'r') as f:
            for line in f:
                try:
                    log = json.loads(line)
                    logs.append({
                        'timestamp': datetime.fromisoformat(log['timestamp']),
                        'ip': log['clientIP'],
                        'uri': log['uri'],
                        'status': log['statusCode'],
                        'action': log['action'],
                        'rule': log.get('ruleId', ''),
                        'country': log.get('country', ''),
                        'user_agent': log.get('userAgent', '')
                    })
                except:
                    continue
        
        return pd.DataFrame(logs)
    
    def detect_brute_force(self, threshold=10, window_minutes=5):
        """ブルートフォース攻撃の検出"""
        # 時間窓でグループ化
        self.df['time_window'] = pd.cut(
            self.df['timestamp'],
            pd.date_range(
                self.df['timestamp'].min(),
                self.df['timestamp'].max(),
                freq=f'{window_minutes}min'
            )
        )
        
        # IP別、時間窓別でカウント
        attacks = self.df[
            (self.df['uri'].str.contains('/login')) &
            (self.df['status'] == 401)
        ].groupby(['ip', 'time_window']).size()
        
        # 閾値を超えるIPを特定
        suspicious_ips = attacks[attacks > threshold].reset_index()
        suspicious_ips.columns = ['ip', 'time_window', 'attempt_count']
        
        return suspicious_ips
    
    def analyze_patterns(self):
        """攻撃パターン分析"""
        patterns = {
            'top_attacking_ips': self.df['ip'].value_counts().head(10),
            'top_attacked_endpoints': self.df['uri'].value_counts().head(10),
            'attack_timeline': self.df.groupby(
                pd.Grouper(key='timestamp', freq='H')
            ).size(),
            'country_distribution': self.df['country'].value_counts(),
            'blocked_percentage': (
                self.df[self.df['action'] == 'BLOCK'].shape[0] / 
                self.df.shape[0] * 100
            )
        }
        
        return patterns

Elasticsearch/Kibanaとの連携

ElasticsearchKibanaを使用した、リアルタイムログ分析基盤の構築方法です。

アーキテクチャ構成:

WAF → Kinesis/Kafka → Logstash → Elasticsearch → Kibana
                          ↓
                    Alerting → Slack/PagerDuty

Logstash設定例:

input {
  kinesis {
    kinesis_stream_name => "waf-logs"
    region => "ap-northeast-1"
    codec => json
  }
}

filter {
  # IPアドレスから地理情報を追加
  geoip {
    source => "clientIP"
    target => "geoip"
  }
  
  # User-Agentの解析
  useragent {
    source => "userAgent"
    target => "ua"
  }
  
  # ブルートフォース検出用フィールド追加
  if [uri] =~ /login|auth|signin/ {
    mutate {
      add_field => { "is_auth_endpoint" => true }
    }
    
    # 5分間のウィンドウでカウント
    aggregate {
      task_id => "%{clientIP}"
      code => "
        map['attempts'] ||= 0
        map['attempts'] += 1
        event.set('attempt_count', map['attempts'])
      "
      push_previous_map_as_event => false
      timeout => 300
      timeout_tags => ['_aggregatetimeout']
    }
  }
  
  # 攻撃スコア計算
  ruby {
    code => "
      score = 0
      score += 30 if event.get('statusCode') == 401
      score += 20 if event.get('attempt_count').to_i > 5
      score += 25 if event.get('geoip.country_name') != 'Japan'
      score += 25 if event.get('ua.name') =~ /bot|crawler|spider/i
      event.set('threat_score', score)
    "
  }
}

output {
  elasticsearch {
    hosts => ["localhost:9200"]
    index => "waf-logs-%{+YYYY.MM.dd}"
    template_name => "waf-logs"
    template => "/etc/logstash/templates/waf-template.json"
  }
  
  # 高スコアアラート
  if [threat_score] >= 75 {
    email {
      to => "security@example.com"
      subject => "High threat score detected: %{clientIP}"
      body => "Threat Score: %{threat_score}\nIP: %{clientIP}\nEndpoint: %{uri}"
    }
  }
}

リアルタイムダッシュボード構築

Kibanaダッシュボードで、ブルートフォース攻撃をリアルタイム監視します。

必須ビジュアライゼーション要素:

ビジュアル タイプ メトリクス 更新頻度 アラート条件
攻撃試行数 Line Chart COUNT(401) 10秒 >100/分
Top攻撃元IP Data Table IP別カウント 30秒 >50回
地理的分布 Coordinate Map 国別ヒートマップ 1分 新規国
ブロック率 Gauge BLOCK/TOTAL 10秒 <90%
レスポンスタイム Area Chart 95パーセンタイル 10秒 >1000ms
異常スコア分布 Histogram threat_score 30秒 >80

自動化とオーケストレーション

SOAR連携

SOAR(Security Orchestration, Automation and Response)との連携により、インシデント対応を自動化します。

SOAR連携のメリット
検知から対応まで**平均対応時間を87%削減**。24時間365日の自動対応により、深夜・休日の攻撃にも即座に対処。人的ミスの削減と、対応の一貫性確保も実現。
主要SOAR製品
Splunk Phantom、IBM Resilient、Palo Alto Cortex XSOAR、開源のTheHive/Cortexなど。中小企業向けには、Shuffleなどの無料OSSも選択肢。

Cortex XSOAR Playbook例:

# ブルートフォース攻撃対応プレイブック
id: brute_force_response
name: Automated Brute Force Response
tasks:
  - id: "1"
    name: "WAFアラート受信"
    type: trigger
    trigger:
      type: webhook
      path: /waf/bruteforce
  
  - id: "2"
    name: "IP評価"
    type: action
    action:
      service: virustotal
      method: ip_report
      params:
        ip: "{{incident.source_ip}}"
    outputs:
      reputation_score: "{{result.reputation}}"
  
  - id: "3"
    name: "自動判定"
    type: condition
    conditions:
      - if: "{{reputation_score}} > 50"
        goto: "4"  # 自動ブロック
      - elif: "{{reputation_score}} > 20"
        goto: "5"  # 一時制限
      - else:
        goto: "6"  # 監視継続
  
  - id: "4"
    name: "IPブロック"
    type: action
    action:
      service: waf
      method: add_ip_blacklist
      params:
        ip: "{{incident.source_ip}}"
        duration: 86400  # 24時間
        reason: "Automated: High risk brute force"
  
  - id: "5"
    name: "レート制限強化"
    type: action
    action:
      service: waf
      method: update_rate_limit
      params:
        ip: "{{incident.source_ip}}"
        limit: 1  # 1req/分に制限
        duration: 3600  # 1時間

自動ブロックとその解除

自動ブロックは効果的ですが、誤検知による影響を最小化する仕組みが必要です。

段階的エスカレーション:

レベル トリガー条件 自動アクション 継続時間 解除条件
L1 5回/分 JavaScriptチャレンジ 5分 自動
L2 10回/分 CAPTCHA表示 15分 成功で解除
L3 20回/分 一時IPブロック 1時間 自動
L4 50回/分 恒久IPブロック 24時間 手動確認
L5 100回/分 ASNブロック 7日間 調査後解除

自動解除の実装例(Python):

import redis
import time
from datetime import datetime, timedelta

class AutoBlockManager:
    def __init__(self):
        self.redis = redis.Redis(host='localhost', port=6379, db=0)
        self.block_durations = {
            'L1': 300,      # 5分
            'L2': 900,      # 15分
            'L3': 3600,     # 1時間
            'L4': 86400,    # 24時間
            'L5': 604800    # 7日
        }
    
    def block_ip(self, ip, level, reason):
        """IP自動ブロック"""
        duration = self.block_durations.get(level, 3600)
        block_key = f"blocked:{ip}"
        block_data = {
            'level': level,
            'reason': reason,
            'blocked_at': datetime.now().isoformat(),
            'expires_at': (datetime.now() + timedelta(seconds=duration)).isoformat(),
            'attempt_count': 0
        }
        
        # Redisに保存(TTL付き)
        self.redis.setex(
            block_key,
            duration,
            json.dumps(block_data)
        )
        
        # WAFルール更新
        self.update_waf_rules(ip, 'add')
        
        # 通知
        self.notify_block(ip, level, reason, duration)
        
        return block_data
    
    def auto_unblock_check(self):
        """自動解除チェック(cronで定期実行)"""
        pattern = "blocked:*"
        cursor = 0
        
        while True:
            cursor, keys = self.redis.scan(
                cursor, match=pattern, count=100
            )
            
            for key in keys:
                data = json.loads(self.redis.get(key))
                ip = key.decode().split(':')[1]
                
                # 解除条件チェック
                if self.should_unblock(ip, data):
                    self.unblock_ip(ip, 'auto')
                    
            if cursor == 0:
                break
    
    def should_unblock(self, ip, block_data):
        """解除条件の評価"""
        # レベル1-3は自動解除
        if block_data['level'] in ['L1', 'L2', 'L3']:
            return True
            
        # レベル4-5は追加条件チェック
        if block_data['level'] in ['L4', 'L5']:
            # 最近のアクセスログを確認
            recent_attempts = self.check_recent_attempts(ip)
            if recent_attempts == 0:
                return True
                
        return False
    
    def unblock_ip(self, ip, method='auto'):
        """IPブロック解除"""
        # Redisから削除
        self.redis.delete(f"blocked:{ip}")
        
        # WAFルール更新
        self.update_waf_rules(ip, 'remove')
        
        # ログ記録
        self.log_unblock(ip, method)

インシデントレスポンス自動化

DDoS攻撃との複合攻撃にも対応できる、包括的な自動化フレームワークです。

インシデント自動対応フロー:

graph TD
    A[WAF Alert] -->|Threat Score > 80| B{Attack Type}
    B -->|Brute Force| C[Rate Limit]
    B -->|DDoS| D[CDN Shield]
    B -->|Injection| E[Block + Patch]
    
    C --> F[Monitor 5min]
    F -->|継続| G[IP Block]
    F -->|停止| H[解除]
    
    G --> I[Incident Report]
    I --> J[Root Cause Analysis]

パフォーマンスとコストの最適化

キャッシュ戦略

WAFのパフォーマンスを維持しながら、キャッシュを効果的に活用する方法です。

エンドポイント別キャッシュ設定:

エンドポイント キャッシュ TTL 除外条件 バイパス条件
/login 無効 - - -
/api/auth 無効 - - -
/static/* 有効 1年 なし なし
/api/public/* 有効 5分 認証ヘッダー エラーレスポンス
/dashboard Edge Side 10秒 Cookie有 POST/PUT/DELETE

CDNとの協調動作

CDNとWAFを組み合わせることで、パフォーマンスとセキュリティを両立します。

CDN-WAF統合アーキテクチャ
CDNエッジでの初期フィルタリング → WAFでの詳細検査 → オリジンサーバー保護の3層構造。**レイテンシを50%削減**しながら、DDoS耐性を100倍に向上。
エッジコンピューティング活用
Cloudflare WorkersやAWS Lambda@Edgeで、エッジロケーションでブルートフォース検知。データセンターまでの往復を削減し、**応答時間を10ms以下**に短縮。

コスト削減のベストプラクティス

WAFの運用コストを最大60%削減する実践的な方法です。

コスト最適化チェックリスト:

  • [ ] 不要なログの削減(デバッグログは開発環境のみ)
  • [ ] サンプリングレート調整(正常トラフィックは10%サンプリング)
  • [ ] リザーブドキャパシティの活用(AWS WAFで最大20%割引)
  • [ ] ルールの統合(類似ルールをまとめて課金単位削減)
  • [ ] 地域限定デプロイ(必要な地域のみ有効化)

月間コスト試算例(1000万リクエスト/月):

項目 最適化前 最適化後 削減額
WAF基本料金 $5 $5 $0
リクエスト料金 $60 $60 $0
ルール料金(20個) $20 $10(10個に統合) $10
ログ保存(S3) $50 $15(圧縮+サンプリング) $35
データ転送 $30 $20(CDNキャッシュ) $10
合計 $165 $110 $55(33%削減)

運用とトラブルシューティング

定期的なルール見直し

WAFルールは生き物です。定期的な見直しが不可欠です。

月次レビューチェックリスト:

  1. 効果測定

    • ブロック率の確認(目標:攻撃の95%以上)
    • 誤検知率の確認(目標:0.1%以下)
    • パフォーマンス影響(レイテンシ増加20ms以下)
  2. ルール最適化

    • 未使用ルールの削除
    • 重複ルールの統合
    • 優先順位の再調整
  3. 新脅威対応

    • 脅威インテリジェンス更新
    • 新しい攻撃パターンの追加
    • ゼロデイ対策の確認

誤検知対応プロセス

誤検知が発生した際の、迅速な対応プロセスです。

エスカレーションフロー:

段階 対応時間 アクション 責任者 ツール
検知 即時 アラート発報 - 監視システム
初動 5分以内 影響確認 NOC ダッシュボード
分析 15分以内 原因特定 L2エンジニア ログ分析
対処 30分以内 ルール修正orホワイトリスト L3エンジニア WAF管理画面
確認 45分以内 正常性確認 NOC 監視
報告 2時間以内 インシデントレポート マネージャー チケット

障害時の切り分け手法

WAF起因の障害を迅速に切り分ける手法です。

トラブルシューティングフローチャート:

症状:Webサイトにアクセスできない
↓
Q1: 特定のIPからのみ?
├─Yes→ IPがブロックされている → ブロックリスト確認
└─No→ Q2へ
↓
Q2: 特定のページのみ?
├─Yes→ 該当URLのルール確認 → ルール無効化テスト
└─No→ Q3へ
↓
Q3: エラーコードは?
├─403→ WAFブロック → ログで理由確認
├─429→ レート制限 → しきい値確認
├─502/504→ バックエンド問題 → オリジン確認
└─その他→ CDN/DNS確認

診断コマンド集:

# WAFバイパステスト(直接オリジンアクセス)
curl -H "Host: example.com" https://origin-server.com/test

# WAF経由アクセステスト
curl -v https://example.com/test

# 特定のUser-Agentでテスト
curl -H "User-Agent: TestBot/1.0" https://example.com/

# レート制限確認
for i in {1..20}; do curl -s -o /dev/null -w "%{http_code}\n" https://example.com/login; done

# WAFログ確認(AWS)
aws wafv2 get-sampled-requests --web-acl-arn $ACL_ARN --rule-metric-name ALL --scope REGIONAL --time-window StartTime=$(date -u -d '5 minutes ago' +%s),EndTime=$(date +%s) --max-items 100

# リアルタイムログ監視
tail -f /var/log/waf/access.log | grep -E "BLOCK|DENY|429|403"

まとめ

WAFによるブルートフォース攻撃防御は、適切な設定と継続的な運用により、95%以上の攻撃を防御できます。重要なのは、製品選定から始まり、段階的な防御層の構築、継続的な監視と改善のサイクルを確立することです。

成功のための重要ポイント:

  1. 多層防御の実装

    • レート制限だけでなく、IPレピュテーション、機械学習、行動分析を組み合わせる
    • 認証エンドポイントは特別に強固な保護を実装
  2. バランスの取れた設定

    • セキュリティとユーザビリティのトレードオフを常に意識
    • 誤検知を最小化しつつ、検知率を最大化
  3. 自動化による効率化

    • SOAR連携で24時間365日の自動対応
    • ただし人間による最終判断の仕組みは維持
  4. 継続的な改善

    • 月次でのルール見直し
    • 新しい攻撃手法への迅速な対応

WAFはブルートフォース攻撃全般に対する強力な防御手段ですが、それ単体では完全ではありません。技術的な実装と組み合わせ、包括的なセキュリティ体制を構築することが重要です。


よくある質問(FAQ)

Q: WAF導入後もブルートフォース攻撃を受けています。設定が間違っているのでしょうか?
A: WAFが攻撃を検知してブロックしているなら、正常に機能しています。重要なのは、攻撃が成功していないことです。確認すべきポイント:(1)ブロック率が90%以上か、(2)認証成功率に異常がないか、(3)レート制限が適切か。もし攻撃が通過している場合は、レート制限を5回/5分程度に強化し、IPレピュテーション機能を有効化してください。また、ログを分析して攻撃パターンを特定し、カスタムルールを追加することも重要です。
Q: レート制限を厳しくしすぎて、正当なユーザーがブロックされてしまいます。どうバランスを取ればよいですか?
A: 段階的エスカレーション方式を推奨します。最初の数回はJavaScriptチャレンジやCAPTCHAで対応し、それでも継続する場合のみブロックします。具体的には:(1)3回失敗→JavaScriptチャレンジ、(2)5回失敗→CAPTCHA表示、(3)10回失敗→15分間ブロック。また、既知の良質なIPアドレス(社内IP、VPN等)はホワイトリスト化し、レート制限を緩和します。ユーザーの行動パターンを2週間程度観察し、ベースラインを把握してから閾値を設定することが重要です。
Q: AWS WAFとCloudflare WAF、どちらを選ぶべきでしょうか?
A: 用途と既存環境によります。AWS環境に統合済みならAWS WAFが管理しやすく、CloudFront、ALB、API Gatewayとのネイティブ統合が利点です。一方、Cloudflareはグローバルエッジネットワークによる低レイテンシ、DDoS対策込み、機械学習ベースのBot対策が標準装備という利点があります。コスト面では、月間1000万リクエストまでならAWS WAF(約$65)、それ以上ならCloudflare(Pro $20+Enterprise要相談)が有利です。両方を併用し、Cloudflareでエッジ防御、AWS WAFで詳細制御という構成も効果的です。
Q: WAFログが膨大でコストがかかります。どう最適化すればよいですか?
A: ログの選択的保存とサンプリングで70%以上のコスト削減が可能です。(1)正常トラフィックは10%サンプリング、ブロックトラフィックは100%保存、(2)S3に保存する際はGZIP圧縮(容量80%削減)、(3)7日後にGlacierへ自動移行、(4)30日後にGlacier Deep Archiveへ、(5)90日後に削除。また、重要なメトリクスはElasticsearchに集約し、生ログはコンプライアンス要件の最小期間のみ保持します。CloudWatchよりS3直接保存の方が安価です。
Q: 機械学習ベースのWAFは本当に効果があるのでしょうか?誤検知が心配です。
A: 機械学習WAFは、従来のシグネチャベースでは検出困難な攻撃に対して非常に効果的で、検出率は90-95%に達します。ただし、導入初期は5-10%程度の誤検知が発生する可能性があります。成功のポイントは:(1)最初の2-4週間は「監視モード」で学習させる、(2)業務特性を考慮したカスタムモデルのトレーニング、(3)機械学習の判定を単独で使わず、他のルールと組み合わせたスコアリング方式の採用、(4)定期的なモデルの再トレーニング。これらにより、3ヶ月後には誤検知率を1%以下に抑えることが可能です。

【重要なお知らせ】

  • 本記事は一般的な技術情報の提供を目的としており、特定の環境での動作を保証するものではありません
  • セキュリティ設定の変更は、必ずテスト環境で検証してから本番環境に適用してください
  • WAF設定の誤りは、正当なユーザーのアクセスを妨げる可能性があります
  • 記載内容は2025年1月時点の情報であり、製品の機能や価格は変更される可能性があります
  • 実装の際は、各製品の最新ドキュメントを必ず確認してください

更新履歴

初稿公開

京都開発研究所

システム開発/サーバ構築・保守/技術研究

CMSの独自開発および各業務管理システム開発を行っており、 10年以上にわたり自社開発CMSにて作成してきた70,000以上のサイトを 自社で管理するサーバに保守管理する。