Cloudflare Freeプランでスクレイパーの殺到:何が止まり、何をオフのままにしたか
オペレーション
ある朝、運営中の商品ページサイトの1つが開かなくなった。Cloudflareは訪問者に524を表示し、オリジンは1ページあたり2〜6分を要し、約10時間誰も気づかなかった。原因は、住宅用プロキシ経由で毎秒約225リクエストを投げるスクレイパーだった。
殺到の形状
- 数千のアドレス、それぞれ1〜3リクエスト。米国、スペイン、フランス、ブラジル、英国などの一般家庭向けブロードバンド接続。住宅用プロキシネットワークが貸し出すようなトラフィックだ。
- Mac上のChromeユーザーエージェント、バージョン番号は103から151。
- CookieやRefererはほぼなし。サーバーでサンプリングした2,697リクエストのうち、Cookie付きは4件、Referer付きは4件だった。
- 2種類のクライアント。約半数は
Sec-Fetch-*ヘッダーもクライアントヒントも送らない:ユーザーエージェント文字列をコピーしたスクリプト。残りの半数は完全なブラウザヘッダーを送る:ヘッドレスブラウザ。
すべてのリクエストでページがレンダリングされるため、各ワーカーは数百件のレンダリングをキューに積み、CPU上限に達した。
アドレス単位制限が助けにならなかった理由
レート制限はアドレスごとのリクエスト数を数える。数千のアドレスからそれぞれ1〜3リクエストでは、どの単一アドレスも制限に近づかない。国をブロックすれば訪問者までブロックしていた。スクレイパーが安価に偽装できなかったのは、以前そのサイトを訪れたことのあるブラウザのように振る舞うことだった。
Cloudflareのエッジで:無料ルール3つ
FreeプランではゾーンごとにWAFカスタムルールを5つまで使える。3つを使い、ブロックではなくマネージドチャレンジを設定した。誤って引っかかった人はクリックで通過できる:
- 偽ブラウザ:ユーザーエージェントに
Chrome/を含み、Sec-Fetch-ModeヘッダーがないGETリクエスト。2019年以降のChromeはすべてこれを送信する。 - スクレイパー用クラウド:Alibaba、Tencent、Huawei Cloudのネットワークからのページリクエスト。チャレンジの多くはここから来ていた。
- 緊急用、デフォルトでオフ:Cookieが一切なく、RefererもないGETリクエスト。サイトを訪れたことのある人、またはリンク経由で到着した人はそのまま通過する。Cookieを保持しないスクレイパーはすべてのリクエストでチャレンジを受ける。殺到時のみオンにする。なぜなら、新規ブラウザでアドレスを入力した人もチャレンジされるからだ。
3つとも、Cloudflareが検証済みのボット、自らをロボットと名乗るユーザーエージェント、当社の独自アドレス、APIおよびWebhookのパス、そしてページではないファイルは通過させます。2日後も洪水は続いていました。1時間で、偽ブラウザルールは10,000件以上のリクエストにチャレンジを課しました。クエリごとにCloudflareが返す10,000件のイベントは、9,627個のアドレスからのもので、いずれも4件を超えていませんでした。
オリジン側:アプリ内のゲート
ヘッドレス側は完全なブラウザヘッダーを持つため、緊急ルールが無効な間はエッジルールだけでは捕捉できません。アプリ自体では、ページレンダラーの前に小さなミドルウェアを配置しました:
Sec-Fetch-ModeもクライアントヒントもないChromeユーザーエージェントは、処理を行う前に403を返されます;- 当社のクッキーもRefererもない見知らぬ訪問者は、ワーカーに余力がある場合のみ、毎秒数ページまで応答します。それを超えると、400バイトの503ページがクッキーを設定し、2秒後にリロードします。人間は2回目の試行でページを取得できますが、クッキーを保持しないスクレイパーは決して取得できません。
開始後1分間で、ゲートは約6,700件の偽ブラウザを拒否し、約6,700件の見知らぬ訪問者を排除しました。一方、見知らぬ訪問者には毎秒約9ページを提供しました。遅いリクエストはゼロになり、ワーカーのCPU使用率は上限から12〜15パーセントに、メモリはそれぞれ4〜5GBから0.65GBに低下しました。
オフのままにしたもの
- Bot Fight Mode。自動化されたトラフィックにチャレンジを課し、Freeプランではカスタムルールでスキップできません。当社の決済プロバイダーのWebhookを捕捉してしまいました。
- ゾーン全体のUnder Attackモード。すべての訪問者、APIクライアント、Webhookをインタースティシャルに通します。緊急ルールは、見知らぬ訪問者のページリクエストに対して同じ役割を果たします。
- Freeプランのレート制限ルール。アドレス単位でカウントしますが、今回の洪水ではトリガーされません。
- AIクローラーのブロック。AI検索アシスタントに見つけてもらいたいので、これらのクローラーは問題ではありませんでした。
まとめ
住宅用プロキシ経由の洪水は、欠けているもの(ブラウザのfetchヘッダー、クッキー、Referer)で容易に見分けられます。エッジでチャレンジを課し、見知らぬ訪問者をワーカーがレンダリングできる範囲に抑え、ページが開かなくなったときにサーバー外から何かを検知できるようにしてください。Night Watchはこれら3つをパッケージ化しています:ウォッチ、緊急ルール用の自動スイッチ付きルール、そしてPython Webアプリ用のゲート。