在這個爬蟲橫行的時代,越來越多開發者深受其害:有人怒斥 OpenAI 的爬蟲瘋狂“偷”數據,;也有人被爬蟲逼到極限,最后只好。但本文作者卻走了一條完全不同的路——他靠一己之力,用一臺每月僅需 6 美元的小破服務器,成功扛下了 Hacker News 熱榜帶來的流量海嘯,還順手反制了那些惡意爬蟲,用“zip 炸彈”讓它們原地爆炸。而他是怎么做到的,我們不妨來看看。
原文:https://idiallo.com/blog/surviving-the-hug-of-death
https://idiallo.com/blog/zipbomb-protection
作者 |Ibrahim Diallo 編譯| 蘇宓
出品 | CSDN(ID:CSDNnews)
背景
我是 Ibrahim Diallo,一名住在加州的軟件開發者。從 1992 年起,我就開始“折騰電腦”:破解系統、寫代碼,一轉眼搞了幾十年,到現在也還沒停下。
平時我會寫點博客,分享技術觀察和一些個人思考。誰知多年前剛開始寫沒多久,就因為一篇意外“火出圈”的文章,遭遇了前所未有的流量暴擊——直接沖上了 Hacker News 和 Reddit 熱榜。
文章登上 HN 首頁的那一刻,我那臺小服務器瞬間崩潰了。請求像潮水一樣涌來,Apache 服務器吃力地運轉,我坐在電腦前一次次重啟它,就像拿個噴水槍去滅森林大火——完全招架不住。這種“被熱度壓垮”的場面,在互聯網圈子里還有個形象的說法:“死亡之擁”(Hug of Death)。
到底訪問量有多猛、服務器壓力有多大?說實話,還真挺難用語言形容。
直到今年二月,我又寫了一篇文章,它沒多久后又登上了 Hacker News 第一名。不過這次我有備而來:提前保存了服務器的日志,還專門做了一段可視化動畫,展示那臺每月只花 6 美元的小服務器,是怎么扛住這波流量洪水的。
上面這個動畫里,每一個網頁請求都用一個小圓點表示,朝服務器移動。右下角還有圖例說明:
機器人 vs 真實用戶:通過 user-agent 判斷。帶有 “bot” 的一般是正規機器人,其他的就靠一些啟發式規則來判斷。
響應類型:
- 200 OK(是一種HTTP 狀態碼,表示網頁請求成功了,服務器已經正常返回了你要的內容):請求成功
- 重定向:用晃動的小圓點表示
- 404 Not Found:紅點會掉出屏幕
- zip Bombs:這個后面再解釋
服務器配置
隨著文章爆火,盡管現場一度混亂,我那臺每月只花 6 美元的小服務器卻始終堅挺。它的配置非常簡陋:只有 1GB 內存,跑著 Apache 2 和一個簡單的 MySQL 數據庫。沒有云服務、沒有自動擴容、也沒有負載均衡器,全靠輕量化配置和合理的緩存策略“硬扛”流量洪峰。
服務器配置如下:
主機服務商:DigitalOcean(1GB 內存)
Web 服務器:Apache 2
系統環境:Ubuntu + PHP
數據庫:MySQL
月費用:$6
我的博客是基于一個自建框架,大部分頁面內容都提前緩存到了 memcached 中。數據庫只在每小時查詢一次頁面,大大減輕了負擔。這套方案在過去幾次流量高峰時也都撐住了。
來看一下這次文章爆火的時間線:
下午 4:43(PST)— 文章提交到 Hacker News
下午 4:53(PST)— 登上首頁,機器人蜂擁而至
下午 5:17(PST)— 成為 Hacker News 第一,洪水般的訪問量涌入
晚上 8:00(PST)— 管理員改了標題(原因不明),流量斷崖式下跌
凌晨 3:56(PST)— 一只機器人掃描了 300 個 URL,試圖找漏洞
上午 9:00(PST)— 來自 Mastodon 網絡的新一波流量暴增
上午 9:32(PST)— 遭遇大規模垃圾攻擊:一分鐘內接收約 4000 個請求,幾乎全是廣告
下午 4:00(PST)— 24 小時內,服務器共處理 46,000 個請求
不過你在動畫中可能注意到一個奇怪現象:明明是 1GB 內存的小服務器,怎么內存始終被占了一半左右?原因其實很簡單——是MySQL在“背鍋”。
當年博客剛上線時,我曾雄心勃勃地記錄下每一條請求,把它們寫入數據庫日志表,用來追蹤哪些文章最受歡迎。這招在當時確實挺實用,但 12 年過去,數據越堆越多,想從中查點東西反而變成了高成本操作。
這次流量沖擊之后,我備份了日志表,然后徹底刪掉它。也是時候跟那段歷史告個別了。
對了,你可能在可視化動畫里看到一些“小爆炸”效果,現在就來解釋下那是怎么回事…
有一天,我偶然發現有個網站在實時偷我博客的內容:每次有人訪問他們的頁面,他們就立刻爬取我最新的文章,刪掉我的名字和品牌標識,然后假裝是他們自己寫的。
一開始,我試著“手動反擊”——故意喂他們一些假數據,讓他們搬錯內容。但沒過多久,我就覺得這種方式太麻煩,干脆拿出了我的秘密武器:“zip 炸彈”。
這個“炸彈”的工作原理是這樣的:當他們的爬蟲訪問我的網站時,我就返回一個看起來沒什么問題的小壓縮文件。他們的服務器會乖乖下載并嘗試解壓。結果呢?幾 GB 的“垃圾”文件瞬間釋放,系統直接崩了。
就這樣,游戲結束。
什么是“zip 炸彈”?為什么能“反殺”爬蟲?
這些年,“zip 炸彈”成了我對付各種惡意爬蟲(比如偷內容、探測漏洞、發垃圾信息的自動程序)最有效的工具。
要知道,互聯網上的流量,其實大部分都來自這些機器人。有的是“友好”的,比如搜索引擎、RSS 訂閱器,或者現在很流行的大模型訓練用爬蟲。但也有很多是惡意的:像發送廣告、偷文章,甚至入侵網站的腳本。我曾經在工作中就遇到過:有個爬蟲發現我們 WordPress 的漏洞,在服務器里偷偷植入惡意代碼,讓網站變成黑客控制的攻擊工具;還有一次,我的網站被爬蟲刷滿垃圾內容,結果直接被 Google 搜索下架。
從那以后我就意識到,必須對這些爬蟲進行“反擊”,zip 炸彈就是我找到的最佳方案之一。
簡單說,zip 炸彈是一種超小的壓縮文件,解壓之后卻會變成一個巨大的文件,能讓處理它的系統崩潰。
在互聯網早期,gzip 壓縮是很早就被引入的一個功能。由于當時網速慢、信息密度高,人們希望盡可能壓縮數據再傳輸。比如一個 50KB 的 HTML 文件,經過 gzip 壓縮后可能只剩 10KB,能節省 40KB 的傳輸量。在撥號上網時代,這意味著頁面加載時間從 12 秒減少到 3 秒。
這種壓縮技術同樣可以用于傳輸 CSS、JavaScript 甚至圖像文件。Gzip 的優勢在于它快速、簡單,而且能顯著提升瀏覽體驗。當瀏覽器發出請求時,會在請求頭中表明自己支持壓縮。如果服務器也支持,就會返回經過壓縮的數據版本。
Accept-Encoding: gzip, deflate
而爬蟲程序也會這么做,它們一樣想節省資源。我正是利用這一點“反制”它們。
反擊過程:用壓縮包“讓你解壓到崩潰”
在我的博客上,經常會遇到一些機器人在掃描安全漏洞,通常我不會理會。但當我發現它們試圖注入惡意攻擊,或是在試探服務器響應時,我就會返回一個看起來正常的響應(比如 200 OK),并提供一個經過 gzip 壓縮的文件。
我會提供一個從 1MB 到 10MB 不等的文件,它們也會欣然接受。通常一旦它們接收了這個文件,我就再也沒見過它們出現。為什么?因為它們在解壓文件后直接崩潰了。
Content-Encoding: deflate, gzip
具體發生的事情是這樣的:機器人收到文件后,會讀取文件頭,發現這是一份壓縮文件。于是它們嘗試解壓這個 1MB 的文件,以查找其中的內容。但文件開始不斷擴展、擴展、再擴展,直到內存耗盡、服務器崩潰為止。這個 1MB 的壓縮文件實際上會被解壓為 1GB,大多數機器人在這一過程中就會崩潰。如果遇到那些死纏爛打的腳本,我就給它們發送 10MB 的版本,它會解壓成 10GB,直接“秒殺”。
在告訴你如何制作 zip Bomb 之前,我得提醒一句:這確實可能會導致你自己的設備崩潰甚至損毀,繼續操作需自擔風險。
下面是創建 zip Bomb 的方法:
dd if=/dev/zero bs=1G count=10 | gzip -c > 10GB.gz
這個命令的作用如下:
dd:用于拷貝或轉換數據;
if:指定輸入文件,這里是 /dev/zero,一個會不斷生成零字節數據的特殊設備;
bs=1G:設置塊大小為 1GB,意味著每次處理 1GB 數據;
count=10:處理 10 個這樣的塊,總共生成 10GB 的零數據;
然后我們將這些數據通過管道傳給 gzip,生成一個壓縮文件 10GB.gz,壓縮后大小大約是 10MB。
在我的服務器上,我寫了一個中間件程序,用來自動識別哪些請求是惡意的。
我維護了一個黑名單 IP 列表,專門記錄那些反復掃描整個網站的地址。同時還有一些啟發式策略來檢測垃圾信息發送者。很多垃圾腳本會在發完內容后再次訪問頁面,看內容是否成功插入,我正是利用這個行為模式來識別它們。
當系統判斷出請求是惡意的,就觸發如下邏輯:
if (ipIsBlackListed() || isMalicious()) {
header("Content-Encoding: deflate, gzip");
header("Content-Length: " . filesize(ZIP_BOMB_FILE_10G)); // 10MB
readfile(ZIP_BOMB_FILE_10G);
exit;
}
就是這么簡單。我只需要“送出”一個 10MB 的文件,就可能讓對方服務器宕機。如果哪天我的文章突然大火、訪問量激增,我就把炸彈換成 1MB 的“輕量版”,對付低端爬蟲也完全足夠。
Zip Bomb 并不是萬能的
最后再補充一點:zip 炸彈并不是萬能的。
高級一點的爬蟲可以識別壓縮文件,提前做限制,比如只讀取一部分或禁止解壓,這樣就能繞過炸彈。不過那些“低級無腦亂爬”的腳本,就非常容易中招了。
而我需要的,就是一個成本低、效果好的防御手段。對于這種級別的威脅來說,“zip 炸彈”已經綽綽有余。
特別聲明:以上內容(如有圖片或視頻亦包括在內)為自媒體平臺“網易號”用戶上傳并發布,本平臺僅提供信息存儲服務。
Notice: The content above (including the pictures and videos if any) is uploaded and posted by a user of NetEase Hao, which is a social media platform and only provides information storage services.