一個正規表達式擊垮了 Cloudflare。27 分鐘。
2019 年 7 月 2 日,世界標準時間 13:42:Cloudflare 的網路應用程式防火牆 (WAF) 的一項新規則在大約兩秒鐘內在全球 180 多個城市上線。
2019 年 7 月 2 日,世界標準時間 13:42:Cloudflare 的網路應用程式防火牆 (WAF) 的一項新規則在大約兩秒鐘內在全球 180 多個城市上線。這是一項模擬模式下的 XSS 規則,因此它不會阻止任何內容,但它仍然會在每個請求上運行,並且它以 .*(?:.*=.*) 結尾。PCRE 進行回溯,每個處理 HTTP 請求的 CPU 核心都達到 100 %,每個經 Cloudflare 代理的網站都返回 502 錯誤達 27 分鐘;流量下降 82 %。終止開關位於 Cloudflare Access 後面,而 Cloudflare Access 又位於 Cloudflare 後面。事後分析,來自 Cloudflare 自己的報告:數週前在為節省 CPU 而進行的重構中刪除了 CPU 防護措施,允許任何規則跳過階段的程序,沒有複雜性保證的引擎,11 個原因和 7 個修復方法。對修復方法的評斷:SHIP IT。
本影片重點
- 世界標準時間 13:31–13:42:PR 合併,CI 綠燈(沒有 CPU 測試),Quicksilver 將規則推送到 180 多個城市;WAF 規則跳過了 DOG → PIG → Canary 階段
- 13:45–14:07:第一個頁面;全球 CPU 達 100 %,流量 −82 %,各地都出現 502 錯誤;內部控制面板位於 Cloudflare Access 後面,而 Cloudflare Access 已癱瘓;一些憑證已過期;一個很少演練的繞行方法
- 14:07–14:09:全球 WAF 終止;27 分鐘後流量和 CPU 恢復正常;14:52 WAF 恢復運作,但移除了該規則
- 7 月 2 日(世界標準時間 15:50)和 7 月 12 日:Cloudflare 發布了當日筆記和完整的事後分析;重新添加了 CPU 防護,重新讀取了 3,868 條規則,階段性部署,轉向線性時間正規表達式引擎
翻譯文字稿
譯自英文原版旁白。可用的音訊和字幕由 YouTube 控制。
0:00 一個正規表達式同時在每個 Cloudflare 伺服器上線, 接下來的二十七分鐘,其後面的網站都顯示 502 頁面, 這對於防火牆來說,是最嚴格的設定。 2019 年 7 月 2 日,世界標準時間 13:42。 Cloudflare 在兩小時內發文:不是攻擊,是錯誤部署, 流量下降 82 %。 十天後,技術長 John Graham-Cumming 發布了完整的事後分析, 包括正規表達式,Hacker News 給予了 698 點讚,
0:26 這對於一次服務中斷來說,簡直是起立鼓掌。 它是如何發生的,為什麼會發生,以及誰真正該受責備。 這是 The Daily Diff,事後分析。 13:31。一個拉取請求合併:一條新的防火牆規則,用於防範跨站點 腳本攻擊,以模擬模式運行,因此它不會阻擋任何東西。 13:37,測試通過;沒有一個測量 CPU。 13:42,該規則在兩秒內發送到 180 個城市, 因為 WAF 規則跳過了其他版本會經過的 dog、pig 和 canary 階段。
0:54 13:45,第一個頁面。 13:49,Hacker News 上有一條關於狀態頁面的討論串, 該狀態頁面仍然顯示所有系統正常運行。 該規則以點星號,點星號,等於,點星號結尾:任何東西, 然後是任何東西,然後是等號。 PCRE 貪婪地猜測,失敗,並回溯所有其他分割。 x 等於 x 需要 23 步。 等號後面有二十個 x:555。
1:15 二十個 x,沒有等號:4,067 步才能找到空無一物。 在每個請求上運行,每個核心都達到百分之百, 徹底地什麼都沒做。 兩個守護者應該要發現它。 規則的 CPU 限制在幾週前被錯誤地刪除, 在一個旨在讓 WAF 使用更少 CPU 的重構中。 而且程序允許任何規則跳過部署階段,因為規則是為了阻止即時 攻擊;這個並非緊急情況,但它仍然全球上線了。
1:37 14:00,WAF 被識別;不是攻擊。 14:02,有人提議全球終止:一個組件, 關閉,全球範圍。該開關位於 Cloudflare Access 後面。 Cloudflare Access 位於 Cloudflare 後面。 一些憑證因久未使用而過期,因此互聯網上最快的網路 花了五分鐘在一個無人演練過的繞行方法上。 14:07,終止。14:09,流量恢復正常。 git blame:一個速度只有一種,全球性的部署;一個 CPU 防護措施因
2:04 意外而重構移除;一個沒有上限的正規表達式引擎。 不是編寫規則的工程師:事後分析列出了 11 個原因,但 沒有指名道姓。影響範圍:27 分鐘,82 % 的流量, 每個城市,每個核心 100 % 的 CPU 佔用。 儀表板和 API 位於同一個邊緣,因此客戶甚至無法將其關閉。 Hacker News,在事後分析下:他們有一個問題, 使用了正規表達式,現在他們有兩個問題了。 老笑話。仍然適用。
2:28 判斷,事後分析:SHIP IT。 CPU 防護已恢復,所有 3,868 條規則都經過人工審閱, 規則經過部署階段,並且引擎轉向 Ken Thompson 於 1968 年發布的 具有線性時間保證的引擎。 週一:任何在每個請求中運行的內容都不能包含點星號點星號, 並將終止開關與其所關閉的對象分開。 將你仍然不被允許談論的事件寄給我, 在評論中,或者寄到 the daily diff dot dev。
2:53 這就是今天的 diff。 我是來自 Axrisi 的 Niko。 負責任地合併。
來源
- John Graham-Cumming, "Details of the Cloudflare outage on July 2, 2019" (Jul 12, 2019)blog.cloudflare.com
- Matthew Prince, "Cloudflare outage caused by bad software deploy (updated)" (Jul 2, 2019)blog.cloudflare.com
- Matthew Prince on X, Jul 2, 2019, 14:22 UTCx.com
- Matthew Prince on X, Jul 2, 2019, 14:36 UTC ("No evidence yet attack related")x.com
- Hacker News, Jul 2, 2019, 13:49 UTC — "Cloudflare Network Performance Issues" (631 points)news.ycombinator.com
- Hacker News, Jul 2, 2019 — "Cloudflare outage caused by bad software deploy" (348 points)news.ycombinator.com
- Hacker News, Jul 12, 2019 — "Details of the Cloudflare outage on July 2, 2019" (698 points)news.ycombinator.com
- TechCrunch, Jul 2, 2019techcrunch.com



