July 28, 2026
Я поставила Cloudflare, щоб полагодити оплати. Через місяць він рятував мене від атак
Як випадкове рішення виявилось найкориснішим — і четверо граблів, на які я наступила по дорозі
By Lialia Sakhno
7 min read
Як випадкове рішення виявилось найкориснішим — і четверо граблів, на які я наступила по дорозі
Мене звати Ляля, я роблю Calorize — застосунок для підрахунку калорій з ШІ-асистенткою. Сама: код, дизайн, сервер, маркетинг. Публічно ділюся своїм соло-стартап-тріпом і все більше отримую питань, особливо стосовно забезпечення безпеки додатка. Якщо ви робите продукт сам-один і ваш сервер уперше став цікавий комусь чужому — це для вас.
Хто я? До цього десять років була бекенд-розробницею і навіть маю магістра кібербезпеки. Розгортати сервери вмію, про безпеку знаю, і цього завжди вистачало. Проблема в тому, що всі ці десять років я працювала переважно в B2B, а Calorize — B2C. І виявилося, що слово «безпека» в цих двох світах означає зовсім різні речі.
У B2B сервер доступний обмеженому колу: корпоративна мережа, білий список адрес, VPN. Трафік передбачуваний. Загрози тихі й цілеспрямовані — витік даних, дірки в правах доступу, вкрадені паролі. І поруч завжди є люди: девопси, адміни на боці клієнта.
У B2C сервер відкритий усьому інтернету цілодобово, трафік стрибає без попередження (вірусний рілз у графіках виглядає майже як атака), користувачі приходять із вбудованих браузерів і старих телефонів, до вас стукають чужі сервери, а хейтерам не потрібні ваші дані — вони просто хочуть, щоб ви лягли.
Далі — чесна послідовність подій: як я випадково опинилась на Cloudflare і чотири проблеми, які створила собі сама.
1. Як я взагалі опинилась на Cloudflare
Почалось із того, що платіжний провайдер (Моно) заблокував мій сервер. Одного дня всі оплати перестали проходити, у логах — відмова на кожен запит. Без попередження і пояснень.
Причина виявилась образливо дурною: я український підприємець, але сервер фізично стоїть у європейському датацентрі (так живе половина українських продуктів після 2022 року). Їхня антифрод-система побачила невідповідність і про всяк випадок заблокувала. У підтримці сказали: «протягом доби з вами зв'яжуться».
Ідея обходу очевидна: якщо заблокували конкретно адресу мого сервера — треба ходити до банку не з неї. Claude запропонував Worker. Я переключила DNS провайдера на Cloudflare.
Worker — це маленька програма, яка живе на серверах Cloudflare. Мій сервер звертається до неї, а вона йде до банку зі своєї адреси. Близько 50 рядків коду, дві години роботи — оплати ожили ще до того, як підтримка «зв'язалась протягом доби».
Захист мене тоді не цікавив узагалі. Cloudflare був водопровідною трубою в обхід затору, і нічим більше.
2. Що таке Cloudflare насправді
Через кілька тижнів почались атаки — і виявилось, що я вже сиджу на тому, що від них рятує.
Cloudflare стає посередником між користувачами і вашим сервером: люди приходять не до вас, а до нього, він забирає у вас сторінку і віддає далі. Зовні нічого не змінюється.
Що це дає: ваш сервер зникає з публічного доступу; перед вами з'являється фільтр, який відкидає сміття до того, як воно дійде до вашого коду; і замість однієї вашої машини удар приймають тисячі їхніх. Безкоштовного тарифу вистачає маленькому продукту з головою — я досі на ньому.
3. Крок, який легко пропустити
Підключення нудне: додаєте домен, замінюєте два записи там, де його купували.
А тепер те, що я мало не пропустила сама.
Підключення Cloudflare не ховає ваш сервер. По-перше, публічні бази роками зберігають історію, яка адреса стояла за яким доменом — ваша стара вже там. По-друге, і це головне: сервер продовжує відповідати всім, хто постукає напряму. Cloudflare нічого йому не забороняє, він просто стоїть збоку. Охорона на парадному вході, чорний хід відчинений.
Тому другий крок обов'язковий: закрити сервер для всіх, крім Cloudflare. Через файрвол: приймати запити тільки з їхніх адрес (список публікується відкрито), решту відкидати мовчки. Після цього спроба зайти на сервер напряму просто зависає.
Перевірити легко: відкрийте адресу свого сервера в браузері як звичайний сайт. Якщо відкривається — чорний хід відчинений.
4. Проблема перша: сайт лягає
Одного дня трафік на головну зріс у двадцять разів. У логах — тисячі запитів на одну сторінку з сотень адрес, User-Agent змінюється на кожному запиті, referer підроблений. Сервер відповідав користувачам помилками.
Технічно атака примітивна, але кожен такий запит змушує сервер піднімати код, лізти в базу, збирати сторінку. Десятки тисяч разів на хвилину — для того, хто ніколи не стане користувачем.
У Cloudflare є вбудований автоматичний захист від таких атак…
5. Проблема друга: захист зламав платежі
…Bot Fight Mode, «режим боротьби з ботами». Я увімкнула, атака припинилась, я пішла робити продукт далі.
Наступного дня в підтримку написала користувачка: оплатила підписку, гроші зняли, преміум не з'явився. Я пішла ковирятися і виявилося, що вже добу підписки не нараховуються після оплати.
Чому так сталось
Коли користувач платить, ваш застосунок не дізнається про це сам. Платіжна система стукає до вас на сервер і каже: транзакція успішна, видай доступ. Це називається webhook.
Ключове слово — сервер. Платіжна система шле виклик не з телефона користувача, а зі своєї інфраструктури: Apple зі своїх серверів, Google зі своїх, банк зі своїх.
А захист від ботів дивиться на адресу і питає: жива людина з браузером чи машина? Адреса з датацентру — очевидно машина. Значить бот, значить блокуємо.
Захист від ботів за визначенням блокує все, що не є людиною за браузером. А платіжний webhook — це і є не-людина.
Я не «випадково зачепила» оплати. Я увімкнула штуку, яка зобов'язана була їх зламати. Це не баг Cloudflare і не помилка в налаштуваннях — це прямий наслідок того, що я не подумала, хто ще, крім ботів, стукає до мене з датацентру.
Чому я не помічала проблему добу
Платіжна система отримувала відмову від Cloudflare, і запит не доходив до мого застосунку взагалі. Отже: у логах порожньо, бо не було запиту; жодного винятку; моніторинг мовчить, бо нічого не впало; користувач бачить успішну оплату на боці банку і йде користуватись.
Збій, який проявляється відсутністю події, невидимий.
Порахуйте, скільки у вас процесів працює тільки тому, що хтось ззовні до вас стукає: прийом оплат, продовження підписок, повернення коштів, сповіщення від інтеграцій.
Як я це полагодила
Хороша платіжна система дозволяє запитати виписку — усі транзакції за період. Це джерело правди, яке не залежить від того, дійшли до мене сповіщення чи ні.
Я написала команду відновлення: вона тягне список транзакцій, прогонить кожну через той самий код, що обробляє живі webhook-и, і показує, що застосувала, а що пропустила як дублікат. Пропущені підписки були успішно нараховані.
Ключова властивість — ідемпотентність: скільки разів не запусти, результат однаковий.
Команда тепер ходить за розкладом. Якщо ви приймаєте платежі і такої команди у вас немає — це найкорисніше, що можна зробити після прочитання статті. Вона рятує не лише від збоїв захисту: мережа моргнула, ви деплоїли, у провайдера аварія — webhook губиться десятками способів.
Точний інструмент замість грубого
Bot Fight Mode я вимкнула назавжди. На безкоштовному тарифі це перемикач «все або нічого»: його не можна звузити й не можна зробити з нього винятки. Він або душить підряд усе, що не схоже на людину з браузером — разом із платіжними системами, — або не працює.
Точний інструмент лежить в іншому місці. У Cloudflare є розділ, де ви пишете власні правила: умова + дія. Вони виконуються списком згори вниз, і перше, що збіглося, вирішує долю запиту.
Першим у моєму списку тепер стоїть правило-страховка: для адрес, куди приходять платіжні webhook-и, не застосовувати жодних перевірок.
Стоїть воно першим саме тому, що список читається згори вниз: правило, яке опинилось нижче за блокування, просто не встигне спрацювати. І це страховка на майбутнє — що б я не додала до захисту потім, у паніці чи ні, оплати вже виведені з-під удару.
А боятись, що виняток відкриє діру, не варто: платіжні webhook-и підписані криптографічно, підробити їх не можна, а невалідний ваш застосунок і так відкине. Захист там дає мало, а ламає багато.
6. Проблема третя: захист зламав переходи із соцмереж
Коли Cloudflare показує перевірку «ви людина?», результат він відправляє назад службовим запитом особливого типу. У звичайному браузері цього ніхто не помічає — Cloudflare сам його перехоплює.
А у вбудованих браузерах (тих, що відкриваються всередині Instagram, TikTok, Telegram) механізм іноді збоїть: службовий запит долітає до мого сервера, а сторінка вміє відповідати тільки на звичайний перехід. Користувач проходить перевірку і замість сторінки бачить помилку. Кожен такий випадок — людина, яка прийшла з мого ж рілза і впіймала стіну.
Полагодила обробником на боці застосунку: якщо прилетів такий запит на сторінку, яка його не очікує — не показувати помилку, а м'яко перенаправити на неї ж, як звичайний перехід.
Мораль: якщо аудиторія приходить із соцмереж — тестуйте саме у вбудованих браузерах. Те, що бездоганно працює у вашому Chrome, там може розсипатись. І це стосується не лише захисту.
7. Проблема четверта: я дізнавалась останньою
Я весь час намагалась побудувати кращий захист, а проблема була не в захисті. Атака тривала майже добу — я дізналась, бо випадково глянула в логи. Оплати були зламані добу — я дізналась від користувачів. У обох випадках я дізнавалась останньою.
Тому найкорисніше, що я зробила — не правило і не налаштування, а сповіщення в Telegram. Розкажу детально, бо це варто зробити, навіть якщо ви більше нічого з цієї статті не зробите.
Моніторинг. Я користуюсь Netdata: безкоштовний, ставиться однією командою і одразу починає збирати все підряд без налаштувань.
Бот. Дві хвилини без програмування. У Telegram знаходите @BotFather, пишете /newbot — він дає токен (це пароль бота, його нікому не показують). Далі пишете @userinfobot, він дає ідентифікатор вашого чату. І напишіть щось своєму боту — без цього він не має права писати вам першим.
Зв'язати. У Netdata є файл налаштувань сповіщень: увімкнути Telegram, вписати токен і номер чату.
Правила. У мене їх два, і цього вистачає. Перше — різкий стрибок помилок: однозначний сигнал, що прямо зараз користувачі бачать поламаний сайт. Друге — різкий стрибок кількості запитів: раннє попередження, бо під час атаки потік росте першим, а помилки з'являються за хвилину-дві, коли сервер уже не встигає.
Пороги. Не беріть цифри зі стелі: подивіться реальні показники за добу спокійної роботи і порівняйте з тим, що було під час атаки. У мене різниця виявилась у сотні разів — тож межу можна ставити з величезним запасом, щоб вірусний рілз ніколи не підняв тривогу, а атака підняла одразу. Головна помилка — надмірна чутливість: якщо сповіщення прилітають щодня без причини, за тиждень ви навчитесь їх ігнорувати.
Перевірка. Крок, який усі пропускають. Я тимчасово занизила поріг до сміховинного значення, дочекалась сповіщення на телефоні, повернула назад. Неперевірений алерт — це не алерт, а надія. І приходити воно має туди, куди ви реально дивитесь, — не на пошту, яку відкриваєте раз на день.
Через кілька днів прилетіла нова атака. Сповіщення прийшло за хвилини, я відкрила графіки ще до того, як хтось із користувачів щось помітив. Різниця між «доба простою» і «п'ять хвилин» — це не захист, це моніторинг.
8. Happy End
Коли прилетіла та нова атака, я приготувалась тиснути аварійні кнопки. Але не встигла. Вбудований автоматичний захист Cloudflare і звичайне обмеження частоти запитів її зупинило. Обидва безкоштовні, обидва спрацювали самі. Атака протривала близько двох хвилин і згасла без мого втручання.
Порядок дій, якби я починала спочатку
- Підключити Cloudflare.
- Закрити сервер файрволом для всіх, крім Cloudflare. Без цього кроку перший майже безглуздий.
- Більше нічого поки не вмикати — вбудований автоматичний захист уже працює і дрібні атаки з'їдає сам.
- Поставити моніторинг і сповіщення в месенджер — раніше, ніж будь-який додатковий захист.
- Перевірити сповіщення штучно. Один раз, але обов'язково.
- Якщо приймаєте платежі — зробити виняток для webhook-адрес і поставити першим у списку правил. До того, як увімкнете хоч якийсь захист, а не після.
- Написати ідемпотентну команду відновлення платежів.
- Додаткові захисти вмикати по одному, коли є конкретна причина — і щоразу питати: хто ще, крім поганих, під це потрапить?
Calorize — застосунок для підрахунку калорій з ШІ-асистенткою. Роблю його сама і розповідаю про процес, як є.