DDoS
利用 JS Challenge 緩解 DDoS 攻擊
之前的文章提到,我接手管理了一個內容網站:Clojurians Log。當時,僅透過 Nginx 的 rate limit 功能,就讓網站成功恢復正常。然而,這幾天遭遇到一波更強烈的 DDoS ,單靠簡單的 Nginx 設定已無法有效防禦。
這時,該是拿出十多年前的經驗來應用的好時機了。十多年前,我曾經經營 web hosting 生意,也曾面對過大規模的 HTTP GET flood。當時,我的解法是透過 Nginx 搭配一款名為 Roboo 的套件來進行防禦。
Roboo 與 JS Challenge
初次接觸 Roboo 時,雖然安裝過程非常繁瑣,但在其他手段皆失敗的情況下,只能硬著頭皮完成部署。成功啟用後,DDoS 攻擊隨即被有效攔截。
後續,我逐步理解 Roboo 的防禦原理:它利用了「JS Challenge」。
當瀏覽器存取網站時,Nginx 會主動回傳一小段以 JavaScript 撰寫的程式碼,要求瀏覽器執行。若瀏覽器能正確執行並回傳結果,即認定為人類操作的合法流量;反之,若無法執行,則可能是如 CURL 之類的簡易瀏覽器或爬蟲程式。這種以 JavaScript 驗證的方式,便稱為 JS Challenge。
此防禦策略背後的核心是「不對稱防禦」原理:只要防禦方能設計出使攻擊方成本大幅提升的機制,通常便能有效遏止攻擊。
儘管 JS Challenge 的原理並不複雜,但 Roboo 的安裝仍頗具挑戰性,主要原因在於其對 Perl 的依賴。具體來說,安裝 Roboo 需要滿足兩個條件:
Perl 函式庫安裝
Roboo 以 Perl 撰寫,因此必須安裝其所依賴的各種 Perl 函式庫。雖然我平時不撰寫 Perl 程式,但這部分與安裝 Node.js 或 Python 函式庫的流程類似,尚屬簡單。
啟用 Nginx 的 Perl 模組
更大的挑戰在於 Nginx 必須啟用 ngx_http_perl_module 模組,才能支援內嵌 Perl 程式碼。然而,大部分透過 apt-get 或 yum 安裝的 Nginx 套件,預設並未啟用此模組。
換言之,若要使用 Roboo,必須自行下載 Nginx 原始碼,並在編譯時啟用 Perl 支援,隨後將其安裝至正確的目錄。這牽涉到大量的編譯、設定與指令操作。
回顧十年前,正是按部就班地完成了這一連串繁瑣流程,才成功部署了防禦機制。
利用 Cloudflare 的 WAF 實作 JS Challenge
這次面對新一波攻擊,一開始我也打算重走舊路。然而,當意識到必須重新編譯 Nginx 後,我重新評估了整體成本,並嘗試尋找更現代、簡便的方案。
蒐集資料後,我發現可以直接利用 Cloudflare 的 WAF(Web Application Firewall)來設定 JS Challenge,省去了繁瑣的伺服器端作業。
具體操作步驟如下:
登入 Cloudflare,選擇對應的網域名稱。
在側欄選擇「Security」>「WAF」。
點選「Create firewall rule(建立防火牆規則)」。
在規則條件中設定比對條件,並在 then 動作選擇「JS Challenge」。
參考:圖形化教學連結
透過這種方式,不需動到 Nginx ,僅透過 Cloudflare 介面設定,即可快速部署防禦機制。
總結
這次面對更強力的 DDoS ,我原本想採用十年前熟悉的解法(Nginx + Roboo),但在評估重新編譯 Nginx 的設置成本後,最終選擇了更簡便有效的 Cloudflare WAF JS Challenge 功能,迅速完成了防禦部署。
這段經驗再次提醒我:
隨著技術演進,過去奏效的方法未必是今日最佳選擇。
熟悉工具運作原理,能在選擇新解法時提供寶貴的判斷依據。


