23 điểm bởi GN⁺ 2025-11-19 | 8 bình luận | Chia sẻ qua WhatsApp
  • Vào 11:20 (UTC) ngày 18 tháng 11 năm 2025, chức năng phân phối lưu lượng cốt lõi của mạng Cloudflare bị gián đoạn, khiến người dùng trên toàn cầu nhìn thấy trang lỗi
  • Nguyên nhân là tệp feature của hệ thống Bot Management phình to bất thường do thay đổi quyền cơ sở dữ liệu, không liên quan đến tấn công mạng
  • Việc kích thước tệp tăng lên khiến phần mềm định tuyến lưu lượng vượt quá ngưỡng giới hạn và thất bại, gây ra lỗi HTTP 5xx trên diện rộng
  • Khoảng 14:30, Cloudflare dừng triển khai tệp có vấn đề và thay bằng phiên bản ổn định trước đó để khôi phục lưu lượng cốt lõi; đến 17:06, mọi dịch vụ đã hoạt động bình thường trở lại
  • Cloudflare đánh giá đây là sự cố nghiêm trọng nhất kể từ năm 2019, và đang thúc đẩy các biện pháp ngăn tái diễn như tăng cường kiểm tra tệp cấu hình và bổ sung công tắc ngắt toàn cục

Tổng quan sự cố

  • Khoảng 11:20, mạng Cloudflare gặp lỗi phân phối lưu lượng cốt lõi, người dùng thấy trang lỗi nội bộ của Cloudflare
  • Không phải tấn công mạng hay hành vi ác ý, mà nguyên nhân trực tiếp là thay đổi quyền trong hệ thống cơ sở dữ liệu
  • Thay đổi này khiến kích thước của tệp feature mà hệ thống Bot Management sử dụng tăng gấp đôi, rồi được triển khai trên toàn mạng
  • Trong quá trình phần mềm định tuyến lưu lượng đọc tệp này, nó đã vượt quá giới hạn kích thước tệp, gây lỗi hệ thống
  • Ban đầu sự cố bị nhầm là một cuộc tấn công DDoS quy mô lớn, nhưng sau khi xác định được nguyên nhân, Cloudflare đã thay bằng tệp ổn định trước đó để tiến hành khôi phục

Diễn biến và tác động của sự cố

  • Trước 11:20, tỷ lệ lỗi 5xx ở mức bình thường; sau đó tăng vọt do triển khai nhầm tệp feature lỗi
  • Trên một số node của cụm cơ sở dữ liệu ClickHouse, kết quả truy vấn sai được tạo ra theo chu kỳ 5 phút, khiến các tệp bình thường và bất thường luân phiên được triển khai, làm hệ thống liên tục rơi vào vòng lặp phục hồi rồi lại thất bại
  • Từ 14:30, Cloudflare ngừng tạo tệp có vấn đề và chèn thủ công tệp bình thường, sau đó khôi phục bằng cách khởi động lại proxy lõi
  • 17:06, toàn bộ dịch vụ trở lại bình thường
Dịch vụ Nội dung ảnh hưởng
Core CDN và dịch vụ bảo mật Xuất hiện lỗi HTTP 5xx
Turnstile Tải thất bại, không thể đăng nhập
Workers KV Lỗi gateway khiến lỗi 5xx tăng mạnh
Dashboard Không thể đăng nhập do Turnstile gặp sự cố
Email Security Độ chính xác phát hiện spam tạm thời giảm, một số thao tác di chuyển tự động thất bại
Access Xảy ra nhiều lỗi xác thực, nhưng phiên hiện có vẫn được duy trì
  • Trong thời gian sự cố, độ trễ phản hồi của CDN tăng lên, nguyên nhân là mức sử dụng CPU của hệ thống debug tăng đột biến

Nguyên nhân sự cố: hệ thống Bot Management

  • Mô-đun Bot Management của Cloudflare dùng mô hình máy học để tạo điểm bot cho từng request
  • Tệp cấu hình feature dùng làm đầu vào cho mô hình được triển khai trên toàn mạng sau mỗi vài phút để phản ứng với các mối đe dọa mới nhất
  • Do thay đổi hành vi truy vấn của ClickHouse, nhiều dòng feature trùng lặp đã được đưa vào, làm kích thước tệp tăng lên
  • Vì vậy mô-đun Bot Management gặp lỗi và trả về phản hồi HTTP 5xx, đồng thời ảnh hưởng đến Workers KV và Access
  • Trên engine proxy mới FL2, lỗi 5xx xảy ra; còn trên phiên bản cũ FL, điểm bot bị đặt về 0, làm tăng false positive

Thay đổi hành vi truy vấn ClickHouse

  • Lúc 11:05, thay đổi quyền truy cập cơ sở dữ liệu của ClickHouse được triển khai
  • Trước đó chỉ có thể truy vấn metadata của cơ sở dữ liệu default, nhưng sau thay đổi, metadata của cơ sở dữ liệu r0 cũng được lộ ra
  • Truy vấn tạo tệp feature của Bot Management được chạy mà không lọc theo tên cơ sở dữ liệu, nên cuối cùng trả về các cột trùng lặp
  • Điều này khiến số dòng trong tệp feature tăng hơn gấp đôi, vượt quá giới hạn của hệ thống

Cấp phát bộ nhớ trước và panic hệ thống

  • Mô-đun Bot Management giới hạn tối đa 200 feature của mô hình máy học và cấp phát bộ nhớ trước dựa trên giới hạn đó
  • Khi tệp sai chứa số feature vượt quá 200, mã Rust phát sinh panic, với thông báo lỗi
    thread fl2_worker_thread panicked: called Result::unwrap() on an Err value
  • Kết quả là lỗi HTTP 5xx xảy ra trên diện rộng

Các ảnh hưởng khác và quá trình khôi phục

  • Workers KV và Access phụ thuộc vào proxy lõi nên mức ảnh hưởng lan rộng hơn
    • Lúc 13:04, Workers KV được vá để đi vòng qua proxy, giúp tỷ lệ lỗi giảm xuống
  • Dashboard phụ thuộc vào Turnstile và Workers KV nên không thể đăng nhập
    • Có hai giai đoạn suy giảm khả dụng: 11:30~13:10 và 14:40~15:30
    • Độ trễ tăng do backlog và các request thử lại, rồi được khôi phục vào khoảng 15:30
  • Sau 14:30, phần lớn dịch vụ trở lại bình thường; 17:06 hoàn tất khôi phục hoàn toàn

Biện pháp ngăn tái diễn

  • Tăng cường kiểm tra đầu vào cho các tệp cấu hình do Cloudflare tạo ra
  • Mở rộng công tắc ngắt tính năng toàn cục (kill switch)
  • Ngăn cạn kiệt tài nguyên hệ thống do báo lỗi
  • Rà soát các điều kiện lỗi trên toàn bộ các mô-đun proxy lõi

Tóm tắt timeline (UTC)

Thời điểm Trạng thái Mô tả
11:05 Bình thường Triển khai thay đổi kiểm soát truy cập cơ sở dữ liệu
11:28 Bắt đầu ảnh hưởng Xuất hiện lỗi đầu tiên trên lưu lượng khách hàng
11:32–13:05 Điều tra đang diễn ra Phân tích nguyên nhân lỗi của Workers KV, thử các biện pháp giảm nhẹ
13:05 Mức ảnh hưởng giảm Áp dụng đường vòng cho Workers KV và Access
13:37 Tập trung khôi phục Chuẩn bị rollback tệp cấu hình của Bot Management
14:24 Dừng triển khai tệp lỗi Hoàn tất kiểm thử tệp bình thường
14:30 Giải quyết phần lớn tác động Triển khai toàn cục tệp bình thường, bắt đầu khôi phục dịch vụ
17:06 Khôi phục hoàn toàn Tất cả dịch vụ hoạt động bình thường trở lại

Kết luận

  • Sự cố lần này xảy ra do tương tác giữa logic tạo tệp cấu hình của Bot Management và thay đổi quyền cơ sở dữ liệu
  • Cloudflare đánh giá đây là sự cố gián đoạn mạng nghiêm trọng nhất kể từ năm 2019
  • Trong thời gian tới, công ty sẽ thúc đẩy các cải tiến mang tính cấu trúc và tăng cường hệ thống phòng vệ tự động để nâng cao khả năng phục hồi của hệ thống

8 bình luận

 
t7vonn 2025-11-19

Sự cố liên quan đến tệp cấu hình thì ở đâu cũng xảy ra nhỉ.

 
princox 2025-11-19

Cloudflare bị sự cố khiến đủ loại dịch vụ ngừng hoạt động, đúng là địa ngục..

 
epdlemflaj 2025-11-19

Tài liệu phân tích nguyên nhân được công bố khá nhanh nhỉ, ghê thật

 
epdlemflaj 2025-11-19

Mà tiện thể, tác giả của bài viết này lại chính là CEO.

 
GN⁺ 2025-11-19
Ý kiến trên Hacker News
  • Đây là một câu chuyện tai nạn .unwrap() trị giá hàng triệu đô
    Việc gọi .unwrap() trên đường đi của hạ tầng cốt lõi Internet chẳng khác nào tuyên bố rằng “việc này tuyệt đối không thể thất bại, nếu thất bại thì giết luôn thread ngay lập tức”
    Trình biên dịch Rust buộc phải biểu đạt rõ khả năng thất bại, nhưng ở đây họ đã chọn panic thay vì xử lý một cách mềm dẻo
    Tôi nghĩ đây là một ví dụ điển hình của phản mẫu “parse, don’t validate

    • Có vẻ nhiều người có điểm mù với .unwrap(). Có lẽ vì nó xuất hiện quá thường xuyên trong code ví dụ
      Trong code vận hành thực tế, .unwrap() hay .expect() nên được review như panic
      Nếu dùng .unwrap() trong code production thì bắt buộc phải có chú thích “INFALLIBILITY”, và có thể cưỡng chế điều này bằng clippy::unwrap_used
    • Ý chính của bài này dường như là vấn đề phát sinh từ sự kết hợp của các thành phần vốn hoạt động bình thường hơn là từ một nguyên nhân đơn lẻ
      Không chỉ vì .unwrap(), mà còn vì truy vấn không phân biệt cơ sở dữ liệu nên payload phình to, và ClickHouse lại phơi bày thêm nhiều DB hơn
      Thay vì khẳng định đơn giản là “do unwrap”, tôi nghĩ điều quan trọng hơn là cải thiện thiết kế để có global kill switch hoặc tránh làm quá tải tài nguyên hệ thống
    • Thực ra việc này vẫn sẽ thất bại ngay cả ngoài nhánh Rust. Vì hệ thống quản lý bot đã phân loại toàn bộ lưu lượng thành bot
      Ở tầng FL2 cần bắt panic của từng component, nhưng fail-open không phải lúc nào cũng tốt hơn
      Cần thêm logic để quyết định một cách tường minh ở cấp FL2 xem có nên bắt panic và xử lý hay không
    • Nếu được xử lý mềm dẻo thì có lẽ sẽ có suy giảm hiệu năng (dù tôi vẫn nghĩ còn tốt hơn là suy giảm độ tin cậy)
      Nếu là hệ thống sharding, tôi cũng thắc mắc tại sao lại không có rollout dần và giám sát
    • Swift có unwrap ngầm ! và unwrap tường minh ?
      Tôi hầu như không dùng unwrap ngầm. Kể cả với giá trị đã được đảm bảo, tôi vẫn luôn xử lý tường minh
      Ví dụ tôi sẽ định nghĩa @IBOutlet weak var someView? thay vì @IBOutlet weak var someView!
      Đây là kiểu tiếp cận belt & suspenders
  • Việc công bố post mortem chưa đầy 24 giờ sau sự cố thật sự rất ấn tượng

    • Tôi tò mò về chính sách nội bộ nào cho phép họ công khai nhanh và minh bạch như vậy
      Với hầu hết các tập đoàn lớn, việc công bố code gần như là bất khả thi vì phải qua nhiều vòng xem xét của các stakeholder
    • Hơn nữa, bài viết tự thân nó cũng được viết rất tốt. So với các postmortem của AWS thì gần như đạt tầm văn chương
  • Khi đọc phần giải thích sự cố của Cloudflare, tôi đã tự hỏi “tại sao khôi phục lại mất lâu đến vậy”
    Tôi hiểu nguyên nhân gây sự cố, nhưng nếu phần lớn mạng lưới bị sập thì chẳng phải ưu tiên số một là hoàn tác thay đổi cấu hình gần nhất sao
    Tất nhiên nhìn lại thì mọi thứ đều rõ ràng hơn, nhưng việc họ bắt đầu điều tra chỉ sau 7 phút vẫn rất đáng nể

    • Ban đầu họ nhầm là bị tấn công. Sau đó đã xác định được vấn đề, nhưng không có cách thay thế file hỏng trong hàng đợi, nên phải khởi động lại vô số máy trên toàn thế giới
  • Vụ việc này gợi cảm giác giống sự cố CrowdStrike
    Một file cấu hình được tạo tự động đã làm phần mềm hỏng và lan ra toàn bộ mạng lưới
    Tôi hiểu việc cần triển khai nhanh, nhưng lần này đã bộc lộ sự thiếu vắng của chiến lược rollout dần và rollback

    • Xem đây như kênh điều khiển của một hệ thống phát hiện bot phân tán thì đúng hơn là một đợt triển khai CI/CD
    • Điều đáng ngạc nhiên là họ đẩy thẳng vào production mà không có simulator
    • Dù vậy, tôi tin rằng từ sự việc này họ sẽ có cải tiến
  • Nhìn vào kế hoạch cải thiện trong tương lai mà Cloudflare công bố,

    • Tăng cường xác thực các file cấu hình do Cloudflare tạo ra
    • Thêm global kill switch
    • Ngăn cạn kiệt tài nguyên do core dump hoặc báo lỗi
    • Rà soát các chế độ lỗi của module proxy
      có các mục như vậy
      Nhưng lại không thấy canary deployment hay triển khai cấu hình dần dần
      Global switch có thể nguy hiểm, và chỉ một lỗi cũng có thể làm dừng toàn bộ hệ thống
    • Cấu hình quản lý bot đúng là cần được lan truyền nhanh, nhưng nếu thử trước trên một instance thì đã có thể bắt panic sớm
      Tôi cũng thắc mắc vì sao lại dùng ClickHouse làm kho lưu feature flag. Ngay cả tài liệu deduplication của ClickHouse cũng có nói đến các yếu tố rủi ro
    • Dịch vụ cấu hình có rollout dần, nhưng các dịch vụ tiêu thụ lại tự động cập nhật quá thường xuyên nên chỉ một tỷ lệ lỗi nhỏ cũng ảnh hưởng đến toàn bộ
    • Cấu hình toàn cục hữu ích cho phản ứng nhanh, nhưng cơ chế rollback nhanh là bắt buộc
      Nếu có bản đồ quan hệ phụ thuộc giữa các dịch vụ thì việc lần ra nguyên nhân sẽ dễ hơn rất nhiều
    • Rốt cuộc thì phần lớn các sự cố lớn đều đến từ config push
      Việc triển khai code thì cẩn trọng, còn triển khai cấu hình thì không. Cần nhìn nhận cấu hình cũng là code
  • Chi tiết trạng thái trang status cũng bị sập, dẫn tới việc ban đầu bị nhầm là bị tấn công, khá thú vị
    Họ nói nó hoàn toàn tách biệt với hạ tầng Cloudflare, nhưng lại không giải thích vì sao nó cũng chết theo

    • Rất có thể là do lưu lượng tăng vọt khiến việc mở rộng hạ tầng thất bại
    • Thực tế có thể họ nghĩ là không phụ thuộc Cloudflare, nhưng vì một phần lớn Internet phụ thuộc vào CloudFront, nên chưa chắc đã thật sự độc lập hoàn toàn
    • Muốn biết nguyên nhân thì cần postmortem của statuspage.io. Đây là dịch vụ do Atlassian vận hành
    • Cũng có thể đơn giản là vì quy mô của Cloudflare quá lớn nên lưu lượng đổ dồn vào
  • Tôi đã tích hợp Turnstile theo chiến lược fail-open, và lần sự cố này nó đã phát huy tác dụng
    Nếu JS không tải được thì vẫn cho phép gửi bằng token giả, còn ở backend nếu xác thực thất bại thì cũng xử lý theo fail-open
    Một số người dùng vẫn bị chặn, nhưng tác động tổng thể đã giảm bớt
    Đây là cách tiếp cận chỉ khả thi khi có các biện pháp giảm thiểu bot khác

    • Vậy thì cũng có câu hỏi là kẻ tấn công chỉ cần chặn script là có thể vượt CAPTCHA hay không
      Nhưng có lẽ điều này chỉ hiệu quả khi không phải tấn công có chủ đích
  • Tôi thắc mắc tại sao code của Cloudflare lại cho phép .unwrap()
    Ít nhất họ cũng nên dùng expect("chuyện này tuyệt đối không xảy ra")
    Triết lý coi lỗi là giá trị vốn là để ngăn những vấn đề kiểu này, và nó cũng sẽ giúp việc chẩn đoán dễ hơn rất nhiều

    • Tôi không phải nhân viên Cloudflare, nhưng dùng Rust khá nhiều
      Trong code có lời gọi mạng, khả năng thất bại là quá nhiều
      Lúc phát triển thì tôi có dùng .unwrap(), nhưng trong production đôi khi vẫn để lại expect(). Vì có những lúc thực sự không còn cách nào để tiếp tục
  • Bài học thật sự là có quá nhiều chức năng đang phụ thuộc vào một số ít người chơi
    Cấu trúc người thắng ăn cả đang ngày càng trầm trọng, làm suy giảm tính đàn hồi của hệ thống
    Tất nhiên vị thế đó là do họ có năng lực mà đạt được, nhưng kỳ vọng Internet lúc nào cũng sẽ “hoạt động bình thường” có lẽ là hơi quá

  • Câu nói “cứ là Rust thì sẽ an toàn” là phóng đại
    Dù là ngôn ngữ nào thì dùng sai cũng chẳng khác gì tự chĩa súng vào chân mình

 
barca105 2025-11-19

Ngay cả một công ty tầm cỡ như CF mà cũng dùng .unwrap() nhỉ, ghê thật.
Không hiểu đoạn code đó đã được đưa vào production bằng cách nào

 
skageektp 2025-11-19

Có vẻ không phải vấn đề của unwrap

 
barca105 2025-11-19

Vấn đề cốt lõi là truy vấn bị sai.
Nhưng tôi cũng nghĩ việc bỏ qua khâu kiểm chứng vấn đề bằng unwrap cũng là một vấn đề.
Dù nội bộ có phát sinh sự cố đi nữa, nếu đã xử lý lỗi thì có lẽ lưu lượng sẽ không bị sập.