AWS 봇이 한 달에 20억 건의 요청을 보내는 것을 어떻게 멈출 수 있을까?
(news.ycombinator.com)- AWS 인프라에서 예상치 못한 대량 웹 요청 문제 발생
- 한 달에 2억 건에서 20억 건까지 급격하게 증가한 트래픽 현상 보고
- 로그 분석 결과 특정 User-Agent에서 반복적인 요청 확인
- AWS 지원팀에 문의했지만 명확한 해결책을 받지 못한 상황
- 방화벽 규칙 설정, User-Agent 차단 등 다양한 차단 방법 검토 필요성 대두
문제 소개
- 한 AWS 사용자가 웹 서버에서 2B(20억) 건의 요청이 한 달 동안 발생한 현상에 대해 질문 제기함
- 이 요청들은 특정 User-Agent를 사용하는 봇에서 발생했으며, 정상 사용 패턴과 일치하지 않는 비정상 트래픽임
- 갑작스런 트래픽 증가는 비용 상승 및 시스템 부하 문제로 이어질 위험성이 존재함
원인 분석
- 방대한 요청 중 대부분이 의심스러운 AWS IP 대역에서 유입됨
- 접근 기록을 통해 특정 봇 또는 스크립트가 원인임을 파악함
- User-Agent에 공통된 패턴이 존재하여 필터링이 가능함
기존 대응 및 한계
- AWS 지원팀에 문의했지만 결정적인 방안 제공 받지 못함
- 이와 같은 대량의 요청은 서비스 장애 유발 및 비용 부담 증가 가능성이 높음
해결 방향 및 고려사항
- 방화벽 규칙 추가 및 User-Agent 기반 트래픽 차단, IP 블랙리스트 적용 등 다양한 차단 정책 필요성 검토함
- 장기적으로는 트래픽 모니터링 시스템 강화와 비정상 접근 감지 및 자동 차단 체계 구상 필요성 대두
Hacker News 의견
- 30x 리다이렉트를 시도해 본 경험이 있음, 예를 들어 301 응답을 통해 내가 싫어하는 회사들이 호스팅하는 아주 큰 파일들로 유도하는 방식임, 만약 그 회사 AWS 인스턴스가 7만 개의 윈도우 ISO를 동시에 다운로드하게 만들면 분명 눈치챌 것임, 또한 클라우드플레어로는 쉽지 않지만, 일명 ‘타르 핏’ 전략도 사용 가능함, 요청을 받은 후 응답을 한 글자씩, 각 문자마다 30초씩 지연시켜 전송하는 방식임, 각 요청당 10KB 헤더/응답으로 초당 700개의 요청이 발생한다면 서버가 엄청 느린 것처럼 보일 것임
- 301 리다이렉트 대상으로 특정 회사가 마음에 들지 않으면 Amazon 같은 곳을 지정하는 방법 추천임
- 요청을 받고 한 글자씩 천천히 보내는 전략은 Slow Loris DDoS 공격과 정반대의 방식이라는 생각임, Slow Loris 공격에 대한 설명은 Cloudflare 에서 참고 가능임, 즉 공격을 느린 연결로 하는 것이 아니라, 방어 측에서 느린 연결로 맞대응하는 셈임
- 대안으로 .sg 공식 정부 사이트로 301 리다이렉트해서 현지 법 집행기관이 처리하게 만드는 방법도 생각해볼 수 있음
- AWS의 인바운드 트래픽은 무료이기 때문에, 인스턴스 소유자가 엄청난 양의 데이터를 받더라도 AWS에서는 요금이 추가로 발생하지 않는다는 점을 지적함
- 명백히 악의적인 봇을 운영비 측면에서 부담스럽게 만드는 것도 한 방법임, 특히 gzip bomb 같은 방식을 쓰면 봇이 취약할 때 효과가 있지만, 단순히 응답 전 10초 정도만 대기시켜도 서버에서 약 7,000개의 포트를 소비하게 할 수 있음, 대부분의 리눅스 프로세스가 이를 감당 못해서 죽게 됨, nginx + mod-http-echo로 구현이 쉬움
- 실제로 이런 전략을 이미 구현한 사람들이 있음, 오픈소스 코드의 user agent 리스트를 보면 알 수 있고, 구현 자체도 매우 간단함, 관련 소스는 여기에서 확인 가능함
- AWS 고객은 아웃바운드 트래픽에 비용을 내야 하지만, 반대로 대용량 트래픽을 AWS 또는 Cloudflare 쪽에서 우리에게 보낼 수 있는 방법도 궁금함
- 비슷한 상황을 겪었음, 우리 사이트 가격정보를 긁으려고 악성 스크래핑이 반복됐고, 카탈로그 상품이 수백만 개나 되어 동적으로 가격을 계산하는 데 엄청난 리소스가 소모됐음, 갑작스런 요청 폭탄에 인프라가 감당하지 못해 서비스가 마비될 뻔하기도 했음, 방어 전략으로는 스팸 트래픽을 태그로 구분해 실제 고객에게 영향이 없게 캐싱하는 방법을 시도했고, 추가로 가격에 무작위 오류 값을 넣어 데이터 자체를 무의미하게 만드는 방식도 논의했었음, 결국 Cloudflare와 협업해 악성 요청을 신속히 차단하는 쪽으로 정착했지만 시간·비용 부담이 컸음, 공격자가 경쟁사의 외주 서비스로 추정됐는데 정식 API 제공이 가능한 상황이었음에도 불구하고 직접 문의하지 않는 점이 아쉬웠음, 예전에는 이런 문제에 대해 "트래픽을 견디지 못하면 사이트 잘못"이라 보는 분위기였으나 요즘은 인식이 많이 달라진 느낌임
- 그 방식대로 하면 내 서버에서도 7,000개의 포트가 소모되는 건 아닌지 궁금함
- 해당 기법을 쓰면 내 서버에도 연결이 동일하게 많이 생기는 것 아닌지 질문함
- Anubis의 메인 작성자임, Cloudflare에서 HTTP 200 응답을 반환하도록 설정하면, 봇이 200을 받을 때까지 때리는 걸 멈춘다는 점을 경험했음
- 참고로 지금 메인 사이트에 이슈가 있는 것 같음
- 애플리케이션 레이어에서 탐지되면 아예 연결을 강제로 끊어버리는 방식도 써봤는데, Cloudflare 쪽 설정이 힘들 때 원시적인 봇에는 통하는 것 같음
- 예전에 내 개인 블로그에서 비슷한 상황을 겪음, 7~8년 전엔가 갑자기 트래픽이 치솟아 바이럴된 줄 알았으나 너무 기계적이라 이상하게 여김, 원인을 찾아보니 누군가의 봇/크롤러가 테스트 삼아 내 사이트를 긁는 것이었음, 몇 달 동안 정중하게 여러 번 요청해도 소용이 없어서 결국 리다이렉트로 해당 봇을 무작위 포르노 사이트로 보내버렸더니 크롤링이 멈췄음
- 이 방식이 실질적으로 최고임, 크롤러 로그에 남기 싫은 곳으로 리다이렉트시키거나, 자기 자신이나 서비스 제공자, 원하지 않는 컨텐츠로 돌려보내봄
- 200 응답에 EICAR 테스트 스트링을 바디에 포함시켜서 데이터 오염을 유도하는 것도 꽤 속 시원한 복수용 방법임, EICAR 테스트 파일 설명 참고
- SSRF 공격의 반대 개념으로, 봇을 클라우드 메타데이터 API로 리다이렉트해 <shutdown> 같은 엔드포인트 호출을 유도해도 재미있겠다는 생각임, 리다이렉트 응답에 EICAR 테스트 스트링까지 넣어서 자동 보안 탐지 시스템도 작동하게 할 수 있을 것임
- AWS Singapore로부터 정상 트래픽을 아예 받을 일이 없다면, 해당 대역 전체를 블랙홀 처리하는 방법도 대안임
- WAF를 이용해 해당 패킷을 아예 드롭시키는 방법이 있음, Cloudflare WAF의 "block" 기능이 이런 용도임
- 나도 예전에 이렇게 한 적 있는데, Byte Dance에서 운영하는 Byte Spider 봇이 수백만 건 이미지를 긁어갔고, 결국 Cloudinary 측에서 사용자 에이전트 차단 요청도 하고 처음에는 Singapore 전체 차단도 했었음, AI 스크래핑 회사들이 정말 악의적으로 봇을 운영하는 것에 화가 났음, Cloudinary 같은 좋은 서비스를 써서 그나마 비용을 아꼈고, 요새는 Cloudflare로 AI 봇 전체를 차단하는 방식으로 끝냄
- 참고로 AWS의 각 리전별 IP 대역은 여기에서 확인 가능함
- 2018년에 비슷한 일을 훨씬 작은 규모로 겪은 적 있음, AWS 공식 IP 대역 json 리스트를 읽어와 Windows Firewall에서 해당 대역을 차단하는 툴을 직접 제작했었음, 관련 블로그 글은 여기에서 참고 가능하고, 툴의 readme는 이곳에서 볼 수 있음, 수년간 서버에서 예약 작업으로 잘 돌아갔으나 지금도 동작하는지는 확신이 없음, 혹시 관심 있다면 코드를 공개하거나, 다른 분한테 넘기는 것도 생각해 볼 수 있음, 직접 구현해도 그리 어렵지 않을 것임, 행운을 빔
- 싱가포르의 통신 규제기관은 포르노 자체 소지도 금지함, 그래서 악성 봇에 소프트코어를 대응으로 전송하고 동시에 기관과 AWS에 이메일 신고하는 전략 제안임
- 누군가가 인터넷상에서 반복적으로 피해를 주면 그 나라 법을 활용해 대응하는 게 가장 효과적임, 다른 기관에서는 대부분 아무런 조치도 기대하기 어려움
- Cloudflare에 해당 트래픽이 악의적임을 알리면, 계정 외부에서 차단해주기 때문에 내 쪽 트래픽 집계에 부담이 없게 처리 가능함
- 비슷한 경험이 있음, 80MB짜리 소프트웨어 인스톨러를 엄청난 양으로 요청하는 경우였는데, offending 요청을 "please-stop.txt"라는 파일로 리다이렉트하고, 파일 안에 문제 상황을 설명하며 멈춰달라는 요청을 남겼더니 실제로 멈췄음