DX Bot Challenge 3.0.0 (+ DX Page Cache)
초기 버전(플러그인 폴더 3파일)에 대한 패치 배포입니다. 패치 내역은 아래 "패치 내역"을 보세요.
DXCMS용 봇 차단 패키지입니다. 악성 봇은 PHP·DB 없이 바로 막고, 허용 봇과 로그인한 관리자는 통과시키며, 나머지 방문자에게는 JS 챌린지를 한 번 거치게 합니다. 게시글 상세 페이지를 HTML로 캐시하는 DX Page Cache가 함께 들어 있습니다.
라이선스
DesignOneX License 1.0 — https://designonex.com/notice/view/1787577858493247
Copyright © DesignOneX — designonex.com · All Rights Reserved.
모든 소스 파일 머리말과 dx-page-cache의 manifest.php에 위 라이선스를 표기했습니다. (코어는 LGPL-3.0, 플러그인은 별개)
패치 내역 (초기 버전 → 3.0.0)
1. 설정 읽기에서 DB 부하 제거 (handler.php)
- 기존: 요청마다 설정값 하나씩 DB를 직접 조회했습니다.
- 변경: 메모리 → 파일 캐시(
plugins/dx-bot-challenge/.config_cache.php, 5분) → DB 순서로 읽습니다. DB는 캐시가 없거나 만료됐을 때만 조회하며, 이때 이 플러그인의 설정 전체를 한 번에 읽어 파일에 저장합니다. - 관리자에서 설정을 저장하면 캐시를 즉시 지웁니다. (
plugin.php저장 처리에clearCache()추가)
2. 통과 쿠키를 가장 먼저 검사 (handler.php)
- 기존: 봇 차단 사용 여부 확인 → 허용 봇 확인 → 챌린지 POST 처리 → 쿠키 확인 순서였습니다.
- 변경:
/admin/,/api/경로 통과 직후 쿠키를 먼저 검사합니다. 유효하면 DB를 읽지 않고 바로 통과합니다. "봇 차단 사용 안 함" 확인은 그 뒤로 옮겼습니다.
3. 비밀키는 파일 우선 (handler.php)
- 기존: DB 설정값 → 키 파일 → 자동 생성 순서였습니다.
- 변경: 키 파일(
.secret_key) → DB 설정값(있으면 파일에도 저장) → 자동 생성 순서입니다. 쿠키 검사에서 DB를 읽지 않게 하기 위한 변경입니다.
4. Gemini URL 읽기 허용 (handler.php, bot_guard)
- UA가 정확히
Google인 요청을 허용 봇으로 통과시킵니다. (Gemini의 URL 읽기)
5. 새로 포함된 파일
extend/top/00_aaaa_bot_guard.php(DX Bot Guard): 챌린지 이전 단계에서 PHP 본체와 DB 없이 처리합니다. UA 없음·10자 미만, 악성 UA 패턴은 즉시 403, 허용 봇과 유효 쿠키는 통과시키고 나머지는 챌린지 플러그인에 넘깁니다. 관리자가 추가한 허용 봇은 파일 캐시에서 읽습니다.- DX Page Cache 일체:
extend/top/00_aaab_page_cache.php,extend/bottom/00_page_cache_save.php,plugins/dx-page-cache/
6. 배포 정리
- DesignOneX License 1.0 표기 추가, 버전 표기 3.0.0 통일,
plugins/dx-bot-challenge/manifest.php추가 - PHP 5.6 호환 규칙에 맞춰 함수 결과를 바로 배열로 접근하던 두 곳(
bot_guard,handler.php의 IP 추출) 수정
변경 없음
- 관리자 화면
admin.php와 챌린지 발급·검증 방식(nonce·HMAC·SHA-256 응답), 허용 봇 목록은 초기 버전과 같습니다. (관리자 화면의 버전 문구만 3.0.0으로 변경)
패치 후 알아둘 점
- 초기 버전에서 올리는 경우
.config_cache.php와.secret_key가 플러그인 폴더에 새로 생깁니다. 폴더에 쓰기 권한이 필요합니다. 쓰기가 안 되면 캐시 없이 DB를 읽는 방식으로 동작하지만 부하 절감 효과는 없습니다. - 파일 캐시는 5분 간격으로 갱신되며, 설정을 저장하면 바로 갱신됩니다.
설치
zip은 사이트 루트 기준 경로입니다. 사이트 루트에 풀어 덮어쓰면 됩니다. DB 구조 변경은 없습니다.
extend/top/00_aaaa_bot_guard.php UA 필터 + 쿠키 확인 (DB 없음)
extend/top/00_aaab_page_cache.php 캐시가 있으면 즉시 응답
extend/bottom/00_page_cache_save.php 캐시 저장
plugins/dx-bot-challenge/ 챌린지 발급·검증, 관리자 화면(봇 차단), manifest.php
plugins/dx-page-cache/ 캐시 무효화 훅, 관리자 화면(Page Cache)
동작 순서 (bot_guard → 챌린지 플러그인)
/admin/,/api/경로는 통과합니다.- UA가 정확히
Google이면 통과합니다. (Gemini의 URL 읽기) - UA가 없거나 10자 미만이면 403.
- 악성 UA 패턴이면 403. (masscan, zgrab, python-requests, go-http-client, curl/, wget/, libwww-perl, java/, nikto, nmap, sqlmap, scrapy, semrushbot, ahrefsbot, mj12bot, dotbot, petalbot, bytespider, dataforseobot, ccbot, turnitinbot)
- 허용 봇이면 통과합니다. (googlebot, googleother, google-extended, google-safety, yeti, slurp, bingbot, gptbot, oai-searchbot, chatgpt-user, claude-user, claudebot, gemini, applebot, yandexbot, duckduckbot, baiduspider, perplexitybot) 관리자가 "추가 허용 봇"에 넣은 UA도 통과합니다.
- 유효한 통과 쿠키(
dx_bc_pass, IP 묶음 HMAC)가 있으면 통과합니다. DB를 읽지 않고 파일 캐시의 비밀키만 사용합니다. - 나머지는 DX Bot Challenge 플러그인이 JS 챌린지를 내고, 통과하면 쿠키를 발급합니다. 로그인한 관리자는 챌린지 없이 통과합니다.
AI·검색 크롤러와 사용자가 요청한 AI 읽기(ChatGPT-User, Claude-User, Gemini)는 항상 들어올 수 있게 허용 목록에 있습니다.
관리자 화면
- 봇 차단(
/admin/bot-challenge): 활성화, 로그 기록, 쿠키 유효시간(초), Secret Key, 추가 허용 봇, 오늘 차단 통계(JS 실패·봇 차단·IP 차단), 로그 보기 - Page Cache(
/admin/page-cache): 캐시 상태와 전체 삭제
DX Page Cache
- 비로그인 GET 요청 중
/view/가 들어간 주소만 캐시합니다. (기본 1시간) - 제외:
/admin/,/api/,/auth/,/install/, 로그인 쿠키가 있는 요청 - 게시글 수정·삭제, 댓글 작성·삭제 때 해당 캐시를 자동으로 지웁니다.
- 응답 헤더
X-DX-Cache: HIT로 확인합니다.
이번 배포 준비에서 바꾼 것
- DesignOneX License 1.0 표기를 모든 파일에 추가했습니다. (dx-page-cache의 manifest는 기존
LGPL-3.0표기를 이 라이선스로 교체) - PHP 5.6 호환 규칙에 맞춰 함수 결과를 바로 배열로 접근하던 두 곳(
bot_guard,handler.php의 IP 추출)을 풀어 썼습니다. 동작은 같습니다. - 버전 표기를 정리했습니다. (아래 버전 참고)
버전
- DX Bot Challenge(
bot_guard포함) 3.0.0 — 초기 버전에서의 변경은 위 "패치 내역"에 정리했습니다. - DX Page Cache 1.0.1 (manifest와 파일 머리말 표기를 맞춤)
plugins/dx-bot-challenge/manifest.php를 새로 추가했습니다.