↓ До тексту
  1. Статті/

CrowdSec проти fail2ban - коли сторожу треба спільнота

cat /etc/passwd
Автор
cat /etc/passwd
Технічний блог про Linux, DevOps та Open Source технології.
Зміст
Захист сервера - частина серії статей.
Частина 2: ця стаття (ти тут)

У попередньому пості fail2ban чудово впорався з брутфорсом: прочитав логи, порахував невдалі входи й забанив набридливий IP. Але він бачить лише те, що відбувається у тебе, і банить за простими правилами «N промахів - бан». CrowdSec - це наступний крок тієї самої ідеї: детекція за поведінкою, окремий компонент для блокування і, найцікавіше, колективна база репутації IP - твій сервер користується даними про атаки на тисячі інших серверів.

Поставимо його на такий самий сервер, нацькуємо той самий брутфорс - і подивимось, що він уміє понад fail2ban.

Що потрібно зробити?
#

Поставити CrowdSec із офіційного репозиторію (у Debian лежить дуже стара версія), додати bouncer, який реально блокує, а тоді повторити наш брутфорс із сусідньої машини й побачити бан у реальному часі. Насамкінець - розберемо головну відмінність від fail2ban: колективну базу.

З чим працюю?
#

Та сама пара одноразових машин, що й у пості про fail2ban, обидві Debian 13:

  • srv-01.linuxway.com.ua (10.10.60.102) - сервер, який захищаємо;
  • attacker (10.10.60.103) - з нього ломимось.

Ставимо CrowdSec
#

Важливий нюанс: у самому Debian 13 лежить CrowdSec аж 1.4.6 (реліз 2022 року, без половини сучасних можливостей). Тому ставимо з офіційного репозиторію - він дає актуальну гілку:

1
2
curl -s https://install.crowdsec.net | sudo sh
apt install crowdsec

Під час установки CrowdSec сам знаходить запущені сервіси й налаштовується під них. На Debian 13 це особливо приємно: він одразу бачить, що sshd пише в systemd journal (нема /var/log/auth.log!), і генерує правильний acquisition-конфіг source: journalctl. Разом із цим приїжджає колекція crowdsecurity/sshd з шістьма ssh-сценаріями - руками робити нічого не треба.

Але є принципова річ: CrowdSec сам нічого не блокує. Агент лише детектить і пише рішення; застосовує їх окремий bouncer. Ставимо firewall-bouncer для nftables (Debian 13 саме на ньому):

1
apt install crowdsec-firewall-bouncer-nftables

Він сам реєструється в агенті - перевіримо, що все на місці:

1
2
cscli bouncers list     # bouncer під’єднався
cscli metrics show acquisition    # журнал ssh читається

Заковика з приватними IP. На відміну від fail2ban, CrowdSec за замовчуванням не банить приватні адреси (RFC1918) - це розумний дефолт, щоб не відстрелити собі внутрішню мережу. Але мій attacker сидить у тій самій підмережі 10.10.60.0/24, тож для демо я тимчасово прибрав 10.0.0.0/8 з вайтлиста (/etc/crowdsec/parsers/s02-enrich/whitelists.yaml). У реальному житті цього не чіпають.

Той самий брутфорс - і бан
#

Запускаю з attacker той самий перебір паролів до srv-01. Ліворуч - живий монітор активних банів CrowdSec, праворуч - атакувальник. Дивись, як після кількох спроб у моніторі зʼявляється рішення:

CrowdSec розпізнав атаку не за тупим лічильником, а за сценарієм - ssh-bf (швидкий брутфорс) чи ssh-slow-bf (повільний, розтягнутий у часі), залежно від темпу. А далі є помітна відмінність від fail2ban: той робив reject - і атакувальник одразу бачив Connection refused. Bouncer CrowdSec за замовчуванням робить drop - пакети зникають мовчки, і зловмисник отримує Connection timed out, повисівши в порожнечі. Дрібниця, а боту додає роботи.

Головна відмінність: колективна база
#

Якби все закінчувалось на «забанив свій брутфорс», різниця з fail2ban була б косметичною. Але ось що цікаво. Одразу після встановлення, без жодного акаунта, CrowdSec під’єднався до центрального API (CAPI) і підтягнув колективну базу - 15 000 IP, які зловили на атаках по всій мережі CrowdSec.

І всі вони вже заблоковані на моєму сервері, хоча жодна з них до мене ще не стукала. Переважно це ssh-брутфорсери, але є і спамери, і сканери. Це і є суть CrowdSec: ти не сам-один проти ботів, а частина мережі, де кожна атака на будь-кого стає сигналом для всіх. fail2ban так не вміє - він бачить лише власні логи й реагує постфактум.

CAPI (колективна база) - це не те саме, що хмарна Console на app.crowdsec.net. База працює локально й безкоштовно, акаунт для нього не потрібен. Console - окремий необовʼязковий веб-UI.

Як подивитись, що всередині
#

Уся щоденна робота з CrowdSec - через cscli. Кілька команд, які варто знати з першого дня: що за набори правил стоять, які атаки ти ловиш, хто блокує і скільки кого забанено.

  • cscli collections list - встановлені колекції (готові набори парсерів і сценаріїв);
  • cscli scenarios list - за якими сценаріями CrowdSec розпізнає атаки (ssh-bf, ssh-slow-bf, сканери, postfix тощо);
  • cscli bouncers list - підключені bouncer-и, що виконують блокування;
  • cscli metrics show decisions - скільки й за що забанено, окремо локальна детекція і колективна база (CAPI);
  • cscli decisions list - активні бани просто зараз.

Оновити правила з хабу - cscli hub update && cscli hub upgrade. Додати новий набір (наприклад, для nginx) - cscli collections install crowdsecurity/nginx. Руками забанити чи розбанити IP - cscli decisions add --ip X --duration 4h і cscli decisions delete --ip X.

Графіки: чіпляємо до Grafana
#

CLI - це добре, але хочеться й картинки. Своєї веб-панелі CrowdSec не має, зате віддає Prometheus-метрики на порту 6060. Збираємо навколо них стандартний стек: Prometheus їх збирає, Grafana малює.

Спершу відкриваємо метрики назовні - у /etc/crowdsec/config.yaml:

1
2
3
4
5
prometheus:
  enabled: true
  level: full
  listen_addr: 0.0.0.0   # щоб дотягнувся Prometheus із контейнера
  listen_port: 6060

systemctl restart crowdsec - і curl localhost:6060/metrics має сипати метрики cs_*. Поряд піднімаємо Prometheus + Grafana. prometheus.yml:

1
2
3
4
5
6
global:
  scrape_interval: 10s
scrape_configs:
  - job_name: crowdsec
    static_configs:
      - targets: ["localhost:6060"]

compose.yml (обидва в host-мережі, щоб бачити і CrowdSec, і одне одного по localhost):

1
2
3
4
5
6
7
8
9
services:
  prometheus:
    image: prom/prometheus:v2.54.1
    network_mode: host
    volumes:
      - ./prometheus.yml:/etc/prometheus/prometheus.yml:ro
  grafana:
    image: grafana/grafana:11.5.1
    network_mode: host

Лишилось у Grafana (:3000) додати datasource Prometheus (http://localhost:9090) і заімпортувати офіційний дашборд CrowdSec - найшвидше за ID з grafana.com: 19010 (Overview), 19011 (Insight). Бери свіжу Grafana (11+) - старі панелі дашборда вона осучаснить сама. За кілька хвилин маємо живу картину:

Офіційний дашборд CrowdSec Overview у Grafana: сплеск brute-force на Buckets overflow, Decisions Count 15 000 із колективної бази, алерти та рішення за сценаріями

Тут одразу видно весь епізод: сплеск на Buckets overflow і Parsers у момент нашого брутфорсу, Decisions Count рівно 15000 (та сама колективна база), кількість алертів і розбивку рішень за сценаріями - де ssh:bruteforce зі спільноти тримається на 15 тисячах, а наші локальні ssh-bf/ssh-slow-bf лише визирають біля нуля. Усе з реального Prometheus, без жодної намальованої статики.

То fail2ban чи CrowdSec?
#

Не «краще-гірше», а різні інструменти під різні задачі:

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

Одне чесне застереження про CrowdSec: власної веб-панелі з коробки він не має (стару команду cscli dashboard прибрали) - дані або через cscli, або через Grafana поверх Prometheus, як ми щойно й зробили. Хмарна Console теж є, але це вже хмара.

Куди далі
#

Маємо два способи автоматично банити брутфорс. Але бан непроханих гостей - це лише один рубіж. У фінальному пості серії зберемо базовий чеклист безпеки сервера: ssh-ключі замість паролів, вимкнений вхід root-ом, файрвол, автооновлення - і місце fail2ban/CrowdSec у цій картині. Щоб свіжий сервер був прикритий з усіх боків, а не лише з одного.

Захист сервера - частина серії статей.
Частина 2: ця стаття (ти тут)

Related

fail2ban - автоматичний вартовий проти SSH-брутфорсу

·5 хвилин
fail2ban - це сторож, що читає логи, рахує невдалі входи й автоматично банить IP, з якого ломляться. Піднімаємо його на Debian 13, брутфорсимо власний сервер із сусідньої машини й дивимось, як бан накладається в реальному часі. Плюс три заковики, специфічні саме для trixie.

Cowrie - honeypot, що ловить незваних гостей

·5 хвилин
Honeypot - це сервер-приманка: він навмисне виглядає вразливим, впускає зловмисника зі слабким паролем і тихо записує все, що той робить. Піднімаємо Cowrie в Docker, самі граємо «гостя» і дивимось, хто клюне - у реальному часі.