Bot Management ベストプラクティス Complete Guide to Bot Detection and Mitigation
Cloudflare Bot Management の包括的ガイド。ボット検知の仕組みから、誤検知の対処、Waiting Room との統合まで、実践的なベストプラクティスを解説します。
イントロダクション
Bot Management は、自動化されたトラフィック(ボット)を検知し、適切に処理するための Cloudflare の高度なセキュリティ機能です。 悪意のあるボットからサイトを保護しながら、検索エンジンクローラーなどの有益なボットは許可します。
Bot Management の仕組み
Bot Management は、機械学習とヒューリスティック分析を組み合わせて、各リクエストが人間によるものかボットによるものかを判定します。
- TLS フィンガープリント (JA3/JA4): クライアントの TLS ハンドシェイクパターンを分析
- 行動分析: リクエストパターン、タイミング、頻度を評価
- JavaScript チャレンジ: ブラウザ環境の検証
- 機械学習モデル: Cloudflare ネットワーク全体のデータから学習
Bot Score とは
Bot Score は 1〜99 の数値で、リクエストがボットである可能性を示します:
| Score | 判定 | 説明 |
|---|---|---|
1 |
🤖 確実にボット | 自動化トラフィックとして確認済み |
2-29 |
⚠️ ボットの可能性が高い | ボットの特徴を示すが、確証はない |
30-99 |
👤 人間の可能性が高い | 人間のユーザーとして扱われる |
⚠️ 重要な注意点
Bot Score 30 以上でも、実際にはボットである場合があります(False Negative)。 高度なボットは人間のブラウザを模倣し、高いスコアを獲得することがあります。
ボット検知の仕組み
JA3/JA4 Fingerprint
JA3 と JA4 は、TLS ハンドシェイクから生成されるフィンガープリントで、クライアントの「指紋」として機能します。
JA3 Fingerprint
TLS Client Hello メッセージから以下の情報を抽出:
- TLS バージョン
- 暗号スイート
- 拡張機能
- 楕円曲線
- 楕円曲線ポイントフォーマット
// JA3 Fingerprint の例
771,4865-4866-4867-49195-49199-49196-49200-52393-52392-49171-49172-156-157-47-53,0-23-65281-10-11-35-16-5-13-18-51-45-43-27-17513,29-23-24,0
// MD5 Hash
abc123def456ghi789jkl012mno345pq
JA4 Fingerprint (より詳細)
JA4 は JA3 を改良し、より詳細な情報を含みます:
// JA4 Fingerprint の例
t13d1516h2_8daaf6152771_02713d6af862
形式: [プロトコル][暗号情報]_[拡張情報]_[署名情報]
💡 実用的な使い方
JA3/JA4 は WAF ルールで直接ブロックできます。 既知の悪意のあるボットのフィンガープリントをブラックリストに追加することで、 Bot Score に関係なくブロック可能です。
スコアリングアルゴリズム
Bot Management のスコアリングは複数の要素を組み合わせます:
- 静的分析: User-Agent、ヘッダー構成、TLS フィンガープリント
- 動的分析: JavaScript チャレンジの応答、Canvas フィンガープリント
- 行動分析: リクエストパターン、タイミング、セッション特性
- 機械学習: 過去のトラフィックパターンからの学習
検証済みボット
以下のボットは自動的に検証され、許可されます:
- 🔍 検索エンジン: Google, Bing, Baidu など
- 📊 モニタリング: Pingdom, UptimeRobot など
- 🤖 AI クローラー: OpenAI, Anthropic など
// Verified Bot のチェック (WAF ルール例)
(cf.bot_management.verified_bot eq true)
and (cf.bot_management.ja3_hash eq "abc123...")
// Action: Allow
誤検知の理解
False Negatives (見逃し)
False Negative は、実際にはボットであるにもかかわらず、 Bot Management が人間と判定してしまう状況です。
🚨 False Negative の典型例
- 高度なヘッドレスブラウザ (Puppeteer, Playwright)
- 住宅用プロキシを使用したボット
- 人間のブラウザをエミュレートするツール
- Bot Score 30 以上を獲得する洗練されたボット
False Negative の原因
- 完璧な TLS フィンガープリント: 本物のブラウザと区別できない
- JavaScript 実行: チャレンジに正しく応答
- 行動の模倣: 人間らしいランダム性を持つ
- IP レピュテーション: クリーンな住宅用 IP を使用
対処方法
// 1. JA3/JA4 ベースのブロック
(cf.bot_management.ja3_hash in {"abc123...", "def456..."})
and (http.request.uri.path contains "/api")
// Action: Block
// 2. 行動パターンベースのルール
(http.request.uri.path contains "/login")
and (rate.requests.count > 10 per 60s)
and (cf.bot_management.score > 30)
// Action: Challenge
// 3. Turnstile の併用
// 高いスコアでも Turnstile でチャレンジ
False Positives (誤判定)
False Positive は、実際には人間であるにもかかわらず、 Bot Management がボットと判定してしまう状況です。
False Positive の原因
- 古いブラウザや非標準のブラウザ
- プライバシー拡張機能 (Privacy Badger など)
- VPN や企業プロキシ経由のアクセス
- JavaScript が無効化されている
- 自動化ツールを使用した正当なユーザー
対処方法
// 1. スコアの閾値を調整
(cf.bot_management.score < 10) // 確実なボットのみブロック
// Action: Block
// 2. 特定パスのみ厳しく
(cf.bot_management.score < 30)
and (http.request.uri.path contains "/checkout")
// Action: Challenge (Block ではなく Challenge)
// 3. Allow リストの作成
(cf.bot_management.score < 30)
and (not http.request.uri.path in {"/public", "/docs"})
// Action: Block
設定ガイド
動作モード (Block/Challenge/Log)
Bot Management には3つの主要な動作モードがあります:
| モード | 動作 | 推奨用途 |
|---|---|---|
| Log | ログのみ、アクションなし | 初期テスト、False Positive の確認 |
| Challenge | JavaScript/CAPTCHA チャレンジ | 一般的なボット対策、False Positive の最小化 |
| Block | 即座にブロック | 悪意のある既知のボット、API エンドポイント |
⚠️ 推奨されるアプローチ
本番環境に導入する前に、必ず Log モード で 1〜2 週間テストしてください。 False Positive の発生率を確認し、閾値を調整してから Challenge または Block に移行します。
WAF ルールとの統合
Bot Management を WAF ルールと組み合わせることで、より細かい制御が可能になります。
基本的な WAF ルール
// 1. 低スコアのボットをブロック
(cf.bot_management.score < 30)
// Action: Block
// 2. 中程度のスコアにチャレンジ
(cf.bot_management.score >= 30 and cf.bot_management.score < 80)
// Action: Managed Challenge
// 3. 検証済みボットを許可
(cf.bot_management.verified_bot eq true)
// Action: Skip (Bot Management をスキップ)
パスごとの異なる対応
// ログインページ: 厳しく
(http.request.uri.path eq "/login")
and (cf.bot_management.score < 50)
// Action: Block
// API エンドポイント: 非常に厳しく
(http.request.uri.path starts_with "/api/")
and (cf.bot_management.score < 80)
// Action: Challenge
// 公開コンテンツ: 緩く
(http.request.uri.path starts_with "/blog/")
and (cf.bot_management.score < 10)
// Action: Log
JA3/JA4 ベースのルール
// 既知の悪意のある JA3 をブロック
(cf.bot_management.ja3_hash in {
"abc123def456...",
"xyz789uvw012...",
"pqr345stu678..."
})
// Action: Block
// 特定の JA4 パターンにチャレンジ
(cf.bot_management.ja4 contains "t13d1516h2")
// Action: Challenge
Turnstile 統合
Turnstile は Bot Management を補完し、追加の検証レイヤーを提供します。
Turnstile を使うべき場面
- 🔐 ログイン/サインアップ: ブルートフォース攻撃の防止
- 💳 決済フロー: カード試行攻撃の防止
- 📝 フォーム送信: スパム送信の防止
- 🎫 Waiting Room: ボットがキューに入るのを防ぐ
バックエンド検証 (Cloudflare Workers)
// Turnstile トークンの検証
export default {
async fetch(request, env) {
const { token } = await request.json();
// Cloudflare Turnstile API で検証
const verifyUrl = 'https://challenges.cloudflare.com/turnstile/v0/siteverify';
const result = await fetch(verifyUrl, {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({
secret: env.TURNSTILE_SECRET,
response: token
})
});
const outcome = await result.json();
if (outcome.success) {
return new Response('Verified!', { status: 200 });
} else {
return new Response('Verification failed', { status: 403 });
}
}
}
Waiting Room との統合
リクエスト処理順序
Waiting Room と Bot Management の処理順序を理解することが重要です:
- リクエストが Cloudflare Edge に到達
- Waiting Room が先に評価 (キューに入れるか判定)
- Bot Management がスコアリング
- WAF ルールが適用される
🚨 重要な問題点
Waiting Room は Bot Management の前に実行されるため、 ボットが Waiting Room のキューに入ってしまう可能性があります。
Bot Management がボットを検知しても、すでに Waiting Room のスロットを 消費してしまっているため、正規ユーザーがキューで待たされる原因になります。
よくある問題
問題 1: ボットが Waiting Room スロットを消費
症状:
- Waiting Room の Active Users が予想より多い
- Bot Management Score 30 以上のトラフィックが多数
- 正規ユーザーがキューで長時間待機
原因:
- Bot Management の False Negative (高スコアのボット)
- Waiting Room が Bot Management の前に実行される
- Cookie を返さないボットが FIFO キューを占拠
解決策:
1. Turnstile を Waiting Room に統合
// Waiting Room 設定で Turnstile を有効化
{
"name": "prod_waiting_room",
"host": "example.com",
"path": "/sale",
"turnstile_mode": "managed", // ← 重要
"turnstile_action": "challenge",
"new_users_per_minute": 1000,
"total_active_users": 5000
}
2. WAF ルールでボットを Waiting Room 前にブロック
// Waiting Room パスへの低スコアボットをブロック
(http.request.uri.path contains "/waiting-room-path")
and (cf.bot_management.score < 30)
// Action: Block (Waiting Room に到達する前にブロック)
3. JA3/JA4 ベースのブロック
// 既知のボット JA3 を Waiting Room 前にブロック
(http.request.uri.path contains "/sale")
and (cf.bot_management.ja3_hash in {
"abc123...", // 既知のボット fingerprint
"def456..."
})
// Action: Block
問題 2: Cookie を返さないボットが FIFO キューを占拠
症状:
- FIFO Waiting Room でキューが進まない
- Abandoning Users が異常に多い
- New Users Per Minute が低下
原因:
FIFO (First-In-First-Out) キューでは、先頭のユーザーが Waiting Room Cookie を 返さないと、後続のユーザーが進めません。ボットは Cookie を返さないため、 キューの先頭で5分間(Session Duration)タイムアウトを待つことになり、 キュー全体が停滞します。
解決策:
1. Random キューに変更
// FIFO から Random に変更
{
"queueing_method": "random", // FIFO の代わりに Random
"session_duration": 5
}
Random キューでは、Cookie を返さないボットがキューを停滞させることはありません。
2. Session Duration を短縮
// Session Duration を 5分 → 1分 に短縮
{
"session_duration": 1 // タイムアウトまでの時間を短縮
}
3. Turnstile 必須化
Turnstile を有効にすることで、Cookie を返さないボットがキューに入る前にフィルタリングされます。
トラブルシューティング
スコアの問題
問題: Bot Score が常に 1 または 99
原因:
- Bot Management が有効化されていない
- Zone が Free プランで Bot Management が利用できない
- WAF ルールが Bot Management をスキップしている
確認方法:
// Logpush で Bot Score を確認
{
"ClientIP": "203.0.113.45",
"ClientRequestPath": "/api/endpoint",
"BotScore": 1, // ← スコアが 1 か 99 のみの場合は要注意
"BotScoreSrc": "Not Computed" // ← スコアが計算されていない
}
解決策:
- Cloudflare ダッシュボード → Security → Bots で Bot Management が有効か確認
- Enterprise プランで Bot Management が購入済みか確認
- WAF ルールで Skip ルールがないか確認
問題: Bot Score が予想と異なる
症状:
- 明らかなボットが Score 90 を取得
- 正規ユーザーが Score 20 を取得
デバッグ方法:
// Logpush で詳細を確認
{
"BotScore": 90,
"BotScoreSrc": "Machine Learning",
"JA3Hash": "abc123...",
"ClientRequestUserAgent": "Mozilla/5.0 ...",
"ClientIP": "198.51.100.78"
}
// JA3 Hash を確認
// User-Agent を確認
// IP レピュテーションを確認
ボットのバイパス
問題: Bot Management を有効にしてもボットが通過
チェックリスト:
🔍 調査ステップ
- Bot Score を確認: Logpush で実際のスコアを取得
- JA3/JA4 を確認: ボットの TLS フィンガープリントを特定
- User-Agent を確認: 既知のボット User-Agent かチェック
- リクエストパターンを確認: 頻度、タイミング、Cookie の有無
- WAF ルールを確認: Skip ルールやバイパスルールがないか
解決策: 多層防御アプローチ
// レイヤー 1: JA3 ベースのブロック (最優先)
(cf.bot_management.ja3_hash in {"abc123...", "def456..."})
// Action: Block
// Priority: 1
// レイヤー 2: 低スコアボットのブロック
(cf.bot_management.score < 30)
// Action: Block
// Priority: 2
// レイヤー 3: 行動パターンベースのチャレンジ
(rate.requests.count > 20 per 60s)
and (cf.bot_management.score < 80)
// Action: Managed Challenge
// Priority: 3
// レイヤー 4: Turnstile (フォーム送信、ログインなど)
// フロントエンドで実装
デバッグ手法
1. Logpush でボットトラフィックを分析
// Logpush フィールド設定
{
"ClientIP",
"ClientRequestHost",
"ClientRequestPath",
"ClientRequestUserAgent",
"EdgeStartTimestamp",
"BotScore",
"BotScoreSrc",
"JA3Hash",
"JA4",
"EdgeResponseStatus"
}
2. Analytics でパターンを確認
Cloudflare ダッシュボード → Security → Analytics → Bot Management
- Bot Score Distribution グラフで異常なパターンを確認
- Top User-Agents でボットの User-Agent を特定
- Top JA3 Hashes で悪意のあるフィンガープリントを特定
3. Ray ID でリクエストを追跡
// 問題のあるリクエストの Ray ID を取得
Ray ID: 8a1b2c3d4e5f6789-NRT
// Cloudflare ダッシュボードで検索
// Analytics → Logs → Ray ID で検索
// 詳細情報を確認:
// - Bot Score
// - JA3/JA4
// - WAF ルールの適用結果
// - レスポンスステータス
ケーススタディ
Case 1: Waiting Room + Bot 問題
📋 ケース概要
顧客: ZIPAIR (航空会社)
問題: Bot Management 有効にもかかわらず、ボットが Waiting Room を通過
症状:
- Bot Score 30 以上のトラフィックが Waiting Room スロットを消費
- 正規ユーザーがキューで長時間待機
- Bot Management が「人間」と判定しているボット
調査結果
Logpush データを分析した結果:
- Bot Score 35〜50 のトラフィックが大量に存在
- 同一の JA3 Hash を持つリクエストが毎秒 10 件以上
- User-Agent は正規のブラウザを模倣
- Cookie を返さない (Waiting Room Cookie なし)
根本原因
Bot Management False Negative: 高度なヘッドレスブラウザが 本物のブラウザを完璧に模倣し、Bot Score 30 以上を獲得していた。
解決策
// 1. JA3 ベースのブロックルール作成
(http.request.uri.path contains "/v1/waitingRoom")
and (cf.bot_management.ja3_hash in {
"abc123def456...", // 特定されたボット JA3
"xyz789uvw012..."
})
// Action: Block
// 2. Turnstile を Waiting Room に統合
{
"turnstile_mode": "managed",
"turnstile_action": "challenge"
}
// 3. Cookie なしリクエストへの Rate Limiting
(http.request.uri.path contains "/v1/waitingRoom")
and (not http.cookie contains "__cfwaitingroom")
and (rate.requests.count > 5 per 60s)
// Action: Challenge
結果
- ✅ ボットトラフィックが 95% 減少
- ✅ 正規ユーザーの待機時間が 70% 短縮
- ✅ Waiting Room Active Users が正常範囲に
Case 2: False Negative 調査
📋 ケース概要
顧客: E コマースサイト
問題: フラッシュセール時に 600 ユーザーが同時接続 (設定は 200 まで)
症状:
- Waiting Room の制限を超過
- サイトが 30 分間ダウン
- Bot Management は有効だが効果なし
調査結果
// Analytics から判明した事実
{
"total_requests": 15000,
"bot_score_30_plus": 12000, // 80% が「人間」判定
"unique_ja3_hashes": 5, // わずか 5 種類の JA3
"high_abandonment": true, // 放棄率 90%
"no_cookies": 11000 // ほとんどが Cookie なし
}
根本原因
- False Negative: ボットが Bot Score 42〜85 を獲得
- 設定ミス: new_users_per_minute = 200 × session_duration = 5min = 1000 可能ユーザー
- 自動化ツール: 住宅用プロキシ + ヘッドレス Chrome の組み合わせ
解決策
// 1. JA3 パターンのブロック
(cf.bot_management.ja3_hash in {"abc", "def", "ghi", "jkl", "mno"})
// Action: Block
// 2. Waiting Room 設定の最適化
{
"new_users_per_minute": 50, // 200 → 50 に削減
"session_duration": 1, // 5 → 1 に短縮
"turnstile_mode": "managed" // Turnstile 追加
}
// 3. Rate Limiting 追加
(rate.requests.count > 3 per 10s)
and (http.request.uri.path eq "/flash-sale")
// Action: Challenge
教訓
⚠️ 重要な学び
- Bot Management だけでは不十分 (多層防御が必要)
- Waiting Room 設定の数学的検証が重要
- フラッシュセール前に Turnstile 必須化を推奨
- JA3 ホワイトリスト/ブラックリスト戦略の構築