TELEPASI

검색하기 전에 통하다

웹사이트 악성 봇 차단 실전 가이드

강병우
2026.07.20 👁️ 128

검색엔진 봇은 환영하고, 악성 봇은 차단하는 IP 기반 nginx 실전 가이드

telepasi.com 적용 사례:

  • VPS + nginx 환경
  • IP 주소 기반 차단 (User-Agent 위조 불가)
  • 검색엔진 공식 IP 대역 검증으로 오차단 방지

목차

  1. 봇 타입의 이해
  2. 봇 감지 및 분류
  3. 로그 저장 테이블
  4. nginx 차단 설정
  5. 외부 IP 데이터베이스
  6. FAQ

1. 봇 타입의 이해

웹사이트를 방문하는 봇은 크게 네 가지로 분류됩니다:

🔍 검색엔진 봇 (환영)

  • Google: Googlebot
  • Bing: Bingbot
  • Naver: Yeti
  • Daum: Daumoa
  • 기타: Yandex, Baidu

역할: 사이트를 크롤링하여 검색 결과에 반영 (SEO 필수)

🤖 AI 크롤러 (선택적 환영)

  • ClaudeBot: Anthropic의 AI 학습용
  • GPTBot: OpenAI의 ChatGPT 학습용
  • Bing AI: Microsoft의 AI 서비스용

역할: AI 모델 학습을 위한 데이터 수집

📊 SEO 분석 크롤러 (선택적 환영)

  • SemrushBot: SEO 분석 도구
  • AhrefsBot: 백링크 분석
  • MJ12bot: Majestic SEO

역할: 사이트 SEO 점수 및 백링크 분석

⚠️ 악성 봇 (차단 필요)

스캐너 툴:

  • Nmap / Nikto: 웹 취약점 진단 및 침투 스캔
  • ZmEu / Zgrab / Masscan: 무차별 포트/페이지 스캔
  • DirBuster / Go-http-client: 숨겨진 디렉터리/파일 탐색
  • GitFinder: Git 설정 파일 (.git, .env) 탐색
  • sqlmap: SQL 인젝션 공격 자동화

역할: 취약점 탐색, 데이터 무단 수집, 서버 부하 유발


2. 봇 감지 및 분류

2.1 User-Agent 기반 감지

function detectBotType(userAgent) {
  const ua = userAgent.toLowerCase();
  
  // 검색엔진
  if (ua.includes('googlebot')) return 'google';
  if (ua.includes('bingbot')) return 'bing';
  if (ua.includes('yeti')) return 'naver';
  if (ua.includes('daumoa')) return 'daum';
  
  // AI 크롤러
  if (ua.includes('claudebot')) return 'claudebot';
  if (ua.includes('gptbot')) return 'gptbot';
  
  // SEO 크롤러
  if (ua.includes('semrush')) return 'semrush';
  if (ua.includes('ahrefs')) return 'ahrefs';
  if (ua.includes('mj12bot')) return 'mj12bot';
  
  // 악성 봇
  if (ua.includes('gitfinder')) return 'malicious';
  if (ua.includes('sqlmap')) return 'malicious';
  if (ua.includes('nikto')) return 'malicious';
  if (ua.includes('nmap')) return 'malicious';
  if (ua.includes('masscan')) return 'malicious';
  if (ua.includes('zgrab')) return 'malicious';
  if (ua.includes('zmeu')) return 'malicious';
  if (ua.includes('dirbuster')) return 'malicious';
  if (ua.includes('go-http-client/1.1')) return 'malicious';
  
  // 일반 봇
  if (ua.includes('bot') || ua.includes('crawler')) return 'other';
  
  return null; // 일반 사용자
}

2.2 검색엔진 공식 IP 대역

User-Agent는 위조 가능하므로 IP로 검증합니다.

-- Google
66.249.64.0/19
34.147.0.0/16
216.58.192.0/19

-- Naver
125.209.235.0/24
211.249.46.0/24
110.93.150.0/24

-- Bing
40.77.167.0/24
40.77.202.0/24
157.55.39.0/24
207.46.13.0/24

-- Daum
211.249.220.0/24
121.53.105.0/24

2.3 악성 IP 대역 (예시)

-- GitFinder 등 악성 스캐너
185.93.89.0/24

-- Hetzner 악용 사례
144.76.0.0/16

-- 악성 스캔 빈발
217.182.0.0/16

3. 로그 저장 테이블

3.1 기본 로그 테이블 구조

-- 조회 로그 테이블 (예: loan_view_logs, post_view_logs)
CREATE TABLE view_logs (
  id BIGSERIAL PRIMARY KEY,
  
  -- 사용자 식별
  session_id TEXT,              -- 비로그인 세션 (localStorage)
  user_id UUID,                 -- 로그인 사용자 (nullable)
  
  -- 접속 정보
  ip INET NOT NULL,             -- IP 주소 (CIDR 매칭 가능)
  user_agent TEXT,              -- User-Agent 원문
  device TEXT,                  -- mobile, desktop, bot
  
  -- 봇 분류 (핵심!)
  bot_type TEXT CHECK (bot_type IN (
    'google', 'bing', 'naver', 'daum', 'yandex', 'baidu',  -- 검색엔진
    'claudebot', 'gptbot', 'bingbot_ai',                    -- AI 크롤러
    'semrush', 'ahrefs', 'mj12bot',                         -- SEO 크롤러
    'malicious',                                            -- 악성 봇
    'other', NULL                                           -- 기타, 일반사용자
  )),
  
  -- 조회 내용
  page_type TEXT,               -- list, detail 등
  product_id TEXT,              -- 상품/게시물 ID
  action_type TEXT,             -- view, compare, filter 등
  
  referrer TEXT,
  created_at TIMESTAMPTZ DEFAULT NOW()
);

-- 성능 최적화 인덱스
CREATE INDEX idx_view_logs_created_at ON view_logs(created_at DESC);
CREATE INDEX idx_view_logs_bot_type ON view_logs(bot_type) WHERE bot_type IS NOT NULL;
CREATE INDEX idx_view_logs_ip ON view_logs USING GIST(ip inet_ops);

3.2 로그 저장 API 예시

// SvelteKit API 엔드포인트 예시
export async function POST({ request, locals }) {
  const userAgent = request.headers.get('user-agent');
  const clientIP = request.headers.get('x-forwarded-for')?.split(',')[0] 
                   || request.headers.get('x-real-ip');
  
  // User-Agent 분석
  const botType = detectBotType(userAgent);
  const device = botType ? 'bot' : detectDevice(userAgent);
  
  // 로그 저장
  await supabase.from('view_logs').insert({
    session_id: sessionId,       // 클라이언트에서 전송
    user_id: locals.user?.id,    // 로그인 시
    ip: clientIP,
    user_agent: userAgent,
    device: device,
    bot_type: botType,
    page_type: 'detail',
    product_id: productId,
    action_type: 'view',
    referrer: request.headers.get('referer'),
    created_at: new Date().toISOString()
  });
}

4. nginx 차단 설정

4.1 IP 기반 차단

텔레파시 닷컴의 차단 방식:

telepasi.com은 IP 기반 차단을 사용합니다. VPS에서 nginx를 직접 운영하며, 악성 봇의 IP 주소를 목록으로 관리하여 차단합니다.

선택 이유:

  • 정확성: IP는 위조 불가능 (User-Agent는 위조 가능)
  • 효율성: 패킷 레벨에서 차단하여 서버 리소스 절약
  • 간편성: IP 목록만 관리하면 됨
  • 검증 가능: 공식 검색엔진 IP 대역으로 오차단 방지

차단 목록 파일

봇 구분

# /etc/telepasi/blocked_ips.list
# 한 줄에 하나씩 IP 또는 CIDR 기록

# 악성 봇
185.93.89.0/24  # GitFinder - 2026-07-19

# 단일 IP 예시
# 203.0.113.10

# 주석과 빈 줄은 무시됨

nginx 설정

# /etc/nginx/conf.d/00-blocked-ips.conf
# 이 파일은 스크립트로 자동 생성됨 (직접 편집 금지)

deny 185.93.89.0/24;
# deny 203.0.113.10;

적용 스크립트

#!/bin/bash
# /usr/local/bin/telepasi-apply-ip-blocks.sh
# 차단 목록을 읽어 nginx에 적용

set -euo pipefail

BLOCK_LIST="/etc/telepasi/blocked_ips.list"
NGINX_CONF="/etc/nginx/conf.d/00-blocked-ips.conf"

# 차단 IP/대역 읽기
IPS=$(grep -v '^#' "$BLOCK_LIST" | grep -v '^$' | awk '{print $1}')

# nginx 설정 생성
echo "# Auto-generated - DO NOT EDIT" > "$NGINX_CONF"
while IFS= read -r ip; do
  echo "deny $ip;" >> "$NGINX_CONF"
done <<< "$IPS"

# 적용
nginx -t && nginx -s reload
echo "✅ 차단 목록 적용 완료"

사용 방법

# 1. 차단 목록에 IP 추가
sudo nano /etc/telepasi/blocked_ips.list

# 2. 적용
sudo /usr/local/bin/telepasi-apply-ip-blocks.sh

4.2 User-Agent 기반 차단 (참고용)

주의: telepasi.com은 User-Agent 기반 차단을 사용하지 않습니다. IP 기반 차단만 사용합니다.

IP를 자주 바꿔가며 공격하는 봇에 대한 추가 방어 수단으로 User-Agent 차단을 사용할 수 있습니다.

# /etc/nginx/conf.d/block-bad-bots.conf

map $http_user_agent $bad_bot {
    default 0;
    
    # 악성 스캐너 툴
    ~*nikto 1;
    ~*nmap 1;
    ~*masscan 1;
    ~*zgrab 1;
    ~*zmeu 1;
    ~*sqlmap 1;
    ~*dirbuster 1;
    ~*gitfinder 1;
    ~*go-http-client/1.1 1;
}

server {
    # ...
    
    if ($bad_bot) {
        return 403;
    }
}

주의:

  • wget, curl은 정상 API 클라이언트도 사용하므로 신중히 차단
  • 봇이 User-Agent를 위조할 수 있으므로 IP 차단과 병행 필요

4.3 iptables 차단 (선택사항)

nginx 전에 패킷 레벨에서 차단하여 서버 리소스를 아낍니다.

# iptables 체인 생성
sudo iptables -N TELEPASI_BLOCK
sudo iptables -I INPUT 1 -j TELEPASI_BLOCK

# IP 차단
sudo iptables -A TELEPASI_BLOCK -s 185.93.89.0/24 -j DROP

# 체인 종료
sudo iptables -A TELEPASI_BLOCK -j RETURN

# 확인
sudo iptables -L TELEPASI_BLOCK -n

5. 외부 IP 데이터베이스

5.1 AbuseIPDB (추천)

전 세계 웹마스터의 실시간 신고 기반 최대 데이터베이스

  • URL: https://www.abuseipdb.com/
  • 특징: 상위 10,000개 악성 IP 목록 API로 다운로드 가능
  • 무료: 일일 1,000회 API 호출
  • 활용: 차단 전 IP 위험도 조회
# API 예시 (무료 키 발급 필요)
curl -G https://api.abuseipdb.com/api/v2/check \
  --data-urlencode "ipAddress=185.93.89.147" \
  -H "Key: YOUR_API_KEY" \
  -H "Accept: application/json"

5.2 Firehol IP Lists

전 세계 60개 이상 보안 기관 블랙리스트 통합

  • URL: https://iplists.firehol.org/
  • 제공: firehol_level1 (최고 위험), firehol_level2, firehol_level3
  • 무료: 완전 오픈소스, 매일 업데이트
# Level 1 악성 IP 다운로드
wget https://iplists.firehol.org/files/firehol_level1.netset

# nginx 차단 목록 변환
cat firehol_level1.netset | grep -v '^#' | awk '{print "deny "$1";"}' > /etc/nginx/conf.d/firehol-blocks.conf

5.3 Emerging Threats

Snort, Suricata 방화벽용 실시간 룰셋

5.4 CISA (정부 기관)

미국 사이버보안청 공식 IoC (침해지표) 목록


6. FAQ

Q1: AI 크롤러(ClaudeBot, GPTBot)는 차단해야 하나요?

선택사항입니다.

  • 허용: AI 모델 학습에 기여, 잠재적 노출 기회
  • 차단: 서버 리소스 절약, 콘텐츠 보호

허용하되 robots.txt로 제어 권장:

User-agent: GPTBot
Disallow: /admin/
Disallow: /api/

User-agent: ClaudeBot
Crawl-delay: 10

Q2: SEO 크롤러는 차단해야 하나요?

SemrushBot, AhrefsBot은 SEO 분석 도구입니다.

  • 경쟁사가 내 사이트를 분석할 수 있음
  • 서버 부하 유발 가능

권장: robots.txt로 크롤링 빈도 제한

User-agent: SemrushBot
Crawl-delay: 60

User-agent: AhrefsBot
Crawl-delay: 60

Q3: 차단 방법 중 무엇을 선택해야 하나요?

방식 비용 제어권 난이도 적합한 경우
VPS + nginx 낮음 최고 기술 중심 스타트업, 개발자
Cloudflare 무료~$20+ 낮음 중소형 사이트, 빠른 적용
AWS WAF 높음 대기업, AWS 인프라
Fail2ban 무료 높음 자동화 필요 시

telepasi.com의 선택: VPS + nginx + IP 기반 차단

  • VPS에서 직접 운영 (완전한 제어권)
  • CDN 비용 절약
  • IP 기반 차단으로 정확성과 효율성 확보
  • User-Agent 위조 불가능한 IP로만 차단
  • 검색엔진 공식 IP 대역으로 오차단 방지
  • 빠른 테스트 및 적용

Q4: 검색엔진 봇을 실수로 차단하면?

Google Search Console에서 크롤링 오류가 급증하며 검색 노출이 감소합니다.

대응:

# 검색엔진 IP가 차단되었는지 확인
grep -E "66.249|40.77|125.209|211.249" /etc/telepasi/blocked_ips.list

# 발견 시 즉시 제거 후 적용
sudo nano /etc/telepasi/blocked_ips.list
sudo /usr/local/bin/telepasi-apply-ip-blocks.sh

Q5: CDN(Cloudflare)을 사용하면 IP 차단이 의미 있나요?

CDN 사용 시 서버가 보는 IP는 CDN의 IP입니다.

  • 장점: CDN 레벨에서 차단 가능 (더 효과적)
  • 단점: 서버 레벨 차단은 CDN 우회 공격에만 유효

Cloudflare 사용 시 X-Forwarded-For 헤더로 실제 IP를 복원해야 합니다.


참고 자료

검색엔진 공식 문서

악성 IP 데이터베이스

기술 문서


주파수 소통방 (0)

로딩 중...