일부 봇을 차단하는 방법
요약
무분별한 AI 봇 및 크롤러의 공격으로부터 동적 서비스를 보호하기 위한 다양한 방어 전략을 다룹니다. JavaScript 실행 여부 확인, 쿠키 검사, 트래픽 기반 차단 등 실질적인 대응 방안과 그에 따른 트레이드오프를 설명합니다.
핵심 포인트
- 동적 서비스(Forgejo 등)는 봇의 무한한 페이지 탐색으로 인해 서버 과부하 위험이 높음
- 단순 User-Agent 차단보다는 JS 실행 능력이나 리소스 요청 패턴을 검사하는 방식이 효과적임
- 검색 엔진 노출과 보안 사이의 절충안(쿠키 검사 등)을 고려해야 함
- 트래픽 양과 요청 빈도를 기준으로 차단하는 것이 브라우저 독점을 막는 합리적인 방법임
여러 공개 웹사이트를 운영하고 다른 사이트를 긁어 도구에 활용하는 입장에서, 왜 사람들이 봇을 그토록 신경 쓰는지 궁금함
캐시를 둔 WordPress도 가장 저렴한 VPS에서 초당 약 1,000개 요청을 처리하고, 제대로 만든 정적 사이트라면 그 10배도 가능할 듯함. 블로그를 Lambda 같은 것으로 제공하는 건지, 아니면 강박이나 취약점 방어, 크롤링이 실제 서비스에 영향을 주던 시절의 습관인지 궁금함
내 경우에는 Forgejo 인스턴스가 문제임. 블로그는 페이지 수가 제한된 정적 파일이라 괜찮지만, Forgejo는 봇이 사실상 무한히 페이지를 찾아낼 수 있고 일부 페이지를 만들 때 백그라운드에서 Git까지 실행하는 동적 서비스라 작은 서버가 쉽게 과부하됨
저장소는 오픈소스라 일부러 공개해 둠. 지금은 간단한 쿠키 검사로 방어하며 소수의 봇만 통과하지만, 검색 엔진 노출을 희생해야 하는 절충임
공유 호스팅의 개인 사이트가 끊임없는 AI 봇 크롤링으로 CPU를 과도하게 사용해 최근 정지됐음. 크롤링 자체보다 봇이 너무 많고 비효율적으로 동작하는 게 문제임
봇 운영자가 피하거나 우회하기 어려운 JavaScript 같은 공통 특성을 찾아보는 재미로 하는 실험임. 이 블로그는 RAM 디스크에 둔 사전 압축 정적 콘텐츠라 초당 수십만 요청도 처리할 수 있을 듯함
포럼, 이미지 게시판, 채팅 서버 등에 적용할 방법을 보여주려는 것이며 모든 선택지는 조정하거나 끌 수 있음. 실제 적용 전에는 시험 서버에서 검증해야 하고, 그냥 비웃고 넘어가도 괜찮음
집에서는 40Gbit 회선과 그에 맞는 서버를 마련할 수 없음. Google Cloud VPS 몇 대가 nmap과 각종 웹 취약점 검사를 돌리며 분산 서비스 거부 공격(DDoS)을 해도 저사양 장비의 성능은 쉽게 떨어짐
DMZ가 막혀 로컬 IMAP 서버를 확인하는 데 몇 초 더 걸리는 게 큰일은 아니지만, 그렇다고 이를 좋아하거나 계속 허용할 이유도 없음
봇 대응에 더 유용한 일을 할 시간을 빼앗기는 게 가장 큰 문제임
주말에 10~20년간 운영하던 viewvc(CVS·Subversion)와 hgweb(Mercurial) 웹 인터페이스를 종료했음. 주거용 프록시 IP에서 하루 270만 건, 평균 초당 30건의 요청이 들어와 오래된 uWSGI/CGI 프로그램과 같은 서버의 다른 사이트에 부담을 줬고, 트래픽도 VPS 한도인 월 1TB에 근접했기 때문임
동적 VCS URL 조합이 수백만 개일 수 있어 캐시 효과도 불확실하고, 서버를 더 조정하는 데 시간을 쓸 가치도 없어 결국 중앙집중형 인터넷에 한 걸음 더 가까워지는 선택을 했음
“승인된” 사용자 에이전트(User Agent) 외의 모든 것을 차단하면 기존 브라우저 독점을 돕고 디스토피아를 앞당기게 됨. RMS가 수십 년 전부터 경고한 것도 이런 문제임
문제가 된다면 트래픽 양과 요청 빈도를 기준으로 막아야 함. 나 역시 사이트에 접속할 수 없지만 이에 맞춰 행동할 생각은 없으며, DRM처럼 의지가 강한 상대는 결국 통과할 것임
그 비판은 받아들일 수 있음. RMS와 몇 번 함께했는데 흥미롭고 매우 영리한 사람이며, 이 문제로 만났다면 잔소리를 끝없이 들었을 듯함
다만 어떤 브라우저든 쓸 수 있다는 주장과 별개로, 즉흥적으로 생성한 코드이거나 악성 사이트에 맞서 충분히 검증되지 않은 브라우저는 특히 조심해야 함. 리더 앱도 침투 시험 전문가의 광범위한 제3자 코드 검토를 거치지 않았다면 악성 서버에 취약할 수 있음
동작을 기준으로 판단할 수도 있음. go-away는 이미지와 CSS를 불러오는지, 메타 새로고침 리디렉션을 따라가는지 검사하고, Anubis는 몇 초 동안 JavaScript 실행이 가능한지 확인함
사용자 에이전트 문자열 자체가 대체로 해로움. 새 브라우저라면 그냥 Chrome 사용자 에이전트를 복사하는 편이 나음
169.254.169.254를 가리키는 가짜 cpanel 하위 도메인을 추가하면 초보 공격자가 자기 호스팅 업체를 포트 스캔하게 되어 탐지되거나 차단될 수 있다는 발상이 마음에 듦
처음 실험했을 때는 아무 일도 없을 줄 알았음. 며칠 안에 독일 Amazon EC2의 한 사람이 피해야 할 레코드를 찾으려는 듯 내 도메인 일부에 영역 전송 (Zone Transfer)을 시도하더니, 이후 내 도메인을 완전히 제외했고 스캔도 곧 멈췄음
출발지 IP는 전 세계에 흩어져 있었지만 실제 스캔 잡음은 단 한 사람에게서 나온 셈임
AWS가 인스턴스 메타데이터 서비스 (IMDS)에 fail2ban을 실행할 이유를 모르겠음. 구현을 믿지 못하는 건지, 대형 고객의 소송을 원하는 건지도 의문임
IP 기반 차단은 주의해야 함. IP 대역은 가끔 재할당되므로 엉뚱한 사람을 막을 수 있으며, 지역이나 데이터센터라는 이유로 차단했던 대역이 주거용 ISP로 넘어간 경우도 여러 번 봤음
HTTP/1.1 차단도 오래된 브라우저를 쓰는 실제 사용자를 막을 위험이 큼. 또한 교차 출처 요청 (Cross-Origin Request)에서 전체 URL을 보내지 않는 브라우저가 있어 Google 검색에서 유입되면 리퍼러 (Referrer)가 Google 루트 페이지만 가리킬 수 있으므로, 이를 봇의 거짓말로 단정해 막으면 Google 검색 유입까지 사라질 수 있음
자신도 모르게 네트워크가 주거용 VPN에 재판매되는 사람도 안타깝게 많음
반면 HTTP/1.1 차단은 합리적이라고 봄. 거의 모든 브라우저가 이를 넘어선 프로토콜을 지원한 지 10년이 넘었고, 그 정도로 오래된 브라우저라면 이미 주류 웹 대부분이 깨지므로 개인 사이트 하나가 더 안 되는 것도 예외가 아니라 일상일 것임
취미와 실험용 사이트에서는 Google의 모든 ASN을 완전히 차단함. 최근에는 유익한 트래픽을 받은 적이 없고 검색 품질도 망가졌다고 봄
오래된 브라우저와 API 도구를 놓치더라도 HTTP/1.1 차단은 유지할 예정임. 낡은 금융 시스템의 독점 코드라면 이해하지만, 공개 인터넷은 스스로를 위해 갱신해야 함
Google을 오래전부터 막았으므로 Google에서 왔다고 주장하는 요청은 모두 거짓임. 블로그를 여러 무작위 도메인으로 순환시켜 연관 관계와 스냅샷을 끊고, 사람들이 내 글을 발견하는 경로를 통제하려 함
몇 년 전 AWS에서 들어오는 트래픽을 차단하고 글을 썼음. 평소 실제 방문자는 주당 수십 명뿐인데 그 글은 약 3개월간 실제 사람 15,000명이 봤고도 빠르게 잊혔음
덕분에 무료 침투 시험 (Penetration Test)도 받았으며, 방어책과 처리 파이프라인이 견고하다는 결론을 얻음. 생존 압력 때문에 봇 트래픽의 90%가 VPN으로 이동해 VPN 종단점이 크리스마스트리처럼 빛나고 있음
일회성 접근 IP 피드를 제공할 수도 있지만, 이용자는 제대로 검증받고 용도도 승인받아야 함. 이 과정 자체가 재미있음
글쓴이는 여러 종류의 실제 사용자를 차단해도 괜찮다고 명시했으므로, 그 조언은 따르지 않겠음
일반적인 iOS Safari 사용자에게는 안타까운 구현임: [IMG:1]
봇도 아닌데 무언가를 읽기 위해 iCloud Private Relay를 끄고 싶지는 않음. 글쓴이의 다른 답변에 따르면 시험 사이트로서는 좋은 구현이지만, 다른 웹 관리자는 가능하면 모든 방식을 그대로 도입하지 않았으면 함
나도 접속하지 못했는데 archive.ph 크롤러는 무사히 통과했다는 점이 재미있음
응답 본문에 410과 Sec-Fetch-Mode: 문자열만 나오는 걸 보면 나를 봇으로 판단한 듯함. 읽을 것도 볼 것도 없어 그냥 떠나게 되며, 현대 웹은 끔찍함
거기까지도 못 가고 TLS 핸드셰이크 (Handshake)조차 통과하지 못했다는 PR_END_OF_FILE_ERROR가 발생했음
웹 트래픽의 99% 이상이 봇이나 에이전트일 것으로 예상되어 방문자 수 표시를 없앨까 고민 중임. 수치가 무의미하고 실제보다 사이트가 훨씬 붐벼 보이지만, 진짜 사람이 글을 읽거나 책을 내려받지 못하게 될까 봐 대응을 망설이고 있음
테크노 스릴러·SF·미스터리 소설이라니 나중에 살펴보고 싶음
차단이 필요하다면 일반적으로 허용 목록 (Allowlist)이 거부 목록 (Denylist)보다 효과적이며, 허용 목록을 적용할 수 없다면 이 방식도 좋은 해법이 아닐 수 있음
Cloudflare와 Anubis 같은 도구는 심각한 접근성 문제를 일으킬 수 있어 요청 빈도 제한 (Rate Limiting)을 선호함. 접근성을 해치지 않으면서도 깔끔하고, 일시적 문제에는 짧은 IP 차단도 잘 작동함
개인적으로 fail2ban으로 HTTP 로그를 분석해 robots.txt에서 금지한 URL이나 wp-login.php 같은 경로를 요청하거나 요청 빈도 제한을 지나치게 자주 넘는 IP를 N시간 차단함. 현재 Git 웹 UI에서는 Anubis를 시험 중임
기업 간 통신에서는 네트워크 간 VPN으로 허용 목록을 구현했음. VPN 밖에서는 서버에 접근할 수 없고 직원은 회사 VPN을 통해 접속할 수 있음
fail2ban만으로도 꽤 잘 막을 수 있지만, 처음 몇 달은 환경에 맞게 세밀하게 조정해야 함
먼저 failregex = ^ - \S+ [] ".*?" 40[034] 필터로 탐지한 뒤 더 구체적인 목록에 추가했으며, 지금은 약 80개의 정규식 (Regex)으로 모든 트래픽을 차단해 일반 40[034] 필터까지 도달하는 요청이 오래도록 없었음
다만 로드 밸런서 (Load Balancer)나 프록시 (Proxy) 뒤에서는 실제 IP를 얻는 방법이 필요해 fail2ban과 원문의 방식 모두 번거로워짐
대부분의 7계층 로드 밸런서는 실제 IP가 담긴 헤더 (Header)를 추가하는 기능을 제공함. 웹 서버가 그 헤더를 기록하도록 설정하면 되며, CDN이 실제 IP를 전달하는 방식과 매우 비슷함
이 댓글들과 내 접속 시도를 보면 봇뿐 아니라 정상 트래픽도 모두 차단하는 듯함
댓글만 보면 오해할 수 있음. 지금까지 약 2,600명과 일부 봇은 글을 볼 수 있었음
일요일에는 사람들이 웹을 탐색할 때 쓰는 특이한 브라우저와 앱을 가장 많이 볼 수 있고, 평일에는 평범한 주류 브라우저가 많아 좋은 시험이 됨
AI 자동 생성 콘텐츠
본 콘텐츠는 GeekNews의 원문을 AI가 자동으로 요약·번역·분석한 것입니다. 원 저작권은 원저작자에게 있으며, 정확한 내용은 반드시 원문을 확인해 주세요.
원문 바로가기