# 스크레이퍼 봇과 장난치기

> Clean Markdown view of GeekNews topic #24398. Use the original source for factual precision when an external source URL is present.

## Metadata

- GeekNews HTML: [https://news.hada.io/topic?id=24398](https://news.hada.io/topic?id=24398)
- GeekNews Markdown: [https://news.hada.io/topic/24398.md](https://news.hada.io/topic/24398.md)
- Type: GN+
- Author: [neo](https://news.hada.io/@neo)
- Published: 2025-11-17T03:33:20+09:00
- Updated: 2025-11-17T03:33:20+09:00
- Original source: [herman.bearblog.dev](https://herman.bearblog.dev/messing-with-bots/)
- Points: 4
- Comments: 1

## Topic Body

- 공개 웹사이트를 **과도하게 요청해 DDoS처럼 작동하는 스크레이퍼 봇** 문제를 다루며, 이를 역이용해 시간을 낭비시키는 실험적 접근 제시  
- **Markov 연쇄 기반 텍스트 생성기**를 만들어 `.php` 파일처럼 보이는 가짜 데이터를 생성, 악성 봇이 이를 다운로드하도록 유도  
- 이후 **정적 콘텐츠 서버**를 구축해 소설 *Frankenstein* 문단을 무작위로 제공, 링크 구조를 통해 크롤러가 폭발적으로 확산되도록 설계  
- 모든 페이지에 **`noindex, nofollow` 속성**과 요청 카운터를 추가해 정상 검색엔진은 제외하고 규칙을 어기는 봇만 포착  
- 실험 결과는 흥미로웠으나, **Googlebot 오탐 위험**으로 실제 서비스에는 적용하지 않고, 학습·실험용 프로젝트로 유지  

---

### 스크레이퍼 봇 문제와 대응 아이디어
- 스크레이퍼가 의도치 않게 **소규모 웹사이트에 DDoS 수준의 부하**를 유발  
- 일부 운영자들이 보호 방법을 문의했으나, 이번 글은 **“방어가 아닌 역공”** 에 초점  
- 다른 개발자가 **Markov 연쇄로 무한한 가짜 데이터를 생성해 봇을 속이는 사례**를 보고 직접 실험 시작  

### Markov 연쇄 기반 가짜 PHP 생성기
- Rust로 **Markov 연쇄 학습기**를 구현해 임의 텍스트 데이터를 기반으로 현실감 있는 콘텐츠 생성  
- `.env`, `.aws`, `.php` 등 **취약 경로를 노리는 악성 봇**을 대상으로, 실제처럼 보이지만 무의미한 PHP 코드 제공  
- 파일 크기를 2KB에서 10MB까지 늘려 **봇의 리소스 낭비 유도**  
- 예시 출력은 WordPress 함수명과 주석이 섞인 **그럴듯한 가짜 PHP 코드** 형태  
- 목표는 봇의 시간·자원 낭비와, 공격자가 실제 취약점을 찾으려 시간을 허비하게 만드는 것  

### 효율성과 정적 데이터 제공 실험
- VPS에서 1MB 이상 파일을 제공하자 **응답 지연과 서버 부하 증가** 발생  
- 이를 해결하기 위해 **정적 사이트 형태의 “garbage server”** 구축  
  - *Frankenstein* 소설 전체를 메모리에 로드하고, 요청마다 임의의 문단 4개를 반환  
  - 각 페이지 하단에 5개의 링크를 추가해 **폭발적 크롤링 확산(5배수 증가)** 유도  
- 결과물은 https://herm.app/babbler/ 에서 확인 가능  

### 설계 세부와 운영 방식
- 선택한 소설은 **공개 도메인**이며, **할로윈 시기**에 작업한 점과 **AI와 Frankenstein의 유사성**을 이유로 사용  
- 모든 페이지에 `noindex,nofollow` 속성을 부여해 **규칙을 어기는 봇만 포착**  
- 각 페이지 하단에는 **요청 횟수 카운터** 표시, 메모리 기반으로 배포 시 초기화  
- `.php` 요청용 별도 서버도 구성해, **실제 PHP 파일을 메모리에서 무작위로 제공**  
- “Garbage for the garbage king!”이라는 문구로 프로젝트를 요약  

### 위험성과 제한 사항
- 이 시스템은 **실제 서비스에 적용 시 검색엔진 오탐 위험** 존재  
  - Googlebot이 잘못된 엔드포인트를 긁으면 **스팸 사이트로 분류될 가능성**  
  - 검색 노출 저하나 **Chrome 경고 표시**로 이어질 수 있음  
- 따라서 **검색 의존 사이트에는 비추천**, 실험용 프로젝트로만 운영  
- `.php`용 babbler는 HTML이 아니므로 **Googlebot 영향 없음**, 악성 봇만 대상  

### 마무리와 개인적 결론
- 악성 스크레이퍼를 유인하기 위해 블로그에 **숨겨진 링크(rel="nofollow")** 추가  
- VPS의 **트래픽 한도 초과 시 Cloudflare 캐시 사용** 고려  
- 프로젝트를 통해 **Markov 연쇄와 봇 동작 원리**를 학습하며, 재미와 분노가 섞인 실험 진행  
- 결론적으로, **모든 시도가 실용적일 필요는 없으며**, 때로는 단순한 재미로도 충분함

## Comments



### Comment 46379

- Author: neo
- Created: 2025-11-17T03:33:21+09:00
- Points: 1

###### [Hacker News 의견](https://news.ycombinator.com/item?id=45935729) 
- 세상이 변해도 결국 비슷한 문제를 겪게 됨  
  10~15년 전 나는 **소셜 미디어 모니터링 서비스**들과 싸우고 있었음. 큰 브랜드들이 포럼의 감정을 모니터링하도록 그들에게 돈을 주었는데, 내가 운영하던 무료 커뮤니티를 무단으로 긁어가며 서버 부하를 일으켰음  
  그들의 **봇을 차단**해도 IP와 UA를 바꿔 돌아왔기에, 게시글에 무작위로 브랜드 이름을 삽입하는 필터를 만들어 그들의 데이터 품질을 망가뜨렸음. 이 조치를 켜자 이틀 만에 스크래핑이 완전히 멈췄음
  - 나도 비슷한 경험이 있음. 내 사이트의 **기부 폼을 신용카드 테스트용**으로 쓰던 봇이 있었는데, IP를 바꿔가며 계속 시도했음. 그래서 차단 대신 성공/실패 메시지를 무작위로 돌려줬더니, 그들의 데이터가 오염되어 며칠 만에 포기했음
  - 헤더 분석 이야기가 정말 유용했음. 내 **Fediverse 서버**에서도 오래된 Chrome UA를 쓰는 봇들이 Accept-Language 헤더를 전혀 안 보내는 걸 발견했음. nginx에서 403을 반환하도록 설정하니 트래픽이 줄기 시작했음
  - 영화 *The Imitation Game*처럼, 모든 요청에 즉각 반응하면 상대가 눈치챔. 일부 요청만 처리하거나 **무작위 오류 코드**를 주면 탐지하기 어려워지고, 그들의 디버깅을 훨씬 어렵게 만들 수 있음
  - 대부분의 봇은 여전히 **HTTP 헤더 세트**를 제대로 흉내 내지 못함. 2025년에도 같은 방식으로 필터링하게 되었고, 봇들은 여전히 같은 패턴으로 진화 중임
  - 왜 회사 이름을 삽입하면 봇이 사라졌는지 궁금함. 혹시 그들이 브랜드 언급을 찾는 과정에서 **데이터 신호가 오염**되어서 그런 것인지 묻고 싶음

- 이 봇들은 PHP 파일을 실제로 파싱하는 게 아니라, 그 존재 여부로 **취약점 탐지용 지문(fingerprinting)** 을 만드는 것임. 응답 코드만 보고 바로 버림
  - 맞음, 이런 경우엔 **fail2ban**이나 **crowdsec** 같은 도구가 더 효과적임. crowdsec을 써보니 트래픽이 적은 서버에서도 취약점 탐색 시도가 엄청 많다는 걸 알게 되었음
  - 그렇다면 일부러 **가짜 취약점**을 노출시켜 봇을 유인하는 전략도 가능할 듯함. 예를 들어, 자동화된 봇을 **허니팟(honeybot)** 으로 끌어들여 내부 동작을 관찰하는 식임. 참고: [The Cuckoo’s Egg](https://en.wikipedia.org/wiki/The_Cuckoo%27s_Egg)
  - 만약 LLM 스크래퍼들이 이런 응답을 학습 데이터로 쓴다면, **데이터 오염(poisoning)** 위험이 커질 수도 있음. 최근 논문에서도 소수의 데이터 포인트만으로도 모델을 망가뜨릴 수 있다고 했음

- 최근 **AI 및 스크래퍼용 타르핏(tarpit)** 이야기를 들었음. 연결을 끊지 않고 아주 느리게 무한 데이터를 흘려보내는 방식임. [Nepenthes](https://zadzmo.org/code/nepenthes/)라는 도구가 흥미로워서 실험해보고 싶음

- 예전엔 HN에서 스크래퍼를 막으면 비난받았음. “내가 어떻게 접근하든 상관없다”는 논리였음
  - 하지만 지금은 다름. 인간이 개인적으로 접근하는 것과, **AI 기업이 대량으로 DDoS 수준의 요청**을 보내는 건 완전히 별개임. 후자는 명백히 비용을 남에게 떠넘기는 행위임
  - 나도 **정상적인 스크래핑**은 괜찮다고 생각함. UA를 명시하고 robots.txt를 지키면 됨. 하지만 지금처럼 초당 수십 요청을 보내며 옛 Chrome 버전으로 위장하는 건 용납 불가임
  - 나는 학술 프로젝트로 하루 한 번씩 **구인 사이트를 스크래핑**함. 이런 건 합리적인 사용임. 반면, 분 단위로 콘텐츠를 긁어가거나 취약점을 찾는 건 완전히 다른 문제임
  - AI의 등장이 **윤리의식 자체를 약화**시키는 게 가장 우울함. 예전엔 자유를 중시하던 사람들이 이제는 저작권 강화나 익명성 제거를 요구함. 기술이 사람을 더 나쁘게 만들고 있음

- Apache 서버를 직접 관리한다면, **RewriteEngine**으로 PHP 요청을 바로 차단할 수 있음  
  ```apache
  RewriteEngine On
  RewriteCond %{REQUEST_URI} (\.php|%2ephp|%2e%70%68%70) [NC,OR]
  RewriteCond %{QUERY_STRING} \.php [NC,OR]
  RewriteCond %{THE_REQUEST} \.php [NC]
  RewriteRule .* - [F,L]
  ```
  내 서버엔 PHP가 없으니 이런 요청은 전부 악성임
  - nginx에서도 비슷하게 설정함. PHP나 ASPX 요청엔 **HTTP 418 “I’m a teapot”** 코드를 반환함  
    ```nginx
    location ~* \.(?:php|aspx?|jsp|dll|sql|bak)$ { return 418; }
    error_page 418 /418.html;
    ```  
    이렇게 하면 로그 필터링이 쉬워짐. 예시: [FreeSolitaire.win/wp-login.php](https://FreeSolitaire.win/wp-login.php)

- 대부분의 공격성 스크래퍼는 **WordPress 취약점**을 노림. PHP 파일 자체보다 그 **출력 결과**를 원함. 이런 설정은 일종의 **허니팟**에 가깝지만, 봇이 스크립트대로 안 움직이면 그냥 떠남
  - 아마 그들은 출력에서 **정규식으로 관리자 로그인 패턴**을 찾을 것임. 없으면 바로 건너뜀. 즉, 4KB짜리 가짜 PHP를 생성하는 것보다 정규식 한 줄이 훨씬 효율적임

- 예전에 **zipbomb 전략**을 HN에 올렸다가 트래픽이 하루 10만 건으로 폭증했음. $6짜리 VPS로는 감당 불가였음. 지금은 가장 공격적인 봇만 zipbomb으로 대응하고, 나머지는 403을 줌. 새 전략이 잘 먹히지만 다시 공개할지는 고민 중임. 참고: [이전 글](https://news.ycombinator.com/item?id=43826798)

- 예전엔 fail2ban만 썼지만, 좀 더 **재미있는 방어책**을 만들고 싶었음  
  `.htaccess`에서 의심스러운 경로(`/.git`, `/wp-login`)를 `decoy.php`로 리다이렉트하고, **10GB짜리 decoy.zip**을 강제 다운로드하게 함.  
  `decoy.php`는 요청된 민감 파일처럼 보이지만, 실제로는 **가짜 로그와 SQL 데이터**를 무한 스트리밍하여 봇을 붙잡아둠

- 이 봇들은 PHP 파일을 긁는 게 아니라, **프레임워크 취약점**을 찾는 것임. 예상치 못한 응답을 주면 바로 포기하고 다른 타깃으로 이동함

- 가끔 이런 생각을 함 — 봇들이 낭비하는 리소스로 **암호화폐를 채굴**하게 만들 수는 없을까?
  - 시도하려면 **JavaScript 실행**을 유도해야 하지만, 대부분의 봇은 이미 그런 시도를 막는 **대응책**을 갖고 있을 것임
