使用 Service Worker 緩解網站 DDOS 攻擊
前言
傳統的 DDOS 防禦開銷很大,而且有時效果並不好。
例如使用 DNS 切換故障 IP 的方案,由於域名會受到快取等因素的影響通常有分鐘級延時,前端難以快速生效。例如使用 CDN 服務,雖可抵擋大多網路層攻擊,但對應用層攻擊卻常有疏漏,攻擊者可通過惡意請求消耗流量、日誌存儲等費用,導致欠費停止服務。例如購買流量清洗等服務,雖然效果不錯但費用十分昂貴。
今天分享一種超低成本的網站 DDOS 防禦方案 —— 不使用任何後端防禦服務,純前端實現!當然效果也非常極端:如果用戶之前未訪問過該網站,這種防禦不會生效,網站被打垮仍無法訪問;但如果用戶之前訪問過該網站,之後即可無視攻擊,甚至伺服器關機網站也能訪問,並且還能保持更新!
前端代理
說到低成本、防攻擊、離線訪問等特性,大家可能會想到 Cloudflare 服務。不過前面提到,我們不使用後端防禦,而是純前端實現。
事實上,我們可以把 Cloudflare 搬到瀏覽器前端!這裡不得不提 HTML5 中的一個 API —— Service Worker
,它能攔截當前站點產生的所有請求,並能控制返回結果,相當於一個反向代理服務。有了這個黑科技,即可在前端實現 CDN 功能。
我們為靜態資源準備多個站點做冗餘備份,當 Service Worker 載入資源出錯時,可不返回錯誤給上層頁面,而是繼續從備用站點載入,直到獲得正確結果才返回。這樣,只要有一個備用站點可用,資源就不會載入失敗。
相比傳統使用 DNS 切換故障 IP 的方案通常有分鐘級的延遲,這種 JS 控制的方案可精確到毫秒級,並且還能有多次試錯的機會,從而大幅增加穩定性。
離線訪問
Service Worker 的設計初衷就是為了增強網頁的離線化體驗,因此一旦安裝即可在後台長期運行,即使伺服器關機、瀏覽器重啟,它也不會失效。
事實上,除了網頁中的資源可被 Service Worker 攔截,網頁本身也可以。Service Worker 安裝後,用戶在地址欄輸入網址發起的那個請求其實也會被攔截,從而可從備用站點載入網頁文件。
注意,這不是重定向,地址欄不會有變化。
因此即使網站被打垮,之前訪問過的用戶仍可通過 Service Worker 從備用站點載入頁面,從而正常訪問。
免費節點
使用冗餘站點雖能提升穩定性,但攻擊者仍可對備用站點發起攻擊,尤其是惡意消耗流量費用的攻擊,導致成本大幅上升。
為此,我們還可使用一種更極端的方案 —— 使用免費 CDN 作為備用站點,例如 jsdelivr.net、unpkg.com、IPFS Gateway 等等,圖片則可上傳到各大網站的相冊。
對於非圖片類型的文件,甚至還可以封裝成圖片上傳,使用時再從中提取!例如 此文件 正是從 該圖片 中提取。
雖然單個免費 CDN 的穩定性可能不高,但多準備幾個,穩定性就呈指數級上升了。
至於惡意攻擊,幾乎不可能打垮。DDOS(Distributed DOS)的精髓在於分散式,將分布在各地的流量匯聚到一起,從而增加傷害;而我們正好相反,將集中的流量分攤到各地,變成一個去中心化的分散式站點,從而化解攻擊。
演示
這個方案原理雖不複雜,但實現起來還是有很多細節。為方便開發者使用,這裡提供一個工具 //github.com/EtherDream/freecdn,可實現上述提到的所有功能。
演示案例://freecdn.etherdream.com/time.html
該頁面通過 HTML 靜態輸出當前時間,刷新可變化。
關閉頁面,退出瀏覽器。現在模擬該網站被打垮,例如通過 hosts 屏蔽站點域名:
0.0.0.0 freecdn.etherdream.com
清理系統 DNS 快取(當然 Chrome 等瀏覽器自己維護 DNS 快取,退出瀏覽器即可清理)。
打開瀏覽器,再次訪問該頁面。頁面不僅能正常訪問,甚至還能更新!
通過控制台可見,雖然當前站點已無法連接,但後台 Service Worker 將頁面代理到 //freecdn1.etherdream.com:30000/time.html 這個備用地址,因此頁面仍能顯示,並且地址欄毫無變化 —— 儘管該頁面的內容來自第三方站點。
介面防禦
對於純靜態資源的站點,我們可將所有資源甚至包含 HTML 文件都通過免費 CDN 加速,從而大幅降低成本、增加穩定性。
但對於動態介面,又該如何實現防禦?事實上,介面數據也可以分發到多個備用節點上,細節可參考 POST 請求代理 的案例。
當然,動態介面不同於靜態資源那樣可使用大量免費 CDN 分攤攻擊流量,因此即使有背後多個備用節點,攻擊者仍可找出來然後進行攻擊。對此,我們需要更多的巧妙的防禦思路,例如通過雲防火牆和 Service Worker 使用約定的演算法生成埠號,從而可不斷更換埠,識別出固定不變的攻擊流量;例如通過最便宜的搶佔式主機(幾分錢一小時)購買大量公網 IP 作為轉發節點。。。細節下回講解。
當然即使不考慮動態介面,網站被打垮後仍能訪問靜態內容,相比完全打不開要好得多。