
DX 스팸 차단 (dx-spamguard) v1.0.0 — 사용법 및 플러그인 내역
코어 파일을 수정하지 않고 글·댓글·회원가입·쪽지 스팸을 저장 전에 검사하는 DXCMS 플러그인입니다. PHP 5.6 ~ 8.x · DesignOneX License 1.0 · 관리자 주소
/admin/spamguard
1. 한눈에 보기
| 항목 | 내용 |
|---|---|
| 폴더 | plugins/dx-spamguard/ |
| 검사 대상 | 글(작성·답글·수정), 댓글, 회원가입, 쪽지, 추가 지정 주소 |
| 판정 | 통과 / 보류(관리자 확인 대기) / 차단(거부) |
| 방식 | 점수제 (근거마다 점수를 더해 기준과 비교) |
| 학습 | 관리자의 "정상 / 스팸 확정" 판정으로 학습 |
| 코어 수정 | 없음 (훅·출력 버퍼만 사용) |
| 테마·스킨 수정 | 없음 |
2. 설치
plugins/dx-spamguard/폴더를 사이트 루트에 업로드합니다.- 관리자 → 플러그인에서 DX 스팸 차단을 활성화합니다. (테이블이 자동 생성됩니다)
- 관리자 사이드바의 스팸 차단 메뉴로 들어갑니다. 보류 건이 있으면 빨간 숫자 배지가 붙습니다.
- 설정 → 모드를 "학습 모드" 로 두고 며칠 운영한 뒤, 검사 로그를 확인하고 "보호 모드"로 바꾸는 것을 권장합니다.
생성되는 테이블 (접두어 dx_ 기준)
| 테이블 | 용도 |
|---|---|
dx_sg_log |
검사 기록(점수, 근거, 내용 발췌, 판정) |
dx_sg_rules |
사용자 규칙 + 자동 학습 규칙 |
dx_sg_ban |
IP 차단 목록 |
dx_sg_tokens |
학습 모델의 단어 통계 |
dx_sg_hold |
보류된 댓글 보관 |
설정은 dx_settings 의 그룹 dx-spamguard (키 접두어 dxsg_)에 저장됩니다.
3. 동작 원리
요청(POST) ─▶ dx_extend_top 훅 (인증 직후·라우팅 직전)
├ 면제 대상? (관리자·제외 회원·제외 IP) → 통과
├ IP 차단 목록? → 즉시 차단
├ 점수 계산 (아래 4장)
└ 판정
통과 → 코어가 평소대로 저장
보류 → 저장은 하되 숨김 (글·댓글만)
차단 → 저장하지 않고 안내 문구 표시
판정 기준
| 점수 | 글 · 댓글 | 가입 · 쪽지 · 수정 · 기타 |
|---|---|---|
| 보류 점수(기본 50) 미만 | 통과 | 통과 |
| 보류 점수 이상 ~ 차단 점수(기본 90) 미만 | 보류 | 차단 |
| 차단 점수 이상, 또는 즉시 차단 근거 | 차단 | 차단 |
즉시 차단 근거: 허니팟이 채워짐, IP 차단 목록, 스팸으로 확정한 내용과 동일한 글.
보류 처리 방식
- 글:
status=2로 저장되어 목록·본문에 보이지 않습니다. 작성자는 "관리자 확인 후 게시됩니다" 안내를 받습니다. - 댓글:
comments테이블에서 빼서dx_sg_hold에 보관합니다. 그래서 최신댓글 위젯, 댓글 수, 검색, 알림에 전혀 나타나지 않습니다. 글쓴이에게 가는 실시간 알림도 제거합니다. - 관리자가 정상 처리하면 같은 ID로 복원되고 댓글 수와 알림이 정상 반영됩니다.
폼 보호 장치 삽입
- 출력 버퍼로 페이지의 POST 폼마다 숨은 입력칸(허니팟) 과 서명 토큰 을 자동으로 넣습니다. (
/admin,/api,/search폼은 제외) assets/sg.js가 AJAX(XHR/fetch) 요청에 토큰과 사람 행동 정보를 헤더로 붙이고,form.submit()으로 전송되는 폼도 갱신합니다.
4. 검사 항목과 점수 (기본값)
점수는 모두 더해집니다. 아래 표의 점수는 기본값이며 일부는 설정에서 바꿀 수 있습니다.
4-1. 자동 입력 프로그램 감지
| 근거 | 점수 | 비고 |
|---|---|---|
| 허니팟 입력칸이 채워짐 | +100 | 즉시 차단 |
| 서명 토큰 없음 | +55 (회원 +45) | 페이지를 열지 않고 직접 전송 |
| 서명 토큰 위조 | +60 | |
| 서명 토큰 만료 | +8 | 기본 24시간 |
| 폼을 연 뒤 너무 빨리 전송 | +50 | 기본 3초 미만 (가입은 6초) |
| 사람 행동 정보 없음 | +25 | 스크립트 미실행 |
| 마우스·키보드·터치 입력 0 | +30 | |
| Origin/Referer 둘 다 없음 | +20 | |
| 다른 사이트에서 전송 | +40 | |
| User-Agent 없음 | +40 | |
| 자동화 도구 User-Agent | +50 | python-requests, curl, selenium 등 |
4-2. 반복 행동
| 근거 | 점수 | 비고 |
|---|---|---|
| 속도 제한 초과 | +60 | 한도 2배 초과 시 +90 |
| 같은 내용 반복 등록 (본인) | +45 | 숫자만 바꾼 변형 포함 |
| 다른 사용자가 보낸 같은 내용 | +25 | |
| 같은 내용이 여러 IP에서 반복 | +60 | |
| 스팸으로 확정한 내용과 동일 | +100 | 즉시 차단 |
기본 속도 제한: 10분 안에 글 5개 · 댓글 10개 · 쪽지 15개, 가입은 같은 IP 60분에 3회.
4-3. 링크
| 근거 | 점수 |
|---|---|
| 허용 링크 수(기본 3) 초과 | 초과 1개당 +15 (최대 +45) |
| 비회원·가입 직후 회원의 링크 | +20 |
| 글 내용 없이 링크 위주 | +25 |
| 단축 URL (bit.ly 등) | +25 |
| 메신저·오픈채팅 링크 (t.me, open.kakao.com 등) | +15 |
| IP 주소 링크 | +20 |
| 퓨니코드 도메인 | +20 |
| 스팸에 자주 쓰이는 도메인(.xyz, .top, .bet …) | +15 |
| 숨겨진 링크 | +30 |
4-4. 내용 형태
| 근거 | 점수 |
|---|---|
| 한글 없는 외국어 본문 | +25 |
| 영어 본문 + 링크 (신규·비회원) | +10 |
| 같은 글자를 길게 반복 | +10 |
| 전화번호 포함 (신규·비회원) | +10 |
| 보이지 않는 문자 다수 | +15 |
4-5. 내장 스팸 사전
한국어는 공백·기호·전각·제로폭 문자를 제거한 뒤 찾기 때문에 카.지.노, 카 지 노 같은 우회 표기도 걸립니다. 영어는 단어 경계로 찾습니다. 분류마다 점수 상한이 있습니다.
| 분류 | 상한 | 예시 |
|---|---|---|
| 도박·토토 | 70 | 카지노, 바카라, 먹튀검증, 첫충 |
| 성인·유흥 | 70 | 조건만남, 출장안마, 야동 |
| 대출·현금화 | 60 | 무직자대출, 통장매입, 카드깡 |
| 의약품·약물 | 70 | 비아그라, 시알리스, 미프진 |
| 투자·알바 사기 | 60 | 리딩방, 수익보장, 재택알바, 텔레그램문의 |
| 홍보·마케팅 대행 | 50 | 상위노출, 백링크, 팔로워구매 |
| 가품·불법 판매 | 50 | 레플리카, 대포통장, 계정판매 |
| 해킹·감시·흥신소 | 50 | 카톡해킹, 흥신소, 대량문자 |
애매한 단어(예: "대출" 12점, "토토" 15점)는 낮은 점수라 단독으로는 보류되지 않고, 여러 개가 함께 나오거나 다른 근거와 합쳐질 때 보류됩니다. 오탐이 잦은 분류는 규칙·사전 탭에서 끌 수 있습니다.
4-6. 가입 전용
| 근거 | 점수 |
|---|---|
| 일회용 메일 도메인 (40여 개 내장) | +60 |
| 메일 도메인에 메일 서버 없음 | +50 (설정에서 켤 때만) |
| 이름·닉네임에 주소가 들어 있음 | +50 |
| 아이디가 거의 숫자 | +15 |
| 무작위처럼 보이는 아이디 | +15 |
| 메일 아이디에 점이 과다 | +10 |
4-7. 학습 모델 (베이지안)
스팸·정상 판정이 각각 20건 이상 쌓이면 활성화됩니다. 스팸 확률이 높으면 최대 +40, 정상 확률이 높으면 최대 −15 를 줍니다.
4-8. 신뢰 감점
가입 후 14일 이상, 정상 통과 5회 이상, 차단·스팸 판정 이력이 없는 회원은 합계에서 30점을 감점합니다. (즉시 차단 근거에는 적용되지 않음)
5. 관리자 화면 사용법
5-1. 대시보드
- 24시간 검사·통과·보류·차단·학습 모드 기록 수
- 확인 대기 중인 보류 건수와 바로가기
- 최근 14일 보류·차단 그래프, 많이 걸린 근거, 자주 걸린 IP(바로 차단 가능)
- 학습 상태(스팸·정상 판정 수와 시작 기준까지 남은 개수)
- 토큰 없는 요청이 30% 넘으면 경고 표시 (테마가
</body>를 출력하지 않는 등의 문제 점검용)
5-2. 검사 로그 (가장 자주 쓰는 화면)
필터: 결과(보류·차단·학습·통과), 종류(글·댓글·가입·쪽지 등), 판정, 기간, 검색(IP·아이디·이름·제목·내용)
각 행의 버튼:
| 버튼 | 동작 |
|---|---|
| 정상 | 보류 해제(글 게시 / 댓글 복원) + 정상으로 학습 + 자동 도메인 규칙 해제 |
| 스팸 | 글·댓글 숨김 + 스팸으로 학습 + 글 속 도메인을 자동 규칙으로 등록 (점수 60) |
| IP차단 | 해당 IP를 영구 차단 |
| 신뢰 | 해당 회원을 검사 제외 명단에 추가 |
| 글삭제 | 숨겨진 글·보류 댓글을 영구 삭제하고 기록도 삭제 |
| 기록삭제 | 검사 기록만 삭제 (글·댓글은 그대로) |
체크박스로 여러 건을 골라 선택 정상 / 선택 스팸 확정 을 한 번에 처리할 수 있습니다. "자세히"를 누르면 본문 전체, User-Agent, 주소를 볼 수 있습니다.
단축 URL·메신저 주소(bit.ly, t.me 등)는 도메인 자체를 막으면 정상 글까지 걸리므로 자동 규칙으로 등록하지 않습니다.
5-3. 규칙·사전
- 규칙 추가: 금칙어 · 정규식 · 차단 도메인 · 차단 메일 도메인 · IP · User-Agent · 허용 문구(감점)
- 적용 대상(글·댓글·가입·쪽지)을 골라 제한할 수 있고, 비워 두면 전체에 적용됩니다.
- 점수는 보류 기준 이상이면 단독으로 보류, 10~30점이면 의심만 합니다.
- 내 규칙 목록: 적중 횟수, 출처(직접 / 자동), 켜기·끄기, 삭제
- 내장 사전: 분류별로 켜고 끌 수 있습니다.
5-4. IP 차단
- IP 형식:
1.2.3.4·1.2.3.*·1.2.3.0/24 - 기간(시간, 0 = 영구)과 사유를 지정합니다.
- 차단된 IP는 글쓰기·댓글·가입·쪽지 전송만 막히고, 사이트 열람은 그대로 됩니다.
- 자동 차단: 1시간 안에 차단이 5회(설정 가능) 쌓이면 24시간(설정 가능) 자동 차단합니다.
5-5. 검사 테스트
문장·링크·이름·메일을 입력하면 저장 없이 점수와 근거를 보여 줍니다. 요청 신호(토큰·속도 제한 등)는 제외하고 내용만 검사합니다. 작성자 유형(비회원 / 가입 직후 / 오래된 회원)을 골라 볼 수 있어 규칙·점수를 다듬을 때 유용합니다.
5-6. 설정
| 구역 | 항목 |
|---|---|
| 동작 | 사용 여부, 모드(보호 / 학습), 보류 점수, 차단 점수, 검사 대상, 추가 검사 주소 |
| 봇 감지 | 허니팟, 서명 토큰, 사람 행동, 폼 자동 삽입, Origin/Referer, 자동화 UA, 최소 작성 시간, 토큰 유효 시간 |
| 속도·중복·링크 | 측정 시간, 글·댓글·쪽지·가입 한도, 허용 링크 수, 신규 회원 기준 시간, 중복 검사 시간, 외국어 본문 가산, 메일 DNS 확인 |
| 학습 | 내장 사전, 학습 모델, 자동 도메인 규칙, 학습 시작 기준 |
| 신뢰·제외 | 신뢰 회원 조건·감점, 제외 레벨, 제외 권한, 제외 회원 아이디, 제외 IP(내 IP를 꼭 넣어 두세요) |
| 자동 차단·보관 | 자동 IP 차단 조건, 로그 보관 일수(기본 60일, 확인 대기 보류는 삭제 안 함), 보류·차단 안내 문구 |
설정 하단에 학습 초기화 버튼이 있습니다. (단어 통계와 판정 횟수를 0으로 되돌림)
6. 권장 운영 순서
- 활성화 후 학습 모드로 3~7일 운영합니다. (아무것도 막지 않고 기록만 합니다)
- 검사 로그에서
보호 모드라면 차단/보류로 표시된 항목이 실제 스팸인지 확인합니다. 정상 글이 걸리면 점수·사전 분류를 조정하거나 정상을 눌러 학습시킵니다. - 내 IP와 운영자 계정을 설정의 제외 IP / 제외 회원 에 넣습니다.
- 보호 모드로 전환합니다.
- 이후에는 보류 배지(사이드바 · 로그 탭)를 보고 정상 / 스팸만 눌러 주면 사이트에 맞게 계속 학습합니다.
7. 확장 포인트
| 종류 | 이름 | 설명 |
|---|---|---|
| 필터 | dxsg_lexicon |
내장 스팸 사전을 다른 플러그인에서 가공·추가 |
사용 코어 훅: dx_extend_top, dx_board_before_save, dx_board_after_save, dx_after_comment, dx_body_bottom, dx_admin_top
8. 파일 구조
plugins/dx-spamguard/
├─ manifest.php 플러그인 정보
├─ plugin.php 훅 등록 · 관리자 연결
├─ README.md
├─ core/
│ ├─ db.php 테이블 · 설정 · 공용 함수
│ ├─ lexicon.php 내장 스팸 사전 · 도메인 목록
│ ├─ detect.php 점수 계산 엔진 · 베이지안
│ ├─ gate.php 요청 게이트 · 토큰 · 보류 · 폼 삽입
│ └─ learn.php 정상/스팸 판정 처리 · 자동 학습
├─ assets/
│ └─ sg.js 클라이언트(토큰·사람 행동 첨부)
└─ admin/
├─ index.php · actions.php · admin.css · admin.js · sidebar.js
└─ tabs/ dashboard · log · rules · ban · test · settings · _lib
9. 테스트 결과 요약
DXCMS 10.3.0 테스트 사이트(PHP CLI 서버 + MariaDB)에서 확인했습니다.
| 항목 | 결과 |
|---|---|
| 관리자 6개 탭 렌더링 | 오류·경고 없음 |
| 폼 자동 삽입 (허니팟·토큰·스크립트) | 정상 |
| 정상 회원의 글·댓글 | 0점 통과 |
| 도박 스팸 글·댓글 | 차단, 화면에 안내 문구 표시 |
| 토큰 없음 / 너무 빠른 전송 | 보류 |
| 허니팟 채움 · 자동화 UA | 차단 |
| 속도 제한 · 중복 · 여러 IP 반복 | 차단/가산 확인 |
| 자동 IP 차단 | 차단 5회 후 자동 등록, 다음 요청 즉시 차단 |
| 일회용 메일 가입 | 차단 (정상 형태 가입은 통과) |
| 보류 글 정상 처리 | 게시 상태로 복원 |
| 보류 댓글 정상 처리 | 같은 ID로 복원, 댓글 수·알림 반영 |
| 스팸 확정 | 숨김 + 도메인 자동 규칙(60점) + 학습, 이후 같은 도메인 글에 +60 |
| 학습 모드 | 스팸도 통과시키고 "보호 모드라면 차단"만 기록 |
| 관리자 계정 | 검사 제외 |
| 사이트 오류 로그 | 이 플러그인이 낸 오류·경고 없음 |
10. 알려진 한계
- 보류된 글을 승인해도 작성 시 지급된 포인트는 그대로이며, 스팸으로 확정해도 포인트는 회수하지 않습니다.
- 캡차를 대체하지 않고 보완합니다. 공격이 심해지면 코어의 캡차(Turnstile 등)를 함께 켜세요.
- 사람처럼 행동하는 고급 봇과 사람이 직접 올리는 스팸은 내용 기반 근거(사전·링크·중복·학습)로만 걸립니다. 그래서 운영하면서 판정을 눌러 주는 것이 중요합니다.
- 토큰은 페이지를 렌더링할 때 만들어지므로, 페이지 전체를 CDN에 캐시하는 환경에서는 토큰이 오래된 값으로 보일 수 있습니다(만료 기본 24시간, 만료 시 +8점만 부과).
- 테스트는 PHP 8 계열 CLI 서버에서 진행했고, PHP 5.6은 문법만 검토했습니다.
- 이 테스트 환경에서는 가입 페이지의 중복확인(jQuery CDN)이 동작하지 않아 테스트 회원은 DB에 직접 넣고 가입 요청은 직접 POST로 검사했습니다.
라이선스
DesignOneX License 1.0 (디자인원엑스 플러그인·스킨 라이선스) — https://designonex.com/notice/view/1787577858493247
Copyright © DesignOneX — designonex.com · All Rights Reserved.
- 허용: 무료 사용, 개인·학습·포트폴리오·비영리·상업(고객 프로젝트·SaaS 포함) 사용, 소스·디자인·CSS·기능 수정, 개발·커스터마이징·유지보수 비용 청구, 이 플러그인으로 만든 웹사이트·서비스 판매
- 금지: 원본 플러그인 재배포(무료·유료 모두), 플러그인 자체의 판매·단독 상품화·유료 멤버십 혜택 제공, 원본 소스가 포함된 수정본의 재배포·판매 (이름·스타일만 바꾼 경우도 예외 아님)
- 소스 코드의 DesignOneX 저작권·라이선스 표기를 고의로 제거·변경하지 마세요. (최종 사용자 사이트에 로고를 표시할 의무는 없습니다.)