Bot Management 모범 사례
📖 공식 문서 🌐 대시보드
Cloudflare Bot Management

Bot Management 모범 사례 봇 탐지 및 완화를 위한 완벽 가이드

Cloudflare Bot Management의 포괄적인 가이드입니다. 봇 탐지 메커니즘부터 오탐지 처리, Waiting Room 통합까지 실전 모범 사례를 상세히 설명합니다.

보안 Bot Management Enterprise 한국어

📝 작성자: Security Engineering Team | 📅 최종 업데이트: 2026년 6월

소개

Bot Management는 자동화된 트래픽(봇)을 탐지하고 적절하게 처리하는 Cloudflare의 고급 보안 기능입니다. 악의적인 봇으로부터 사이트를 보호하면서 검색 엔진 크롤러와 같은 유익한 봇은 허용합니다.

Bot Management 작동 방식

Bot Management는 머신러닝과 휴리스틱 분석을 결합하여 각 요청이 사람에 의한 것인지 봇에 의한 것인지 판단합니다.

  • TLS 지문 (JA3/JA4): 클라이언트의 TLS 핸드셰이크 패턴 분석
  • 행동 분석: 요청 패턴, 타이밍, 빈도 평가
  • JavaScript 챌린지: 브라우저 환경 검증
  • 머신러닝 모델: Cloudflare 네트워크 전체 데이터로부터 학습

Bot Score란?

Bot Score는 1~99의 숫자로, 요청이 봇일 가능성을 나타냅니다:

점수 판정 설명
1 🤖 확실한 봇 자동화 트래픽으로 확인됨
2-29 ⚠️ 봇일 가능성 높음 봇의 특징을 보이지만 확실하지 않음
30-99 👤 사람일 가능성 높음 일반 사용자로 처리됨

⚠️ 중요 사항

Bot Score가 30 이상이어도 실제로는 봇인 경우가 있습니다(False Negative). 고급 봇은 사람의 브라우저를 모방하여 높은 점수를 얻을 수 있습니다.

봇 탐지 메커니즘

JA3/JA4 지문

JA3와 JA4는 TLS 핸드셰이크에서 생성되는 지문으로, 클라이언트의 "지문" 역할을 합니다.

JA3 지문

TLS Client Hello 메시지에서 다음 정보를 추출합니다:

  • TLS 버전
  • 암호화 스위트
  • 확장 기능
  • 타원 곡선
  • 타원 곡선 포인트 포맷
// JA3 지문 예시
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 해시
abc123def456ghi789jkl012mno345pq

JA4 지문 (더 상세함)

JA4는 JA3을 개선하여 더 상세한 정보를 포함합니다:

// JA4 지문 예시
t13d1516h2_8daaf6152771_02713d6af862

형식: [프로토콜][암호 정보]_[확장 정보]_[서명 정보]

💡 실용적인 사용법

JA3/JA4는 WAF 규칙으로 직접 차단할 수 있습니다. 알려진 악의적인 봇의 지문을 블랙리스트에 추가하면 Bot Score와 관계없이 차단할 수 있습니다.

점수 알고리즘

Bot Management의 점수 부여는 여러 요소를 결합합니다:

  1. 정적 분석: User-Agent, 헤더 구성, TLS 지문
  2. 동적 분석: JavaScript 챌린지 응답, Canvas 지문
  3. 행동 분석: 요청 패턴, 타이밍, 세션 특성
  4. 머신러닝: 과거 트래픽 패턴으로부터 학습

검증된 봇

다음 봇들은 자동으로 검증되어 허용됩니다:

  • 🔍 검색 엔진: Google, Bing, Baidu 등
  • 📊 모니터링: Pingdom, UptimeRobot 등
  • 🤖 AI 크롤러: OpenAI, Anthropic 등
// 검증된 봇 확인 (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의 원인

  1. 완벽한 TLS 지문: 실제 브라우저와 구별 불가능
  2. JavaScript 실행: 챌린지에 정확히 응답
  3. 행동 모방: 사람처럼 자연스러운 무작위성
  4. 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. 허용 목록 생성
(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('검증됨!', { status: 200 });
    } else {
      return new Response('검증 실패', { status: 403 });
    }
  }
}

Waiting Room 통합

요청 처리 순서

Waiting Room과 Bot Management의 처리 순서를 이해하는 것이 중요합니다:

  1. 요청이 Cloudflare Edge에 도착
  2. Waiting Room이 먼저 평가 (대기열에 넣을지 판단)
  3. Bot Management가 점수 부여
  4. 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보다 먼저 실행됨
  • 쿠키를 반환하지 않는 봇이 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...",  // 알려진 봇 지문
  "def456..."
})

// Action: Block

문제 2: 쿠키를 반환하지 않는 봇이 FIFO 대기열 점유

증상:

  • FIFO Waiting Room에서 대기열이 진행되지 않음
  • Abandoning Users가 비정상적으로 많음
  • New Users Per Minute가 감소

원인:

FIFO (First-In-First-Out) 대기열에서는 맨 앞 사용자가 Waiting Room 쿠키를 반환하지 않으면 뒤따르는 사용자들이 진행할 수 없습니다. 봇은 쿠키를 반환하지 않으므로 대기열 맨 앞에서 5분간(Session Duration) 타임아웃을 기다리게 되어 전체 대기열이 정체됩니다.

해결책:

1. Random 대기열로 변경
// FIFO에서 Random으로 변경
{
  "queueing_method": "random",  // FIFO 대신 Random
  "session_duration": 5
}

Random 대기열에서는 쿠키를 반환하지 않는 봇이 대기열을 정체시키지 않습니다.

2. Session Duration 단축
// Session Duration을 5분 → 1분으로 단축
{
  "session_duration": 1  // 타임아웃까지 시간 단축
}
3. Turnstile 필수화

Turnstile을 활성화하면 쿠키를 반환하지 않는 봇이 대기열에 들어가기 전에 필터링됩니다.

문제 해결

점수 관련 문제

문제: 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"  // ← 점수가 계산되지 않음
}

해결책:

  1. Cloudflare 대시보드 → Security → Bots에서 Bot Management 활성화 확인
  2. Enterprise 플랜에서 Bot Management 구매 여부 확인
  3. 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를 활성화해도 봇이 통과

체크리스트:

🔍 조사 단계

  1. Bot Score 확인: Logpush로 실제 점수 가져오기
  2. JA3/JA4 확인: 봇의 TLS 지문 식별
  3. User-Agent 확인: 알려진 봇 User-Agent 체크
  4. 요청 패턴 확인: 빈도, 타이밍, 쿠키 유무
  5. 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 규칙 적용 결과
// - 응답 상태

사례 연구

사례 1: Waiting Room + 봇 문제

📋 사례 개요

고객: ZIPAIR (항공사)

문제: Bot Management 활성화에도 불구하고 봇이 Waiting Room을 통과

증상:

  • Bot Score 30 이상의 트래픽이 Waiting Room 슬롯 소비
  • 정당한 사용자가 대기열에서 오래 대기
  • Bot Management가 "사람"으로 판정하는 봇

조사 결과

Logpush 데이터 분석 결과:

  • Bot Score 35~50의 트래픽이 대량 존재
  • 동일한 JA3 Hash를 가진 요청이 초당 10건 이상
  • User-Agent는 정상 브라우저 모방
  • 쿠키를 반환하지 않음 (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. Waiting Room에 Turnstile 통합
{
  "turnstile_mode": "managed",
  "turnstile_action": "challenge"
}

// 3. 쿠키 없는 요청에 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가 정상 범위로

사례 2: False Negative 조사

📋 사례 개요

고객: 이커머스 사이트

문제: 플래시 세일 시 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          // 대부분 쿠키 없음
}

근본 원인

  1. False Negative: 봇이 Bot Score 42~85 획득
  2. 설정 오류: new_users_per_minute = 200 × session_duration = 5분 = 1000 가능 사용자
  3. 자동화 도구: 주거용 프록시 + 헤드리스 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 화이트리스트/블랙리스트 전략 구축