Cloudflare 免費方案上的抓取器洪水:什麼擋住了它,以及我們關掉了什麼

維運

某天早上,我們的一個商品頁網站打不開了。Cloudflare 向訪客顯示 524 錯誤,來源伺服器每頁需要兩到六分鐘,而大約十小時內沒有任何通知告訴我們。原因是抓取器透過住宅代理以每秒約 225 個請求的速度進行抓取。

洪水的樣貌

每個請求都渲染每個頁面,因此每個工作程序排隊數百次渲染並達到其 CPU 上限。

為什麼每個位址的限制幫不上忙

速率限制計算每個位址的請求數。當數千個位址每個只發送一到三個請求時,沒有任何單一地址接近限制。封鎖國家會封鎖我們的訪客。抓取器無法低成本偽裝的是:像一個以前來過該網站的瀏覽器那樣行為。

在 Cloudflare 邊緣:三個免費規則

免費方案允許每個區域有五個 WAF 自訂規則。我們使用了三個,全部使用受管挑戰而不是封鎖,因此被誤判的人可以點擊通過:

這三種機制都會放行 Cloudflare 驗證過的機器人、自報家門的機器人 User Agent、我們自己的位址、API 與 webhook 路徑,以及非網頁的檔案。兩天後流量洪峰仍在持續:僅一小時內,假瀏覽器規則就對超過 10,000 個請求發起挑戰。Cloudflare 每次查詢回傳的 10,000 個事件來自 9,627 個位址,沒有任何一個位址超過 4 次。

在源站:應用層的一道閘門

無頭瀏覽器端具備完整的瀏覽器標頭,因此在緊急規則關閉時,僅靠邊緣規則無法攔截它。我們直接在應用層中,於頁面渲染器前方加入一個小型中介軟體:

在啟動後的第一分鐘,閘門拒絕了約 6,700 個假瀏覽器,並擋下約 6,700 個陌生訪客,同時以每秒約 9 頁的速率服務陌生訪客。慢速請求降至零,工作者的 CPU 從滿載降至 12 到 15%,記憶體則從每個 4 到 5 GB 降至 0.65 GB。

我們保持關閉的項目

重點整理

透過住宅代理的流量洪峰很容易辨識,因為它缺少:瀏覽器 fetch 標頭、Cookie 與 Referer。在邊緣端對其發起挑戰,將陌生訪客的流量控制在工作者可渲染的範圍內,並確保伺服器外部有機制能在頁面無法開啟時察覺。Night Watch 將這三者打包在一起:守護程序、帶有緊急規則自動切換功能的規則集,以及專為 Python Web 應用設計的閘門。

已更新: