검색엔진 봇은 환영하고, 악성 봇은 차단하는 IP 기반 nginx 실전 가이드
telepasi.com 적용 사례:
- VPS + nginx 환경
- IP 주소 기반 차단 (User-Agent 위조 불가)
- 검색엔진 공식 IP 대역 검증으로 오차단 방지
목차
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 방화벽용 실시간 룰셋
- URL: https://rules.emergingthreats.net/
- 제공: 봇넷, 악성 스캐너 IP 목록
- 무료: Open Ruleset
5.4 CISA (정부 기관)
미국 사이버보안청 공식 IoC (침해지표) 목록
- URL: https://www.cisa.gov/
- 제공: 국가 배후 해킹 조직, 고위험 봇넷 IP
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 데이터베이스
- AbuseIPDB - 실시간 신고 기반
- Firehol IP Lists - 통합 블랙리스트
- Emerging Threats - IDS/IPS 룰셋
- CISA - 정부 기관 IoC


주파수 소통방 (0)
로딩 중...