Cloudflare – Блог страуса https://ostrich.kyiv.ua Sun, 26 Oct 2025 09:16:50 +0000 uk hourly 1 https://wordpress.org/?v=6.8.3 https://ostrich.kyiv.ua/wp-content/uploads/2024/02/ostrich-150x150.png Cloudflare – Блог страуса https://ostrich.kyiv.ua 32 32 Створення Fallback-сторінки за допомогою Cloudflare Workers https://ostrich.kyiv.ua/uk/2025/10/26/%d1%81%d1%82%d0%b2%d0%be%d1%80%d0%b5%d0%bd%d0%bd%d1%8f-fallback-%d1%81%d1%82%d0%be%d1%80%d1%96%d0%bd%d0%ba%d0%b8-%d0%b7%d0%b0-%d0%b4%d0%be%d0%bf%d0%be%d0%bc%d0%be%d0%b3%d0%be%d1%8e-cloudflare-workers/ https://ostrich.kyiv.ua/uk/2025/10/26/%d1%81%d1%82%d0%b2%d0%be%d1%80%d0%b5%d0%bd%d0%bd%d1%8f-fallback-%d1%81%d1%82%d0%be%d1%80%d1%96%d0%bd%d0%ba%d0%b8-%d0%b7%d0%b0-%d0%b4%d0%be%d0%bf%d0%be%d0%bc%d0%be%d0%b3%d0%be%d1%8e-cloudflare-workers/#respond Sun, 26 Oct 2025 09:16:47 +0000 https://ostrich.kyiv.ua/?p=1791

Коли мій сайт на Raspberry Pi вимикався під час блекаутів, Cloudflare показував сторінку 522 – Connection timed out. Я вирішив зробити fallback-сторінку власного дизайну, не витрачаючи ні копійки. У цій статті я детально опишу, як налаштувати безкоштовний Cloudflare Worker.

Що таке Cloudflare Workers

Cloudflare Workers – це безсерверне середовище, у якому можна запускати власний JavaScript-код безпосередньо на edge-серверах Cloudflare. Воно працює як «між прошарок» між користувачем і вашим сайтом, дозволяючи змінювати або замінювати відповіді на запити.

Хоча Cloudflare Workers – дуже зручне та безкоштовне рішення, подібного ефекту можна досягти й іншими способами.
Ось кілька популярних варіантів:

  • Netlify Edge Functions
  • Vercel Edge Functions
  • AWS CloudFront Functions
  • Google Cloud Functions
  • GitHub Pages + JS Redirection

Оскільки DNS мого сайту вже керується Cloudflare, мені здалося логічним залишатися в одній екосистемі. Отже Cloudflare Workers є ідеальним вибором для невеликих домашніх або персональних проєктів, особливо коли потрібно швидко й безкоштовно забезпечити персональну сторінку помилки під час недоступності сервера.

Як працює Cloudflare Workers

Щоб краще зрозуміти, як саме відбувається взаємодія між користувачем, воркером та веб сервером, я візуалізував цей процес в таку просту блок схему

Тобто варто уявити Cloudflare Worker як посередника між користувачем і сервером на Raspberry Pi. Кожен запит до сайту спочатку проходить через мережу Cloudflare, де Worker перевіряє, чи доступний основний сервер. Якщо все працює, запит просто передається далі, ніби нічого й не відбувалося. Але якщо з’єднання з Raspberry Pi розірвано або сервер не відповідає вчасно, Worker миттєво підхоплює управління і показує власну fallback-сторінку.

Створення Worker

Створення Cloudflare Workers це комплекс дій, а саме:

  • Створення шаблонного воркера в 1 клік
  • Зміна кода воркера
  • Підключення до домену

Зараз я опишу кожен пункт більш детально, адже є певні особливості.

Створення шаблонного воркера в 1 клік

  • Увійдіть у Cloudflare Dashboard
  • В лівому меню виберіть Compute & AI → Workers & Pages
  • Оберіть шаблон Hello World!Get started.

Таким чином буде створено шаблон “Hello World” script. Я звернув увагу, що область тексту не активна – сіра, і цей тест не можна редагувати. Єдине що я змінив – це назву цього скрипта на blackout, адже на наступному кроці ми цей скрипт будемо редагувати! Тому в цьому випадку необхідно просто погодитися на створення цього воркера.

Цей скрипт відобразиться в списку воркерів

Зміна кода воркера

На наступному кроці необхідно відредагувати щойно створений скрипт, для цього клацаємо на ньому та переходимо на основну сторінку цього воркера, де клацаємо на кнопку “Edit code“.

Відкриється редактор коду, але із можливістю редагування. Оскільки я не знаю JavaScript я звернувся за допомогою до ChatGPT, щоб він мені написав скрипт. Я замінив код скрипту Hello World на свій.

Розгорніть щоб побачити код:

worker-fallback.js
addEventListener('fetch', event => {
  event.respondWith(handleRequest(event.request))
})

const ORIGIN_HOST = 'https://ostrich.kyiv.ua' 
const ORIGIN_TIMEOUT_MS = 10000

const FALLBACK_HTML = `
<!doctype html>
<html lang="en">
<head>
  <meta charset="utf-8"/>
  <meta name="viewport" content="width=device-width, initial-scale=1"/>
  <title>Site temporarily unavailable — Сайт тимчасово недоступний</title>
  <style>
    body {
      font-family: system-ui, -apple-system, "Segoe UI", Roboto, sans-serif;
      margin: 0;
      display: flex;
      align-items: center;
      justify-content: center;
      height: 100vh;
      background: #f8f9fb;
      color: #111;
      text-align: center;
    }
    .card {
      max-width: 680px;
      background: white;
      border-radius: 16px;
      padding: 30px;
      box-shadow: 0 6px 25px rgba(0,0,0,.08);
    }
    h1 { font-size: 1.5rem; margin-bottom: .5rem; }
    p { margin: .6rem 0; line-height: 1.5; }
    .divider {
      border-top: 1px solid #ddd;
      margin: 1.4rem 0;
    }
    .time {
      font-size: 0.9rem;
      color: #666;
      margin-top: 10px;
    }
  </style>
</head>
<body>
  <div class="card">
    <h1>Site temporarily unavailable</h1>
    <p>Hello! If you are reading this message, please know that due to ongoing massive russian attacks on Ukraine's energy sector, my server is currently without power. I hope electricity will be restored soon, so please visit this page again later. <br>Support Ukraine! 💙💛</p>

    <div class="divider"></div>

    <h1>Сайт тимчасово недоступний</h1>
    <p>Привіт! Якщо ти читаєш це повідомлення, знай, що через постійні масовані атаки росії на енергетичну інфраструктуру України мій сервер зараз без електрики. Я сподіваюся, що найближчим часом живлення буде відновлено, тому запрошую відвідати цю сторінку пізніше. І найголовніше — підтримуй Україну! 💙💛</p>

    <p class="time">Last checked: <span id="ts"></span></p>
  </div>

  <script>
    document.getElementById('ts').textContent = new Date().toLocaleString('uk-UA');
  </script>
</body>
</html>
`

async function handleRequest(request) {
  // будуємо URL до origin (зберігаємо шлях і query)
  const url = new URL(request.url)
  const originUrl = ORIGIN_HOST.replace(/\/$/, '') + url.pathname + (url.search || '')

  // Обгортка для тайм-ауту
  const controller = new AbortController()
  const id = setTimeout(() => controller.abort(), ORIGIN_TIMEOUT_MS)

  try {
    // Пересилаємо отримані headers та method, телом при потребі
    const resp = await fetch(originUrl, {
      method: request.method,
      headers: request.headers,
      body: request.method === 'GET' || request.method === 'HEAD' ? null : request.body,
      redirect: 'manual',
      signal: controller.signal
    })
    clearTimeout(id)

    // Якщо origin повернув помилку 5xx або 4xx - можна показати fallback або все ж віддати origin
    if (resp.status >= 500 || resp.status === 524 || resp.status === 520) {
      // замість помилки origin повертаємо fallback
      return new Response(FALLBACK_HTML, {
        status: 200,
        headers: { 'Content-Type': 'text/html; charset=utf-8' }
      })
    }

    // В іншому випадку проксируємо відповідь від origin (включаючи заголовки)
    const responseHeaders = new Headers(resp.headers)
    // Можна додати cache control для статичних ресурсів, якщо потрібно
    return new Response(resp.body, {
      status: resp.status,
      statusText: resp.statusText,
      headers: responseHeaders
    })
  } catch (err) {
    // тайм-аут або помилка мережі -> показати fallback
    clearTimeout(id)
    return new Response(FALLBACK_HTML, {
      status: 200,
      headers: { 'Content-Type': 'text/html; charset=utf-8' }
    })
  }
}

Для оновлення коду необхідно натиснути на кнопку “Deploy”. В такому випадку дані автоматично збережуться і оновляться на Edge сервері.

Підключення до домену

На головній сторінці створеного воркера, переходимо в розділ “Domains & Routes”, щоб усі запити до сайту проходитили через Worker.

У вікні налаштувань Domains & Routes клацаємо на кнопку +Add, і у вікні що відкрилося праворуч вибираємо Route – адже нам треба побудувати маршрут від воркера до сайта. Вводимо наступні налаштування в цьому вікні:

  • Zone – із списка вибираємо сайт, в моєму випадку ostrich.kyiv.ua
  • Route – прописуємо ostrich.kyiv.ua/*
  • Failure mode – вибираємо Fail open (proceed), щоб наш сайт продовжував працювати не дивлячись на те, чи працює сам воркер чи ні, щоб ми від нього не очікували ніякої помилки.

Клацаємо Add route або Update route – якщо таке було створено раніше. Новий маршрут відобразиться в табличці маршрутів.

На цьому етапі налаштування та конфігурації завершилися. Залишилося перевірити результат роботи!

Перевірка роботи Cloudflare Workers

Тепер, коли мій Raspberry Pi вимикається, користувачі бачать чисту, охайну сторінку з поясненням, а не типовий Cloudflare 522.
І все це – безкоштовно, без додаткових серверів чи плагінів.

Висновки

Cloudflare Workers стали для мене простим і водночас потужним рішенням, яке дозволяє залишатися на зв’язку навіть тоді, коли мій сервер на Raspberry Pi тимчасово недоступний через блекаут. Усе, що потрібно – трохи коду та власна ідея, як зробити досвід користувача кращим. Я залишився в екосистемі Cloudflare, бо DNS уже тут, а робота з Workers інтегрується природно, без зайвих витрат і складних налаштувань. Це рішення довело, що навіть у часи енергетичної нестабільності, через росіян, можна підтримувати присутність свого сайту в мережі – просто, надійно і безкоштовно.

]]>
https://ostrich.kyiv.ua/uk/2025/10/26/%d1%81%d1%82%d0%b2%d0%be%d1%80%d0%b5%d0%bd%d0%bd%d1%8f-fallback-%d1%81%d1%82%d0%be%d1%80%d1%96%d0%bd%d0%ba%d0%b8-%d0%b7%d0%b0-%d0%b4%d0%be%d0%bf%d0%be%d0%bc%d0%be%d0%b3%d0%be%d1%8e-cloudflare-workers/feed/ 0
DNSSEC: як працює захист доменних імен https://ostrich.kyiv.ua/uk/2025/09/25/dnssec-%d1%8f%d0%ba-%d0%bf%d1%80%d0%b0%d1%86%d1%8e%d1%94-%d0%b7%d0%b0%d1%85%d0%b8%d1%81%d1%82-%d0%b4%d0%be%d0%bc%d0%b5%d0%bd%d0%bd%d0%b8%d1%85-%d1%96%d0%bc%d0%b5%d0%bd/ https://ostrich.kyiv.ua/uk/2025/09/25/dnssec-%d1%8f%d0%ba-%d0%bf%d1%80%d0%b0%d1%86%d1%8e%d1%94-%d0%b7%d0%b0%d1%85%d0%b8%d1%81%d1%82-%d0%b4%d0%be%d0%bc%d0%b5%d0%bd%d0%bd%d0%b8%d1%85-%d1%96%d0%bc%d0%b5%d0%bd/#respond Thu, 25 Sep 2025 09:33:40 +0000 https://ostrich.kyiv.ua/?p=1713

Класична система доменних імен (DNS) – одна з головних складових роботи Інтернету. Проте у базовому варіанті DNS не має механізму перевірки достовірності даних. Щоб вирішити цю проблему, було розроблено DNSSEC (Domain Name System Security Extensions) – набір розширень до DNS, які додають до системи перевірку цілісності та автентичності даних.

Що таке DNSSEC

DNSSEC — це набір криптографічних розширень для DNS, які дозволяють:

  • Перевіряти достовірність записів (автентичність джерела);
  • Захищати від підробки та підміни відповідей (integrity protection);
  • Будувати довірений ланцюжок від кореня DNS до конкретного домену.

Принцип роботи ґрунтується на цифрових підписах. Кожен DNS-запис підписується приватним ключем. Клієнт (резольвер) отримує не лише значення, а й криптографічний підпис, який можна перевірити за допомогою відкритого ключа, збереженого у батьківській зоні.

Як працює DNSSEC

Візуально дуже спрощено на моєму реальному домені ostrich.kyiv.ua можна побудувати таку графічну схему:

  • Створення ключів. Для домену генерується пара ключів:
    • KSK (Key Signing Key) — підписує ключі;
    • ZSK (Zone Signing Key) — підписує записи у зоні.
  • Підпис зон. Усі записи (A, MX, TXT тощо) підписуються за допомогою ZSK.
  • Передача відкритого ключа. Хеш відкритого ключа (DS-запис) публікується у батьківській зоні (наприклад, у .ua для домену .com.ua).
  • Ланцюг довіри. Коли резольвер отримує відповідь, він перевіряє підпис, а потім перевіряє, чи ключ довірений через ланцюг від кореня DNS.

У результаті користувач може бути впевнений, що отримані DNS-дані — справжні і не були підмінені.

Приклад застосування

Припустимо, користувач заходить на мій сайт. Без DNSSEC хакер може підмінити DNS-відповідь і переспрямувати його на фішинговий сайт. З DNSSEC браузер (через резольвер) отримає лише підписані записи, і якщо підпис не збігається – відповідь буде відхилена. Таким чином, користувач потрапить лише на справжній сервер банку.

Налаштування DNSSEC

Реєстратор мого доменого імені – це локальний провайдер, який нещодавно додав до переліку своїх послуг DNSSEC. Я вирішив скористатися такою можливістю і внести налаштування. Оскільки реєстратором виступає не Cloudflare, а мій локальний провайдер, то необхідно внести налаштування саме на стороні мого провайдера, проте самі дані я буду отримувати від Cloudflare адже наразі на цьому сервері прописані мої DNS записи.

Активувати функцію доволі просто. В панелі Cloudflare необхідно вибрати DNSSettingsDNSSECEnable

У вікні буде згенерована вся необхідна інформація для подальшоїх активації в панелі керування свого реєстратора домену, про що свідчить попередження: “To enable DNSSEC you will need to add this DS record to your registrar. Most registrars will ask for only a few of the fields below. We have instructions for common registrars”.

Мій реєстратор вимагає заповнити лише 4 поля:

  • Key tag
  • Algorithm
  • Digest type
  • Digest

Буквально через декілька хвилин, статус DNSSEC зміниться на “Success! ostrich.kyiv.ua is protected with DNSSEC.

Перевірка

Щоб перевірити чи дійсно зміни застосувалися, достатньо в терміналі виконати наступну команду, яка напряму звернеться до Cloudflare.

dig +dnssec ostrich.kyiv.ua @1.1.1.1

Очікується отримати до звичайного виводу додатковий рядок із записом RRSIG:

ostrich.kyiv.ua.        300     IN      RRSIG   A 13 3 300 20250926095050 20250924075050 34505 ostrich.kyiv.ua. IQE6axVd6YMeHnyXC2zW9ELt9P+6ZNzuhPbWQ4BqRnAtAGkQtIA7ETiE k/079aSTNqHk+fnnKidHU3Jp5pdORQ==

Цей запис складається з наступних параметрів:

  • A – Це означає, що підпис стосується записів типу A (IPv4).
  • 13 – Алгоритм підпису. 13 = ECDSA Curve P-256 with SHA-256 (сучасний алгоритм, Cloudflare його використовує за замовчуванням).
  • 3 – Кількість міток у доменному імені (для ostrich.kyiv.ua → 3: ostrich, kyiv, ua).
  • 300 – ТТL у секундах, з яким був підписаний запис (тобто максимальний час кешування цього підпису).
  • 20250926095050 – Час закінчення дії підпису (UTC, формат YYYYMMDDHHMMSS). Тут → 26 вересня 2025, 09:50:50 UTC.
  • 20250924075050 – Час початку дії підпису (UTC). Тут → 24 вересня 2025, 07:50:50 UTC. (Отже, підпис дійсний лише в цьому проміжку.)
  • 34505 – Ідентифікатор ключа DNSKEY, яким зроблено підпис. Резольвер шукає DNSKEY із таким тегом, щоб перевірити підпис.
  • ostrich.kyiv.ua. – Домен, якому належить ключ, яким підписано запис.
  • IQE6axVd6YM… – Власне криптографічний підпис (base64). Використовується разом із DNSKEY для перевірки достовірності.

Таким чином вже через декілька хвилин після засосування змін можна отримати додатковий захист свого DNS.

Також є ресурс dnssec-analyzer, який візуально покаже чи все добре із валідацією домена.

Висновок

DNSSEC – це важливий крок до підвищення безпеки Інтернету. Він не замінює HTTPS чи VPN, але робить DNS-назви більш надійними.
Для власників сайтів налаштування DNSSEC – це демонстрація турботи про безпеку відвідувачів і готовність до майбутніх стандартів (як-от DANE).
Якщо твій DNS-провайдер підтримує DNSSEC (наприклад, Cloudflare), рекомендується обов’язково його увімкнути.

]]>
https://ostrich.kyiv.ua/uk/2025/09/25/dnssec-%d1%8f%d0%ba-%d0%bf%d1%80%d0%b0%d1%86%d1%8e%d1%94-%d0%b7%d0%b0%d1%85%d0%b8%d1%81%d1%82-%d0%b4%d0%be%d0%bc%d0%b5%d0%bd%d0%bd%d0%b8%d1%85-%d1%96%d0%bc%d0%b5%d0%bd/feed/ 0
Cloudflare: реальний досвід відбиття DDoS атаки з росії https://ostrich.kyiv.ua/uk/2025/05/25/cloudflare-%d1%80%d0%b5%d0%b0%d0%bb%d1%8c%d0%bd%d0%b8%d0%b9-%d0%b4%d0%be%d1%81%d0%b2%d1%96%d0%b4-%d0%b2%d1%96%d0%b4%d0%b1%d0%b8%d1%82%d1%82%d1%8f-ddos-%d0%b0%d1%82%d0%b0%d0%ba%d0%b8-%d0%b7-%d1%80/ https://ostrich.kyiv.ua/uk/2025/05/25/cloudflare-%d1%80%d0%b5%d0%b0%d0%bb%d1%8c%d0%bd%d0%b8%d0%b9-%d0%b4%d0%be%d1%81%d0%b2%d1%96%d0%b4-%d0%b2%d1%96%d0%b4%d0%b1%d0%b8%d1%82%d1%82%d1%8f-ddos-%d0%b0%d1%82%d0%b0%d0%ba%d0%b8-%d0%b7-%d1%80/#respond Sun, 25 May 2025 13:26:52 +0000 https://ostrich.kyiv.ua/?p=1220 Вступ

Коли я купив домен і прийняв рішення на своїй Raspberry Pi розгорнути публічний сайт (цей блог, який ви зараз читаєте) я знав, що DDoS-атака відбудеться, обов’язково, але це було питання часу. Цей час настав. В цьому дописі я поділюся своїм досвідом, як я відбив DDoS-атаку за допомогою Cloudflare на безкоштовному тарифі. Я тут надам графіки та результати роботи по факту завершення атаки, проте вони будуть доволі інформативними для візуального сприйняття.

Превентивні заходи

Я продовжую вивчати сучасні мережеві можливості, нові технології, розбираюся в налаштуваннях та сервісах. На моєму сервері наразі встановлено декілька веб сервісів, але з точки зору безпеки, я для них обмежив доступ із інтернету, залишивши лише локальну мережу. Такі заходи не можуть стосуватися публічного веб ресурсу – цього блогу. Після написання десь 5ї статті я подумав про захист від DDoS-атак, і перше що прийшло на думку це був сервіс Cloudflare.

Cloudflare – це потужна платформа для забезпечення безпеки, оптимізації швидкодії та підвищення стабільності веб ресурсів. Завдяки глобальній мережі дата-центрів Cloudflare діє як проміжна ланка між сайтом і відвідувачем: кешує контент, блокує небажаний трафік і надає аналітику.

На початковому рівні я вибрав безкоштовний тарифний план, який має певні обмеженні на відміну від комерційного, проте цього цілком достатньо для базових потреб захисту сайту. Щоб почати користуватися Cloudflare необхідно виконати декілька простих кроків:

  • Зареєструватися на Cloudflare
  • В адмін панелі реєстратора домена необхідно прописати DNS записи серверів Cloudflare
  • В адмін панелі Cloudflare додати DNS записи свого фізичного сервера

Після внесення змін почнеться переіндексація DNS записів яка може тривати до 72 годин, проте в моєму випадку це сталося менше ніж за добу. Після цього я видихнув і почав вже користуватися сайтом повноцінно покладаючись на Cloudflare.

Визначення DDoS атаки

Для моніторингу ресурсів своєї локальної мережі я використовую Zabbix. Зазвичай я відслідковую активність поштового серверу, температури Raspberry Pi та інші метрики. Візуально на дашборді розмістив декілька віджетів, щоб наглядно і швидко можна було визначати аномалії в роботі сервісів.

Зазвичай температура становить приблизно 60 – 65°C, проте я звернув увагу на завищену температуру на майже 10 градусів, до 70 – 75°C. В цей час я перевів погляд на навантаження ЦП, і він був на рівні 50%, я відразу зрозумів що щось коїться не те.

Я передивився метрики сервера і майже всі значення графіків свідчили про позаштатну ситуацію

Візуальні графіки показують лише загальну картину. Тепер моя мета була визначити корінь зла. Для цього я підключився до сервера, та почав переглядати стан процесів та роботи сервісів. На жаль під час діагностики я не зробив скріншотів проте скопіював текст з консолі. По історії команд спробую відтворити хід подій.

Ресурс CPU

Першою командою я визначив перші 15 процесів із високим споживанням ресурсу CPU.

ps -eo pid,ppid,cmd,%mem,%cpu --sort=-%cpu | head -n 15

Я отримав таку видачу:

ps -eo pid,ppid,cmd,%mem,%cpu --sort=-%cpu | head -n 15
    PID    PPID CMD                         %MEM %CPU
2366770 1943100 /usr/sbin/apache2 -k start   1.1 12.4
2373538 1943100 /usr/sbin/apache2 -k start   1.2 12.2
2374705 1943100 /usr/sbin/apache2 -k start   1.2 11.8
2374940 1943100 /usr/sbin/apache2 -k start   1.2 11.3
2376091 1943100 /usr/sbin/apache2 -k start   1.0 11.1
2370641 1943100 /usr/sbin/apache2 -k start   1.2 10.4
2355557 1943100 /usr/sbin/apache2 -k start   1.2 10.4
    709       1 /opt/networkoptix/mediaserv  5.7  9.6
2375784 1943100 /usr/sbin/apache2 -k start   1.0  9.3
2373539 1943100 /usr/sbin/apache2 -k start   1.2  7.8
2375416 1943100 /usr/sbin/apache2 -k start   1.2  7.1
2376564 1943100 /usr/sbin/apache2 -k start   0.8  6.9
2372672 1943100 /usr/sbin/apache2 -k start   1.2  6.9

Звісно значення були по 10-20% CPU на процес, що в сумі давало доволі велику сумарну навантаженість.

Джерело трафіку

Другою командою треба було визначити, які IP генерують багато трафіку. Цією командою виводиться перші 10 IP адрес по кількості запитів.

awk '{print $1}' /var/log/apache2/access.log | sort | uniq -c | sort -nr | head -n 10

Я отримав таку видачу:

 118852 127.0.0.1
   7169 162.158.239.23
   7168 162.158.238.232
   6304 162.158.238.233
   5810 162.158.239.24
   5068 162.158.238.106
   4848 162.158.238.107
   3871 162.158.238.120
   3843 162.158.238.121
   2875 104.23.217.65

Ця інформація відображає локальні запити (127.0.0.1) – понад 118 тис. звернень, тобто хтось із самого сервера активно запитує сайт. Пул IP-адрес 162.158.x.x і 104.23.x.x – належить Cloudflare, як проксі, отже, реальний трафік прихований за Cloudflare і певні правила мого роутера не працюють.

В мене додатково на роутері вже налаштована гео-фільтрація трафіку, яка виключає будь який трафік з росії та білорусі.

Причетність віртуального хоста

Наступним етапом можна визначити який саме сайт або віртуальний хост грузить сервер. Для цього проаналізуємо перші 100 рядків логу, проте для покращеної статистики можна це число збільшити. Оскільки я цю атаку визначив на ранній стадії, то 100 рядків достатньо.

sudo tail -n 100 /var/log/apache2/access.log | awk '{print $7}' | sort | uniq -c | sort -nr | head -20

Я отримав таку видачу:

29 /wp-login.php
22 /wp-admin/images/
7 /zabbix/zabbix.php?action=widget.item.view
4 /zabbix/zabbix.php?action=widget.svggraph.view
1 /wp-cron.php?doing_wp_cron=1748089832.8370869159698486328125
...

Можна знехтувати зверненнями до zabbix, адже основні запити йдуть на WordPress. Якщо підсумувати, то результат діагностики наступний:

  • apache2 – споживає більш за всізх ресурсу процесора
  • локальне IP та IP Cloudflare – має найбільшу кількість запитів
  • запити до сторінок WordPress

На першому етапі цих діагностичних даних виявилося достатньо для визначення подальших дій.

Безпекові дії на Cloudflare

Я не очікував, що Cloudflare настільки потужний інструмент, навіть в безкоштовній версії. За замовчанням багато функцій вимкнуто, і при певних атаках їх треба активувати вручну, а по завершенні атаки рекомендується деактивувати ці налаштування. Основним режимом є I’m under attack mode.

I’m under attack mode

I’m Under Attack Mode – це спеціальна функція Cloudflare, призначена для захисту веб сайтів від DDoS-атак, зокрема на рівні HTTP-флуду (наприклад, атаки через масове надсилання GET/POST-запитів). Основний принцип дії цього режиму наступний:

  • Перед кожним візитом до сайту відображається проміжна сторінка перевірки, яка триває кілька секунд.
  • Cloudflare виконує JavaScript-челендж — тобто змушує браузер «довести», що він не є ботом.
  • Якщо перевірка проходить успішно — користувач потрапляє на сайт.
  • Боти та прості скрипти, які не можуть виконати JS — автоматично відсіюються.

Цей режим можна включити в розділі Security -> Settings, там є перемикач I’m under attack mode, його треба активувати, і робота відбиття атаки почнеться негайно.

В новому інтерфейсі, цей пункт перенесли на вкладку All settings в самий низ, і назвали Security Level. При натисканні на Edit можна включити або виключити режим I’m under attack mode.

Після активації цього режиму на дашборді з’явиться повідомлення:

Under Attack Mode is active
Under Attack mode is used when a website is under a DDoS attack. All visitors will be shown an interstitial page for a short duration.

В такому режимі відбувається невеличка затримка із перевіркою, яка має такий вигляд:

В розділі Security -> Events можна побачити записи про ініціатора запитів, відображається доволі вичерпана та впорядкована інформація. В новому інтерфейсі розділ Events перенесено в меню Analytics та створено закладку Events де інформація так само структурована.

Custom та IP access rules

Враховуючи, що DDoS атака відбулася з однієї IP адреси, то можна для неї застосувати правила.

  • IP access rules – для блокування IP адрес поодиноко чи використовуючи маску підмережі
  • Custom rules – більш гнучке налаштування правил

Спочатку я вирішив створити правило яке б блокувало атакуючий сервер по IP адресі, для цього в новому інтерфейсі треба перейти в розділ Security -> Security rules -> IP access rules та натиснути на кнопку +Create. Для створення правила достатньо заповнити лише 4 поля:

  • IP, IP range, country name, or ASN – 194.67.196.50
  • Action – Block
  • Zone – This website
  • Notes – Fucking russian hacker

З самого початку я хотів заблокувати взагалі всю росію по геолокації, але в безкоштовному тарифному плані, на рівні IP access rules так реалізув не можна, після застосування цього правила я бачу помилку: Sorry, block by country is only available on the Enterprise plan.

Виявляється, в безкоштовній версії існує фільтр по геолокації, проте його можна налаштувати в розділі Custom rules.

  • Rule name (required) – Block_country_404
  • Field – Country
  • Operator – equals
  • Value – Russian Federation
  • Then take action – Block
  • Place at – First

Таким чином правило буде виглядати так

Звіти

В розділі Security -> Overview можна побачити графік співвідношення – обмеженого, обробленого Cloudflare та оброблено сервером трафіка, до загальної кількості запитів. При активній роботі Cloudflare, значення обмеження трафіку (Mitigated) буде збільшуватися, також буде збільшуватись кількість кешованих запитів, адже Cloudflare в такому режимі працює без прямого трафіку і має ряд обмежень, для запобігання хакерських дій, по типу підбору пароля брутфорсом.

На дашборді – Overview відображено багато корисних графіків. Я зробив кілька скріншотів, на початку атаки та під її завершення. Графік відображає останні 24 години активності, тому я наклав ці два графіки, щоб показати вам загальну картину активності. Червоним прямокутником я позначив діапазон роботи сервісу Cloudflare від початку до кінця.

Графіки доволі інформативні, а налаштування Cloudflare не викликає труднощів. Згідно із графіком атака тривала 17 годин від початку, а завдяки моїй пильності, на початку атаки, на 6й годині я застосував засоби захисту Cloudflare, та вже за 11 годин атака була припинена, думаю через її нераціональність для зловмисника.

Після завершення атаки я вимкнув режим I’m under attack mode та продовжую моніторинг активності сервера, щоб бути готовим в будь який час запобігти повторним викликам!

Висновки

Досвід боротьби з DDoS-атакою на власному сервері показав, що навіть з мінімальними ресурсами — Raspberry Pi, власний блог і безкоштовний тариф Cloudflare — можна ефективно захищатися від загроз, якщо мати базове розуміння роботи мережі, серверів і систем моніторингу.

Я переконався, що:

  • Превентивні дії важливі. Встановлення Cloudflare заздалегідь дозволило оперативно увімкнути захисні механізми.
  • Засоби моніторингу, такі як Zabbix, допомагають швидко виявити аномалії і локалізувати джерело проблеми.
  • Cloudflare виявився надзвичайно ефективним навіть у безкоштовному варіанті, зокрема завдяки режиму I’m Under Attack, який дозволяє відсіяти шкідливий трафік ще до потрапляння на сервер.
  • Відкритість до навчання та аналізу логів — ключ до швидкої реакції. Команди ps, awk, аналіз access.log допомогли не лише виявити джерело навантаження, а й зробити висновки щодо типу атаки.

Цей випадок підтвердив, що надійний захист — це не завжди дорога інфраструктура, а в першу чергу уважність, готовність до реагування та вміння працювати з доступними інструментами.

Мій блог залишився онлайн, і це найкращий показник ефективності застосованих рішень.

]]>
https://ostrich.kyiv.ua/uk/2025/05/25/cloudflare-%d1%80%d0%b5%d0%b0%d0%bb%d1%8c%d0%bd%d0%b8%d0%b9-%d0%b4%d0%be%d1%81%d0%b2%d1%96%d0%b4-%d0%b2%d1%96%d0%b4%d0%b1%d0%b8%d1%82%d1%82%d1%8f-ddos-%d0%b0%d1%82%d0%b0%d0%ba%d0%b8-%d0%b7-%d1%80/feed/ 0