허니팟을 이용한 사용자 이름 열거: /u/*.json 스캔용 Cloudflare 스니펫

내 Discourse 포럼에 이같은 악성 스캐너가 끊임없이 쏟아지고 있습니다: 봇이 /u/<name>.json 경로에 워드리스트를 대조하며 요청을 보내고, 404 응답을 수집해 어떤 사용자명이 실제로 존재하는지 파악합니다. 각 프로브는 Unicorn 워커를 하나씩 소모시키고, 스캐너에게는 무료 정보까지 제공합니다.

Cloudflare 스니펫을 하나 만들어서 이러한 프로브를 엣지에서 신뢰할 수 있는 가짜 프로필로 응답하도록 해보았습니다. 200 상태 코드와 사용자명에서 파생된 안정적 ID, 가입일, 신뢰 수준, 게시글 수, 그리고 카나리 문자열이 포함된 가짜 이메일 주소까지 포함합니다. 실제 방문자는 그대로 통과됩니다. 세션 쿠키, 동일 사이트 referrer, Accept: text/html 헤더 또는 API 키가 있으면 "건드리지 마세요"라는 뜻입니다. 원본 서버는 프로브 요청을 전혀 받지 않으므로 부하가 증가하지 않고 오히려 감소합니다.

히트는 New Relic에 IP, ASN 및 네트워크 이름, 국가, 도시, 엣지 콜로, HTTP/TLS 버전, 사용자 에이전트, 그리고 프로브된 사용자명과 함께 로깅됩니다. 가져올 수 있는 11개 위젯으로 구성된 대시보드가 있으며, "누가 계속 다시 오는가"를 확인하기 위한 NRQL 쿼리도 있습니다.

스니펫 슬롯 하나면 됩니다. KV, Worker, 원본 변경, 차단 작업 모두 불필요합니다.
그래도 4개가 남으므로 계정 내 다른 사이트에도 활용할 수 있습니다.

저장소: GitHub - hhftechnology/cloudflare-honeypot: Cloudflare Snippet honeypot for user-enumeration scans (/u/*.json): fake 200 profile, New Relic logging, zero origin load · GitHub

문서에서는 Cloudflare 규칙(참고: matches 연산자는 Business 플랜이 필요합니다 — wildcard를 사용하세요), New Relic 가져오기(두 개의 플레이스홀더를 교체해야 하며 그렇지 않으면 실패합니다), Discourse 관련 주의 사항(내장된 hide user profiles from public 설정이 더 나은 해결책인 경우도 포함)을 다룹니다. 하지만 저의 경우에는 이 방법이 불가능했습니다.

누군가에게 도움이 되길 바랍니다. 배포 한 시간 만에 서버 부하가 줄었습니다.