18 листопада 2025 року о 11:20 UTC (увесь час у цьому блозі вказано за UTC) у мережі Cloudflare почалися значні збої в доставці основного мережевого трафіку. Це відображалося для користувачів Інтернету, які намагалися отримати доступ до сайтів наших клієнтів, як сторінка помилки, що свідчила про збій у мережі Cloudflare.
Проблема не була спричинена, прямо чи опосередковано, кібератакою чи будь-якими зловмисними діями. Натомість, це було спричинено зміною дозволів однієї з наших систем баз даних, що призвело до того, що база даних виводила кілька записів у «файл функцій», який використовується нашою системою Bot Management. Цей файл функцій, у свою чергу, збільшився вдвічі. Файл функцій, розмір якого виявився більшим, ніж очікувалося, був потім розповсюджений на всі машини, що входять до нашої мережі.
Програмне забезпечення, що працює на цих машинах для маршрутизації трафіку через нашу мережу, зчитує цей файл функцій, щоб наша система Bot Management була в курсі динамічних загроз. Програмне забезпечення мало обмеження на розмір файлу функцій, який був меншим за його подвоєний розмір. Це призвело до збою програмного забезпечення.
Спочатку ми помилково припустили, що симптоми, які ми спостерігали, були спричинені гіпермасштабною DDoS-атакою, але потім правильно визначили основну проблему та змогли зупинити поширення файлу функцій, розмір якого виявився більшим, ніж очікувалося, та замінити його попередньою версією файлу. Станом на 14:30 основний трафік здебільшого функціонував у звичайному режимі. Протягом наступних кількох годин ми працювали над зменшенням навантаження на різні частини нашої мережі, оскільки трафік стрімко відновлювався. Станом на 17:06 усі системи на Cloudflare працювали у звичайному режимі.
Ми приносимо свої вибачення за незручності, спричинені нашим клієнтам та Інтернету загалом. Враховуючи важливість Cloudflare в екосистемі Інтернету, будь-який збій у роботі будь-якої з наших систем є неприйнятним. Той період, коли наша мережа не могла маршрутизувати трафік, дуже засмучує кожного члена нашої команди. Ми знаємо, що сьогодні ми вас підвели.
Ця публікація є детальним описом того, що саме сталося, та які системи та процеси дали збій. Це також початок, хоча й не кінець того, що ми плануємо зробити, щоб переконатися, що подібні перебої більше не повторяться.
Наведена нижче діаграма показує обсяг кодів стану помилок HTTP 5xx, що обслуговуються мережею Cloudflare. Зазвичай цей показник має бути дуже низьким, і так було аж до початку збою.
Обсяг до 11:20 — це очікуваний базовий рівень помилок 5xx, що спостерігаються в нашій мережі. Пік та подальші коливання свідчать про збій нашої системи через завантаження неправильного файлу функцій. Примітно те, що наша система потім відновлювалася протягом певного періоду. Це була дуже незвичайна поведінка для внутрішньої помилки.
Пояснення полягало в тому, що файл генерувався кожні п'ять хвилин запитом, що виконується на кластері бази даних ClickHouse, який поступово оновлювався для покращення управління дозволами. Неправильні дані генерувалися лише тоді, коли запит виконувався на частині кластера, яка була оновлена. В результаті, кожні п'ять хвилин існувала ймовірність того, що хороший або поганий набір файлів конфігурації буде згенеровано та швидко пошириться мережею.
Через це коливання було незрозуміло, що відбувається, оскільки вся система відновлювалася, а потім знову давала збій, оскільки в нашу мережу поширювалися іноді хороші, іноді несправні файли конфігурації. Спочатку це змусило нас припустити, що це може бути спричинено атакою. Зрештою, кожен вузол ClickHouse генерував несправний файл конфігурації, і коливання стабілізувалися у стані відмови.
Помилки продовжувалися, доки основна проблема не була виявлена та вирішена, починаючи з 14:30. Ми вирішили проблему, зупинивши генерацію та поширення несправного файлу функцій та вручну вставивши відомий справний файл у чергу розповсюдження файлів функцій. А потім примусово перезапустили наш основний проксі-сервер.
Довгий хвіст, що залишився на діаграмі вище, показує, як наша команда перезапускає решту служб, які перейшли у несправний стан, при цьому обсяг коду помилки 5xx повернувся до норми о 17:06.
Це вплинуло на такі служби:
Послуга / Продукт | Опис впливу |
|---|
Основні CDN та послуги безпеки | Коди стану HTTP 5xx. Знімок екрана у верхній частині цієї публікації показує типову сторінку помилки, яка відображається кінцевим користувачам. |
Turnstile | Не вдалося завантажити Turnstile. |
Workers KV | Workers KV повертали значно підвищений рівень помилок HTTP 5xx, оскільки запити до шлюзу «фронт-енду» KV не були виконані через збій основного проксі-сервера. |
Інформаційна панель | Хоча панель інструментів здебільшого працювала, більшість користувачів не змогли увійти через те, що Turnstile був недоступний на сторінці входу. |
Email Security | Хоча обробка та доставка електронної пошти не змінилися, ми спостерігали тимчасову втрату доступу до джерела репутації IP-адреси, що знизило точність виявлення спаму та завадило спрацюванню деяких механізмів виявлення нових доменів, однак це не мало критичного впливу на клієнтів. Ми також спостерігали збої в деяких діях автоматичного переміщення; усі повідомлення, на які це вплинуло, було перевірено та виправлено. |
Access | Збої автентифікації були поширеними для більшості користувачів, починаючи з самого початку інциденту і продовжуючись до початку відновлення роботи о 13:05. Будь-які існуючі сеанси доступу не змінилися.
Усі невдалі спроби автентифікації призвели до появи сторінки з помилкою, тобто жоден із цих користувачів не зміг отримати доступ до цільової програми під час невдалої автентифікації. Успішні входи протягом цього періоду були правильно зареєстровані під час цього інциденту.
Будь-які спроби оновлення конфігурації Access в цей час або зазнали невдачі, або поширювалися дуже повільно. Усі оновлення конфігурації тепер відновлено. |
Окрім повернення помилок HTTP 5xx, ми спостерігали значне збільшення затримки відповідей від нашої CDN протягом періоду впливу. Це було пов'язано з великим споживанням ресурсів процесора нашими системами налагодження та спостереження, які автоматично доповнюють неперехоплені помилки додатковою інформацією для налагодження.
Як Cloudflare обробляє запити та як сьогодні виникли проблеми
Кожен запит до Cloudflare проходить чітко визначений шлях через нашу мережу. Це може бути завантаження вебсторінки браузером, виклик API мобільним додатком або автоматизований трафік з іншого сервісу. Ці запити спочатку завершуються на нашому рівні HTTP та TLS, потім надходять до нашої основної проксі-системи (яку ми називаємо FL від «Frontline») і, нарешті, через Pingora, яка виконує пошук у кеші або отримує дані з джерела, якщо це необхідно.
Раніше ми детальніше розповідали про те, як працює основний проксі-сервер, тут.
Коли запит проходить через основний проксі-сервер, ми запускаємо різні продукти безпеки та продуктивності, доступні в нашій мережі. Проксі-сервер застосовує унікальну конфігурацію та налаштування кожного клієнта, від застосування правил WAF та захисту від DDoS-атак до маршрутизації трафіку на платформу розробників та R2. Це досягається за допомогою набору доменно-специфічних модулів, які застосовують правила конфігурації та політики до трафіку, що проходить через наш проксі-сервер.
Один із цих модулів, Bot Management, був причиною сьогоднішнього збою.
Bot Management Cloudflare включає, серед інших систем, модель машинного навчання, яку ми використовуємо для генерації оцінок ботів для кожного запиту, що проходить через нашу мережу. Наші клієнти використовують оцінки ботів, щоб контролювати, яким ботам дозволено доступ до їхніх сайтів, а яким — ні.
Cloudflare включає, серед інших систем, модель машинного навчання, яку ми використовуємо для генерації оцінок ботів для кожного запиту, що проходить через нашу мережу. Наші клієнти використовують оцінки ботів, щоб контролювати, яким ботам дозволено доступ до їхніх сайтів, а яким — ні.
Модель приймає на вхід файл конфігурації «функції». Функція, у цьому контексті, — це окрема риса, яка використовується моделлю машинного навчання для прогнозування того, чи був запит автоматизований чи ні. Файл конфігурації функцій — це набір окремих функцій.
Цей файл функцій оновлюється кожні кілька хвилин і публікується для всієї нашої мережі, що дозволяє нам реагувати на зміни в потоках трафіку в Інтернеті. Це дозволяє нам реагувати на нові типи ботів та нові атаки ботів. Тому критично важливо, щоб його впроваджували часто та швидко, оскільки зловмисники швидко змінюють свою тактику.
Зміна в нашій базовій поведінці запиту ClickHouse (пояснено нижче), яка генерує цей файл, призвела до появи великої кількості дублікатів рядків «функцій». Це змінило розмір файлу конфігурації функцій, який раніше мав фіксований розмір, що призвело до виникнення помилки модуля ботів.
В результаті, основна проксі-система, яка обробляє трафік для наших клієнтів, повертала коди помилок HTTP 5xx для будь-якого трафіку, що залежав від модуля ботів. Це також вплинуло на Workers KV та Access, які покладаються на основний проксі-сервер.
Незалежно від цього інциденту, ми переносили та наразі переносимо трафік наших клієнтів на нову версію нашого проксі-сервісу, внутрішньо відому як FL2. Обидві версії постраждали від проблеми, хоча її вплив був різним.
Клієнти, які використовували новий проксі-двигун FL2, спостерігали помилки HTTP 5xx. Клієнти нашого старого проксі-двигуна, відомого як FL, не бачили помилок, але оцінки ботів генерувалися неправильно, в результаті чого весь трафік отримував нульову оцінку ботів. Клієнти, у яких були розгорнуті правила для блокування ботів, могли спостерігати велику кількість хибнопозитивних результатів. Клієнти, які не використовували нашу бот-оцінку у своїх правилах, не помітили жодного впливу.
Ще одним симптомом став неочікуваний збій, через який ми навіть припустили, що це могла бути атака: сторінка стану Cloudflare перестала працювати. Сторінка стану повністю розміщена поза інфраструктурою Cloudflare без жодних залежностей від Cloudflare. Хоча це виявилося випадковістю, деякі члени команди, яка діагностувала проблему, припустили, що зловмисник може атакувати як наші системи, так і нашу сторінку стану. Відвідувачів сторінки стану в той час бачили повідомлення про помилку:
У внутрішньому чаті інцидентів ми висловили стурбованість тим, що це може бути продовженням нещодавньої серії масових DDoS-атак Aisuru:
Я згадував вище, що зміна в базовій поведінці запиту призвела до того, що файл функцій містив велику кількість дублікатів рядків. Система баз даних, про яку йде мова, використовує програмне забезпечення ClickHouse.
Для контексту корисно знати, як працюють розподілені запити ClickHouse. Кластер ClickHouse складається з багатьох шардів. Для запиту даних з усіх шардів у нас є так звані розподілені таблиці (на базі даних під назвою Distributed), що працюють на базі даних Default. Механізм Distributed запитує базові таблиці в базі даних r0. Базові таблиці — це місце, де зберігаються дані на кожному шарді кластера ClickHouse.
Запити до розподілених таблиць виконуються через спільний системний обліковий запис. В рамках зусиль щодо покращення безпеки та надійності наших розподілених запитів проводиться робота над тим, щоб вони виконувалися від імені початкових облікових записів користувачів.
До сьогодні користувачі ClickHouse бачили таблиці лише в базі даних Default під час запиту метаданих таблиць із системних таблиць ClickHouse, таких як system.tables або system.columns.
Оскільки користувачі вже мають неявний доступ до базових таблиць у r0, ми внесли зміни о 11:05, щоб зробити цей доступ явним, аби користувачі також могли бачити метадані цих таблиць. Забезпечуючи можливість виконання всіх розподілених підзапитів від імені початкового користувача, обмеження запитів та надання доступу можна оцінювати більш детально, уникаючи впливу одного поганого підзапиту від одного користувача на інші.
Зміна, описана вище, призвела до того, що всі користувачі отримали точні метадані про таблиці, до яких мають доступ. На жаль, у минулому були припущення, що список стовпців, що повертаються таким запитом, міститиме лише базу даних «Default»:
SELECT
name,
type
FROM system.columns
WHERE
table = 'http_requests_features'
order by name;
Зверніть увагу, що запит не фільтрує за назвою бази даних. Оскільки ми поступово розгортали явні права доступу для користувачів певного кластера ClickHouse, після зміни о 11:05 запит вище почав повертати «дублікати» стовпців, оскільки вони стосувалися базових таблиць, що зберігаються в базі даних r0.
На жаль, саме цей тип запиту виконувалася логікою генерації файлу функцій Bot Management для створення кожної вхідної «функції» для файлу, згаданого на початку цього розділу.
Наведений вище запит поверне таблицю стовпців, подібну до відображеної (спрощений приклад):
Однак, як частина додаткових дозволів, наданих користувачеві, відповідь тепер містила всі метадані схеми r0, фактично більш ніж удвічі перевищуючи кількість рядків у відповіді, що зрештою вплинуло на кількість рядків (тобто функції) у кінцевому вивідному файлі.
Попередній розподіл пам'яті
Кожен модуль, що працює на нашому проксі-сервісі, має низку лімітів, щоб уникнути необмеженого споживання пам'яті та попередньо розподілити пам'ять для оптимізації продуктивності. У цьому конкретному випадку система Bot Management має обмеження на кількість функцій машинного навчання, які можна використовувати під час виконання. Наразі це обмеження встановлено на рівні 200, що значно перевищує наше поточне використання ~60 функцій. Знову ж таки, обмеження існує, оскільки з міркувань продуктивності ми попередньо виділяємо пам'ять для функцій.
Коли на наші сервери було поширено пошкоджений файл з більш ніж 200 ознаками, це обмеження було перевищено, що призвело до збою в системі. Код FL2 Rust, який виконує перевірку та був джерелом необробленої помилки, показано нижче:
Це призвело до наступного збою, який, в свою чергу, призвів до помилки 5хх:
thread fl2_worker_thread panicked: called Result::unwrap() on an Err value
Інший вплив під час інциденту
Інші системи, що залежать від нашого основного проксі-сервера, постраждали під час інциденту. Це включало Workers KV та Cloudflare Access. Команді вдалося зменшити вплив на ці системи о 13:04, коли було випущено патч для Workers KV, щоб обійти основний проксі-сервер. Згодом усі нижчі системи, що покладаються на Workers KV (такі як сам Access), спостерігали зниження рівня помилок.
Панель керування Cloudflare також постраждала через внутрішнє використання Workers KV та розгортання Cloudflare Turnstile як частини нашого процесу входу.
Цей збій вплинув на роботу Turnstile, в результаті чого клієнти, які не мали активного сеансу панелі керування, не могли увійти в систему. Це проявилося у зниженій доступності протягом двох періодів часу: з 11:30 до 13:10 та між 14:40 та 15:30, як видно на графіку нижче.
Перший період, з 11:30 до 13:10, був пов'язаний з впливом на Workers KV, від якого залежать деякі функції площини керування та панелі інструментів. Це було відновлено о 13:10, коли Workers KV обійшли основну проксі-систему. Другий період впливу на панель інструментів стався після відновлення даних конфігурації функцій.
Панель керування почала перевантажуватися накопиченими спробами входу. Це накопичення часу, у поєднанні з повторними спробами, призвело до збільшення затримки, що зменшило доступність панелі інструментів. Масштабування паралельних компонентів контрольної площини відновило доступність приблизно о 15:30.
Виправлення та подальші кроки
Тепер, коли наші системи знову в мережі та функціонують нормально, вже розпочалася робота над тим, як ми захистимо їх від подібних збоїв у майбутньому. Зокрема, ми:
посилимо захист файлів конфігурації, згенерованих Cloudflare, таким самим чином, як і для введених користувачем даних;
увімкнемо більшу кількість глобальних аварійних перемикачів для функцій;
виключимо можливості перевантаження системних ресурсів дампами основних даних або іншими звітами про помилки;
переглянемо режими збоїв на наявність помилок у всіх основних проксі-модулях.
Сьогодні стався найгірший збій у роботі Cloudflare з 2019 року019 roku. У нас були збої, через які наша інформаційна панель стала недоступною. Деякі з них призвели до того, що новіші функції були недоступні протягом певного періоду часу. Але за останні 6+ років у нас не було жодного збою, який би спричинив зупинку більшої частини основного трафіку через нашу мережу.
Такий перерив, як сьогодні, неприйнятний. Ми розробили наші системи таким чином, щоб вони були надзвичайно стійкими до збоїв, щоб забезпечити постійний безперебійний потік трафіку. Коли в минулому у нас траплялися перебої, це завжди призводило до створення нових, більш стійких систем.
Від імені всієї команди Cloudflare я хотів би вибачитися за незручності, які ми сьогодні завдали Інтернету.
Час (UTC) | Статус | Описs |
|---|
11:05 | Нормальний. | Розгорнуто зміну контролю доступу до бази даних. |
11:28 | Починається вплив. | Розгортання досягає середовищ клієнтів, перші помилки виявлені в HTTP-трафіку клієнтів. |
11:32–13:05 | Команда дослідила підвищений рівень трафіку та помилки служби Workers KV.
| Початковим симптомом, здавалося, було зниження швидкості реагування Workers KV, що впливало на інші сервіси Cloudflare.
Були зроблені спроби вжити таких заходів, як маніпулювання трафіком та обмеження облікових записів, щоб повернути сервіс Workers KV до нормального робочого рівня.
Перший автоматизований тест виявив проблему о 11:31, а ручне розслідування розпочалося о 11:32. Виклик про інцидент було створено о 11:35. |
13:05 | Впроваджено обхід доступу Workers KV та Cloudflare — вплив зменшено. | Під час розслідування ми використовували внутрішні системні обходи для Workers KV та Cloudflare Access, тому вони повернулися до попередньої версії нашого основного проксі-сервера. Хоча проблема була присутня й у попередніх версіях нашого проксі-сервера, її вплив був меншим, як описано нижче. |
13:37 | Робота була зосереджена на поверненні файлу конфігурації Bot Management до останньої відомої справної версії. | Ми були впевнені, що файл конфігурації Bot Management став причиною інциденту. Команди працювали над способами відновлення служби в кількох робочих потоках, причому найшвидшим робочим потоком було відновлення попередньої версії файлу. |
14:24 | Зупинено створення та поширення нових файлів конфігурації Bot Management. | Ми визначили, що модуль Bot Management був джерелом 500 помилок, і що це було спричинено неправильним файлом конфігурації. Ми зупинили автоматичне розгортання нових файлів конфігурації Bot Management. |
14:24 | Тестування нового файлу завершено. | Ми спостерігали успішне відновлення за допомогою старої версії файлу конфігурації, а потім зосередилися на пришвидшенні виправлення в усьому світі. |
14:30 | Основний вплив усунуто. Сервіси, що зазнали впливу нижче за течією, почали спостерігати зменшення кількості помилок. | Коректний файл конфігурації Bot Management було розгорнуто глобально, і більшість служб почали працювати коректно. |
17:06 | Всі послуги вирішено. Вплив закінчується. | Усі нижчі служби перезапущено, а всі операції повністю відновлено. |