Cloudflare 무료 요금제에서 발생한 스크레이퍼 폭주: 무엇이 이를 막았고, 무엇이 꺼진 채로 남겨졌는가

운영

어느 날 아침, 우리가 운영하던 상품 상세 페이지 사이트가 열리지 않았습니다. Cloudflare는 방문자에게 524 오류를 표시했고, 원본 서버는 페이지당 2~6분이 걸렸으며, 약 10시간 동안 아무런 알림도 없었습니다. 원인은 주거용 프록시를 통해 초당 약 225건의 요청을 보내는 스크레이퍼였습니다.

폭주의 형태

모든 요청마다 모든 페이지가 렌더링되었으므로, 각 워커는 수백 개의 렌더링을 대기열에 넣고 CPU 한도에 도달했습니다.

주소별 제한이 도움이 되지 않은 이유

속도 제한은 주소별 요청 수를 계산합니다. 수천 개의 주소에서 각각 1~3건의 요청이 들어오면, 어떤 단일 주소도 제한에 근접하지 않습니다. 국가를 차단하면 우리 방문자까지 차단되었을 것입니다. 스크레이퍼가 저렴하게 흉내 낼 수 없었던 것은 이전에 사이트에 방문한 적이 있는 브라우저처럼 행동하는 것이었습니다.

Cloudflare 엣지에서: 무료 규칙 세 가지

무료 요금제는 존(zone)당 WAF 사용자 지정 규칙을 5개까지 허용합니다. 우리는 실수로 걸린 사람이 클릭하여 통과할 수 있도록 차단이 아닌 관리형 챌린지(managed challenge)를 사용하는 규칙 세 가지를 사용했습니다:

세 가지 모두 Cloudflare의 검증된 봇, 스스로를 봇으로 밝히는 사용자 에이전트, 자체 주소, API 및 웹훅 경로, 그리고 페이지가 아닌 파일을 허용합니다. 이틀 후에도 트래픽 폭주는 계속되었습니다. 1시간 동안 가짜 브라우저 규칙이 10,000건 이상의 요청을 챌린지했습니다. 쿼리당 Cloudflare가 반환하는 10,000개 이벤트는 9,627개 주소에서 발생했으며, 단일 주소당 최대 4건을 넘지 않았습니다.

오리진에서: 앱 내의 게이트

헤드리스 반쪽은 완전한 브라우저 헤더를 갖추고 있어 비상 규칙이 꺼져 있을 때 엣지 규칙만으로는 이를 잡아내지 못합니다. 앱 자체에서는 페이지 렌더러 앞에 작은 미들웨어를 배치했습니다:

게이트가 작동한 첫 1분 동안 약 6,700개의 가짜 브라우저를 거부하고 약 6,700명의 낯선 방문자를 돌려보냈으며, 낯선 방문자에게 초당 약 9페이지를 서비스했습니다. 느린 요청은 0으로 떨어졌고, 워커의 CPU는 상한선에서 12~15%로, 메모리는 각 4~5GB에서 0.65GB로 감소했습니다.

꺼둔 것들

핵심 요약

주거용 프록시를 통한 트래픽 폭주는 부재한 요소로 쉽게 식별할 수 있습니다: 브라우저 fetch 헤더, 쿠키 및 Referer. 엣지에서 이를 챌린지하고, 낯선 방문자를 워커가 렌더링할 수 있는 범위로 제한하며, 서버 외부에서 페이지가 열리지 않을 때 감지할 수 있는 수단을 확보하십시오. Night Watch는 세 가지를 모두 패키징합니다: 워치, 비상 규칙용 자동 스위치가 포함된 규칙, 그리고 Python 웹 앱을 위한 게이트.

업데이트됨: