doc_memo/raspberry-and-orange-pi/host-protection-with-crowdsec.md

45 KiB
Raw Blame History

Защита хоста с помощью CrowdSec

Вы наверняка использовали (или как минимум слышали) о Fail2Ban. Он очень широко распространён для защиты SSH на хостах, противодействия сканированию сайтов, легких DDoS-атак и "фонового bot-трафика". Fail2Ban существует с 2004 года и давно стал стандартом для защиты серверов. Но он слабо подходит для защиты кластеров Kubernetes, так поды обслуживающие внешний трафик (Ingress-контроллеры Traefik в случае k3s) могут находиться на разных узлах кластера. Если Fail2Ban заблокирует IP-адрес на одной ноде, то он не сможет защитить другие узлы кластера, так как они ничего не узнают о блокировках.

Для защиты распределённых систем (в том числе кластеров Kubernetes) набирает популярность CrowdSec. Это проект с открытым исходным кодом, который, кроме обмена информацией об атаках между узлами (за периметром), использует и внешний краудсорсинг (Community Blocklist) для защиты от атак. Он собирает данные о блокировках и позволяет обмениваться этой информацией между всеми участниками сети (это отключаемая опция, и по умолчанию она отключена). Таким образом, CrowdSec может не только защитить все узлы кластера (благодаря обмену информацией за периметром), о блокировать IP-адреса, еще до их атаки на ваш сервер (если данные IP уже заблокированы другими участниками CrowdSec). А еще CrowdSec модульный, поддерживает сценарии (http-cms-scanning, sshd-bf и тому-подобное),в 60 раз быстрее Fail2Ban (он написан на Golang), работает с IPv6 и имеет интеграции с Traefik, Cloudflare, Nginx, k3s, Docker и другими инструментами. CrowdSec активно растёт в нише DevOps, облаков, контейнеров и кластеров Kubernetes. А еще он не требовательный по ресурсам (~100 МБ RAM) и подходит для Orange Pi.


Утановка CrowdSec

В принципе, СrowdSec можно установить в кластер через Helm. Тогда он сам развернется на всех узлах кластера и это отличный вариант для защиты Traefik (HTTP-запросы, сценарии http-cms-scanning, http-probing) и контейнеризированных приложений (в моем случае Gitea, 3x-ui и тому подобного). Но мне нужно защитить еще и SSH самих узлов (узла) кластера. Поэтому план такой:

  • Хостовый CrowdSec (на одном или всех узлах кластера) использует тот же Local API (LAPI) через виртуальный IP (VIP) Keepalived для получения бан-листа и применяет его к SSH (через Firewall Bouncer) и через тот же LAPI сообщает о банах ssh-bt в CrowdSec Agent внутри k3s.
  • Кластерный CrowdSec Agent, внутри k3s, анализирует логи Traefik и создаёт решения (decisions) о бане IP.
  • Traefik Bouncer в k3s, также подключается к LAPI для защиты HTTP (для git.cube2.ru и других web-приложений).

CrowdSec на первом узле и защита SSH на хосте


Подготовка к установке CrowdSec

Делаем обновляем список пактов и систему:

sudo apt update
sudo apt upgrade

Добавляем репозиторий CrowdSec и ключи репозитория:

curl -s https://packagecloud.io/install/repositories/crowdsec/crowdsec/script.deb.sh | sudo bash

Установка CrowdSec и проверка

Устанавливаем CrowdSec:

sudo apt install crowdsec

Увидим, в число прочего:

...
...
reating /etc/crowdsec/acquis.yaml
INFO[2025-xx-xx xx:xx:xx] crowdsec_wizard: service 'ssh': /var/log/auth.log
INFO[2025-xx-xx xx:xx:xx] crowdsec_wizard: using journald for 'smb'
INFO[2025-xx-xx xx:xx:xx] crowdsec_wizard: service 'linux': /var/log/syslog /var/log/kern.log
Machine 'xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx' successfully added to the local API.
API credentials written to '/etc/crowdsec/local_api_credentials.yaml'.
Updating hub
Downloading /etc/crowdsec/hub/.index.json
Action plan:
🔄 check & update data files


INFO[2025-05-17 17:56:45] crowdsec_wizard: Installing collection 'crowdsecurity/linux'
downloading parsers:crowdsecurity/syslog-logs
downloading parsers:crowdsecurity/geoip-enrich
downloading https://hub-data.crowdsec.net/mmdb_update/GeoLite2-City.mmdb
downloading https://hub-data.crowdsec.net/mmdb_update/GeoLite2-ASN.mmdb
downloading parsers:crowdsecurity/dateparse-enrich
downloading parsers:crowdsecurity/sshd-logs
downloading scenarios:crowdsecurity/ssh-bf
downloading scenarios:crowdsecurity/ssh-slow-bf
downloading scenarios:crowdsecurity/ssh-cve-2024-6387
downloading scenarios:crowdsecurity/ssh-refused-conn
downloading contexts:crowdsecurity/bf_base
downloading collections:crowdsecurity/sshd
downloading collections:crowdsecurity/linux
enabling parsers:crowdsecurity/syslog-logs
enabling parsers:crowdsecurity/geoip-enrich
enabling parsers:crowdsecurity/dateparse-enrich
enabling parsers:crowdsecurity/sshd-logs
enabling scenarios:crowdsecurity/ssh-bf
enabling scenarios:crowdsecurity/ssh-slow-bf
enabling scenarios:crowdsecurity/ssh-cve-2024-6387
enabling scenarios:crowdsecurity/ssh-refused-conn
enabling contexts:crowdsecurity/bf_base
enabling collections:crowdsecurity/sshd
enabling collections:crowdsecurity/linux
...
...

Как видим, CrowdSec сам определил, что у нас есть SSH и Linux (syslog и kern.log). Создан локальный API (LAPI) м логин/пароль для него записан в /etc/crowdsec/local_api_credentials.yaml.

Далее CrowdSec загрузил парсеры, сценарии и коллекции для настройки защиты SSH и Linux.

Проверим, что CrowdSec работает:

sudo systemctl status crowdsec

Увидим что-то вроде:

● crowdsec.service - Crowdsec agent
     Loaded: loaded (/lib/systemd/system/crowdsec.service; enabled; vendor preset: enabled)
     Active: active (running) since Sat xxxx-xx-xx xx:xx:xx XXX; 51min ago
   Main PID: 3357651 (crowdsec)
      Tasks: 14 (limit: 18978)
     Memory: 30.7M
        CPU: 18.233s
     CGroup: /system.slice/crowdsec.service
             ├─3357651 /usr/bin/crowdsec -c /etc/crowdsec/config.yaml
             └─3357715 journalctl --follow -n 0 _SYSTEMD_UNIT=smb.service

Xxx xx xx:xx:xx xxxx systemd[1]: Starting Crowdsec agent...
Xxx xx xx:xx:xx xxxx systemd[1]: Started Crowdsec agent.

Проверим версию CrowdSec:

sudo cscli version

Увидим что-то вроде:

version: v1.6.8-debian-pragmatic-arm64-f209766e
Codename: alphaga
BuildDate: 2025-03-25_14:50:57
GoVersion: 1.24.1
Platform: linux
libre2: C++
User-Agent: crowdsec/v1.6.8-debian-pragmatic-arm64-f209766e-linux
...
...

Проверим список установленных парсеров:

sudo cscli parsers list

Увидим что-то вроде:

──────────────────────────────────────────────────────────────────────────────────────────────────────────────
 PARSERS                                                                                                      
──────────────────────────────────────────────────────────────────────────────────────────────────────────────
 Name                            📦 Status    Version  Local Path                                             
──────────────────────────────────────────────────────────────────────────────────────────────────────────────
 crowdsecurity/dateparse-enrich  ✔️  enabled  0.2      /etc/crowdsec/parsers/s02-enrich/dateparse-enrich.yaml 
 crowdsecurity/geoip-enrich      ✔️  enabled  0.5      /etc/crowdsec/parsers/s02-enrich/geoip-enrich.yaml     
 crowdsecurity/smb-logs          ✔️  enabled  0.2      /etc/crowdsec/parsers/s01-parse/smb-logs.yaml          
 crowdsecurity/sshd-logs         ✔️  enabled  3.0      /etc/crowdsec/parsers/s01-parse/sshd-logs.yaml         
 crowdsecurity/syslog-logs       ✔️  enabled  0.8      /etc/crowdsec/parsers/s00-raw/syslog-logs.yaml         
 crowdsecurity/whitelists        ✔️  enabled  0.3      /etc/crowdsec/parsers/s02-enrich/whitelists.yaml       
──────────────────────────────────────────────────────────────────────────────────────────────────────────────

Как видим crowdsecurity/sshd-logs доступны, а значит CrowdSec может парсить логи SSH. Проверим список установленных коллекций:

 sudo cscli collections list

Увидим что-то вроде:

─────────────────────────────────────────────────────────────────────────────────
 COLLECTIONS                                                                     
─────────────────────────────────────────────────────────────────────────────────
 Name                 📦 Status    Version  Local Path                           
─────────────────────────────────────────────────────────────────────────────────
 crowdsecurity/linux  ✔️  enabled  0.2      /etc/crowdsec/collections/linux.yaml 
 crowdsecurity/smb    ✔️  enabled  0.1      /etc/crowdsec/collections/smb.yaml   
 crowdsecurity/sshd   ✔️  enabled  0.6      /etc/crowdsec/collections/sshd.yaml  
─────────────────────────────────────────────────────────────────────────────────

Видим, что crowdsecurity/sshd доступны. Проверим список установленных сценариев:

sudo cscli scenarios list

Увидим что-то вроде:

SCENARIOS                                                                                             
───────────────────────────────────────────────────────────────────────────────────────────────────────
 Name                             📦 Status    Version  Local Path                                     
───────────────────────────────────────────────────────────────────────────────────────────────────────
 crowdsecurity/smb-bf             ✔️  enabled  0.2      /etc/crowdsec/scenarios/smb-bf.yaml            
 crowdsecurity/ssh-bf             ✔️  enabled  0.3      /etc/crowdsec/scenarios/ssh-bf.yaml            
 crowdsecurity/ssh-cve-2024-6387  ✔️  enabled  0.2      /etc/crowdsec/scenarios/ssh-cve-2024-6387.yaml 
 crowdsecurity/ssh-refused-conn   ✔️  enabled  0.1      /etc/crowdsec/scenarios/ssh-refused-conn.yaml  
 crowdsecurity/ssh-slow-bf        ✔️  enabled  0.4      /etc/crowdsec/scenarios/ssh-slow-bf.yaml       
───────────────────────────────────────────────────────────────────────────────────────────────────────

Сценарии ssh-bf, crowdsecurity/ssh-slow-bf (брутфорсинг и медленный брутфорсинг SSH), crowdsecurity/ssh-cve-2024-6387 (защита от regreSSHion-атак на старые SSH-сервера) и crowdsecurity/ssh-refused-conn` (отказ соединения SSH) доступны.

Кстати, обновлять все это богачество (парсеры, сценарии, коллекции и т.п.) можно командой:

sudo cscli hub update

Проверим конфиги CrowdSec, и убедимся, что он анализирует логи SSH:

sudo cat /etc/crowdsec/acquis.yaml

Должны увидеть вот такой блок:

filenames:
  - /var/log/auth.log
labels:
  type: syslog
---

Если, вдруг, такого блока нет, добавьте его (лучше в начало) и перезапустим CrowdSec. Но обычно все уже настроено.

Проверим, что CrowdSec анализирует логи SSH:

sudo cscli metrics

Увидим что-то вроде:

╭──────────────────────────────────────────────────────────────────────────────────────────────────────────────────╮
│ Acquisition Metrics                                                                                              │
├────────────────────────┬────────────┬──────────────┬────────────────┬────────────────────────┬───────────────────┤
│ Source                 │ Lines read │ Lines parsed │ Lines unparsed │ Lines poured to bucket │ Lines whitelisted │
├────────────────────────┼────────────┼──────────────┼────────────────┼────────────────────────┼───────────────────┤
│ file:/var/log/auth.log │ 628        │ -            │ 628            │ -                      │ -                 │
│ file:/var/log/kern.log │ 2.78k      │ -            │ 2.78k          │ -                      │ -                 │
│ file:/var/log/syslog   │ 3.46k      │ -            │ 3.46k          │ -                      │ -                 │
╰────────────────────────┴────────────┴──────────────┴────────────────┴────────────────────────┴───────────────────╯
...
...

Как видим, CrowdSec читает /var/log/auth.log (логи SSH).


Установка CrowdSec Firewall Bouncer -- блокировщик IP-адресов

По мне, блокировки CrowdSec довольно беззубые. К счастью через "вышибалу" Firewall Bouncer можно блокировать IP-адреса по iptables (или nftables) и сделать CrowdSec злее fail2ban. Для этого нужно установить crowdsec-firewall-bouncer-iptables:

sudo apt-get install crowdsec-firewall-bouncer-iptables

Проверим, что "вышибала" запустилась:

sudo systemctl status crowdsec-firewall-bouncer

Увидим что-то вроде:

● crowdsec-firewall-bouncer.service - The firewall bouncer for CrowdSec
     Loaded: loaded (/etc/systemd/system/crowdsec-firewall-bouncer.service; enabled; vendor preset: enabled)
     Active: active (running) since Sun 2025-05-18 14:47:10 MSK; 723ms ago
    Process: 621537 ExecStartPre=/usr/bin/crowdsec-firewall-bouncer -c /etc/crowdsec/bouncers/crowdsec-firewall-bouncer.yaml -t (code=exited, status=0/SUCCESS)
    Process: 621674 ExecStartPost=/bin/sleep 0.1 (code=exited, status=0/SUCCESS)
   Main PID: 621622 (crowdsec-firewa)
      Tasks: 10 (limit: 18978)
     Memory: 7.4M
        CPU: 401ms
     CGroup: /system.slice/crowdsec-firewall-bouncer.service
             └─621622 /usr/bin/crowdsec-firewall-bouncer -c /etc/crowdsec/bouncers/crowdsec-firewall-bouncer.yaml

May 18 14:47:04 opi5 systemd[1]: Starting The firewall bouncer for CrowdSec...
May 18 14:47:10 opi5 systemd[1]: Started The firewall bouncer for CrowdSec.

Подключить его в CrowdSec:

sudo cscli bouncers add firewall-bounce

Проверим, что "вышибала" добавлен:

sudo cscli bouncers list

Увидим что-то вроде:

─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────
 Name                      IP Address  Valid  Last API pull         Type                       Version                             Auth Type 
─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────
 cs-firewall-bouncer-xxxx  127.0.0.1   ✔️     xxxx-xx-xxTxx:xx:xxZ  crowdsec-firewall-bouncer  v0.0.31-debian-pragmatic-xxxxxx...  api-key   
 firewall-bouncer                      ✔️                                                                                          api-key   
─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────

Подключаем наш CrowdSec к обмену данными об атаках

CrowdSec может обмениваться данными об атаках с другими участниками сети. Чтобы это сделать, нужно пойти на сайт CrowdSec и зарегистрироваться. После подтверждения регистрации по email, в личном кабинете в самом низу, увидим строчку команды, типа:

sudo cscli console enroll -e context хеш-идентификатор-вашего-аккаунта

Скопируем эту команду и выполняем в терминале. Увидим что-то вроде:

INFO manual set to true                           
INFO context set to true                          
INFO Enabled manual : Forward manual decisions to the console 
INFO Enabled tainted : Forward alerts from tainted scenarios to the console 
INFO Enabled context : Forward context with alerts to the console 
INFO Watcher successfully enrolled. Visit https://app.crowdsec.net to accept it. 
INFO Please restart crowdsec after accepting the enrollment. 

Как видим, нужно перезапустить CrowdSec:

sudo systemctl restart crowdsec

Теперь нужно снова зайти в личный кабинет CrowdSec и подтвердить подключение Security Engine.

Все! Подключение локального CrowdSec к Community Blocklist завершено. В личном кабинете можно посмотреть статистику (по каждому Security Engine, ведь на один аккаунт можно подключить несколько хостов с CrowdSec) и даже управлять фильтрами и сценариями (это не точно).

crowdsec--security-engine-registration.png

Проверим, что CrowdSec получает блокировки через Community Blocklist API (CAPI):

sudo cscli metrics

Увидим что-то типа:

...
...
╭──────────────────────────────────────────╮
│ Local API Decisions                      │
├────────────────┬────────┬────────┬───────┤
│ Reason         │ Origin │ Action │ Count │
├────────────────┼────────┼────────┼───────┤
│ generic:scan   │ CAPI   │ ban    │ 3222  │
│ smb:bruteforce │ CAPI   │ ban    │ 427   │
│ ssh:bruteforce │ CAPI   │ ban    │ 10033 │
│ ssh:exploit    │ CAPI   │ ban    │ 1315  │
╰────────────────┴────────┴────────┴───────╯
...

Как видим, CrowdSec получает блокировки. Если очень интересно, можно посмотреть, что именно и почему блокируется (например, ssh:bruteforce):

sudo cscli decisions list --origin CAPI

Увидим длиннющий список, примерно такого содержания:

╭───────┬────────┬────────────────────────────────────┬────────────────┬────────┬─────────┬────┬────────┬────────────┬──────────╮
│   ID  │ Source │             Scope:Value            │     Reason     │ Action │ Country │ AS │ Events │ expiration │ Alert ID │
├───────┼────────┼────────────────────────────────────┼────────────────┼────────┼─────────┼────┼────────┼────────────┼──────────┤
  .....   ....     ......................               ..............   ...                     .        .........    .
│ ..... │ CAPI   │ Ip:129.211.204.27                  │ ssh:bruteforce │ ban    │         │    │ 0      │ 79h15m46s  │ 1        │
│ ..... │ CAPI   │ Ip:128.199.124.27                  │ ssh:bruteforce │ ban    │         │    │ 0      │ -1h44m14s  │ 1        │
│ ..... │ CAPI   │ Ip:Ip:2602:80d:1006::76            │ ssh:bruteforce │ ban    │         │    │ 0      │ 48h15m46s  │ 1        │
│ ..... │ CAPI   │ Ip:123.58.213.127                  │ ssh:bruteforce │ ban    │         │    │ 0      │ 160h15m46s │ 1        │
╰───────┴────────┴────────────────────────────────────┴────────────────┴────────┴─────────┴────┴────────┴────────────┴──────────╯

Настройка Whitelist (белого списка)

Чтобы не заблокировать себя (случайно) нужно создать в Whitelist (белый список). Например, сделаем home_whitelist (имя списка, таких списков может быть несколько, и

sudo cscli allowlist create home_whitelist -d 'Мой домашний whitelist'

Теперь добавим в него свои домашнюю подсеть или IP-адрес (через пробел можно указать несколько адресов или подсетей):

sudo cscli allowlist add home_whitelist 192.168.1.0/24 XXX.XXX.XXX.XXX

Проверим, что все добавилось:

sudo cscli allowlist inspect home_whitelist

Увидим что-то вроде:

──────────────────────────────────────────────
 Allowlist: home_whitelist                    
──────────────────────────────────────────────
 Name                home_whitelist           
 Description         Мой домашний whitelist   
 Created at          2025-05-17T21:00:13.042Z 
 Updated at          2025-05-17T21:01:29.090Z 
 Managed by Console  no                       
──────────────────────────────────────────────

───────────────────────────────────────────────────────────────
 Value           Comment  Expiration  Created at               
───────────────────────────────────────────────────────────────
 192.168.1.0/24           never       2025-05-17T21:00:13.042Z 
 XXX.XXX.XXX.XXX          never       2025-05-17T21:00:13.042Z 
 XXX.XXX.XXX.XXX          never       2025-05-17T21:00:13.042Z 
 ...
 ...
─────────────────────────────────────────────────────────────── 

Еще один способ отредактировать (создать) Whitelist-конфиг парсера, который мы получили командой sudo cscli parsers list. Конфиг /etc/crowdsec/parsers/s02-enrich/whitelists.yaml довольно простой, если его отредактировать (добавить нужные IP-адреса, подсети или даже доменные имена), а затем перезапустить CrowdSec -- получим тот же результат. Только управлять через списки (allowlist) удобнее. См. документацию.


Настройка Firewall Bouncer (блокировщик IP-адресов)


Сценарии блокировок

Когда мы проверяли установку CrowdSec, и проверим список сценариев shell sudo cscli scenarios list, то нам был показан список yaml-манифестов c конфигурациями сценариев блокировок. Эти сценарии занимаются распознаванием атак, в частности касающихся SSH:

  • /etc/crowdsec/scenarios/ssh-bf.yaml -- брутфорс SSH
  • /etc/crowdsec/scenarios/ssh-slow-bf.yaml -- медленный брутфорс SSH
  • /etc/crowdsec/scenarios/ssh-cve-2024-6387.yaml -- regreSSHion-атака (атаки уязвимости SSH-серверов старых версий)
  • /etc/crowdsec/scenarios/ssh-refused-conn.yaml -- отказ соединения SSH, защищает от сканеров, которые ищут открытые SSH-порты (на очень актуально, если у вас SSH открыт по стандартном 22-порту).

В некоторых манифестах может быть несколько блоков конфигурации блокировок для разных сценариев атак "зловредов". Например, в ssh-bf.yaml есть блоки crowdsecurity/ssh-bf (для тупого брутфорса) и crowdsecurity/ssh-bf_user-enum (для перебора пользователей).

Меняем "беззубые" параметры, на что-то более серьезное. Открываем на редактирование, например, ssh-bf.yaml:

sudo nano /etc/crowdsec/scenarios/ssh-bf.yaml

Увидим что-то типа:

# ssh bruteforce
type: leaky
name: crowdsecurity/ssh-bf
description: "Detect ssh bruteforce"
filter: "evt.Meta.log_type == 'ssh_failed-auth'"
leakspeed: "10s"
references:
  - http://wikipedia.com/ssh-bf-is-bad
capacity: 5
groupby: evt.Meta.source_ip
blackhole: 1m
reprocess: true
labels:
  service: ssh
  confidence: 3
  spoofable: 0
  classification:
    - attack.T1110
  label: "SSH Bruteforce"
  behavior: "ssh:bruteforce"
  remediation: true
---
# ssh user-enum
type: leaky
name: crowdsecurity/ssh-bf_user-enum
description: "Detect ssh user enum bruteforce"
filter: evt.Meta.log_type == 'ssh_failed-auth'
groupby: evt.Meta.source_ip
distinct: evt.Meta.target_user
leakspeed: 10s
capacity: 5
blackhole: 1m
labels:
  service: ssh
  remediation: true
  confidence: 3
  spoofable: 0
  classification:
    - attack.T1589
  behavior: "ssh:bruteforce"
  label: "SSH User Enumeration"

Что тут происходит:

  • Сценарий crowdsecurity/ssh-bf:
    • Тип: leaky -- leaky bucket — алгоритм "дырявое ведро", считающий события в окне времени. Метафора "дырявого ведра" в том, что из дырок на дне идет утечка со скоростью одна попытка за leakspeed. Емкость ведра равна capacity. Когда "ведро" было пустм, в него можно было поместить capacity событий, и после по одому событию в leakspeed. Если ведро переполнено событиями, то включается blackhole (черная дыра) и события игнорируются в течении blackhole времени.
    • Фильтр: evt.Meta.log_type == 'ssh_failed-auth' -- ловит неудачные попытки входа по SSH из /var/log/auth.log.
    • Логика:
      • groupby: evt.Meta.source_ip -- группирует события по IP атакующего.
      • leakspeed: 10s -- "окно времени" — 10 секунд (каждые 10 сек разрешена одна попытка).
      • capacity: 5 -- Бан после 5 неудачных попыток.
      • blackhole: 1m -- Бан на 1 минуту.
  • Сценарий crowdsecurity/ssh-bf_user-enum:
    • Тип тот же.
    • Фильтр тот же.
    • Логика:
      • distinct: evt.Meta.target_user -- считает попытки с разными пользователями (root, admin, pi, orangepi и т.д.).
      • leakspeed: 10s -- "окно времени" — 10 секунд.
      • capacity: 5 -- Бан после 5 разных пользователей за 10 секунд.
      • blackhole: 1m -- Бан на 1 минуту.

Как видим в обоих случаях бан срабатывает после пяти попыток за десять секунд, и блокировка всего на минуту. Конечно, брутфорсеры -- это быстрые атаки, но "быстрота" понятие относительное. Я выставляю:

  • leakspeed: 10m
  • capacity: 2
  • blackhole: 1h

И считаю, что это довольно мягко. Но чтоб случайно не заблокировать себя, когда буду подключаться с внешнего IP не из белого списка (например, по мобильному интернету) -- это разумный компромисс.

После редактирования файла, нужно перезапустить CrowdSec, чтоб он применил изменения:

sudo systemctl restart crowdsec
sudo systemctl restart crowdsec-firewall-bouncer

Другие сценарии можно настроить по аналогии. "Злость" управляется параметрами leakspeed, capacity и blackhole. Но имейте в виду: не стоит менять много параметров одновременно. Настройки разных сценариев могут конфликтовать друг другом, и тогда CrowdSec не запустится.

После перезапуска CrowdSec:

sudo systemctl restart crowdsec

И еще, экспериментально я обнаружил, что настройки дней, например 2d недопустимы. Надо указывать 48h (48 часов), и в целом не нужно сразу месть настройки сразу во всех сценариях. Они могут конфликтовать друг с другом, и CrowdSec не перезапуститься.

Проверим, что CrowdSec начал банить на основании настроенных правил (особо ждать не придется, зловреды попадутся уже через пару минут):

sudo cscli decisions list

Увидим что-то типа:

╭───────┬──────────┬───────────────────┬────────────────────────────────┬─────┬────┬────────────────────────┬────────┬────────────┬──────────╮
│   ID  │  Source  │    Scope:Value    │              Reason            │ Act │ Co │           AS           │ Events │ expiration │ Alert ID │
├───────┼──────────┼───────────────────┼────────────────────────────────┼─────┼────┼────────────────────────┼────────┼────────────┼──────────┤
│ 30004 │ crowdsec │ Ip:39.98.38.186   │ crowdsecurity/ssh-slow-bf      │ ban │ CN │ 37963 Hangzhou Alibaba │ 11     │ 3h54m49s   │ 6        │
│ 30002 │ crowdsec │ Ip:165.246.104.64 │ crowdsecurity/ssh-bf           │ ban │ KR │ 9317 INHA UNIVERSITY   │ 3      │ 3h50m0s    │ 4        │
│ 90210 │ crowdsec │ Ip:180.10.143.248 │ crowdsecurity/ssh-bf_user-enum │ ban │ CN │ 4134 Chinanet          │ 3      │ 3h6m38s    │ 216      │
╰───────┴──────────┴───────────────────┴────────────────────────────────┴─────┴────┴────────────────────────┴────────┴────────────┴──────────╯

Время блокировок

Сценарии занимаются распознаванием угроз, но самими блокировками они не занимаются. Блокировки настроены по умолчанию на четыре часа, и это указано в профилях /etc/crowdsec/profiles.yaml. Чтобы изменить время, на которое "зловред" отправляется в бан, нужно отредактировать этот файл. По умолчанию он вот такой:

name: default_ip_remediation
#debug: true
filters:
 - Alert.Remediation == true && Alert.GetScope() == "Ip"
decisions:
 - type: ban
   duration: 4h
#duration_expr: Sprintf('%dh', (GetDecisionsCount(Alert.GetValue()) + 1) * 4)
# notifications:
#   - slack_default  # Set the webhook in /etc/crowdsec/notifications/slack.yaml before enabling this.
#   - splunk_default # Set the splunk url and token in /etc/crowdsec/notifications/splunk.yaml before enabling this.
#   - http_default   # Set the required http parameters in /etc/crowdsec/notifications/http.yaml before enabling this.
#   - email_default  # Set the required email parameters in /etc/crowdsec/notifications/email.yaml before enabling this.
on_success: break
---
name: default_range_remediation
#debug: true
filters:
 - Alert.Remediation == true && Alert.GetScope() == "Range"
decisions:
 - type: ban
   duration: 4h
#duration_expr: Sprintf('%dh', (GetDecisionsCount(Alert.GetValue()) + 1) * 4)
# notifications:
#   - slack_default  # Set the webhook in /etc/crowdsec/notifications/slack.yaml before enabling this.
#   - splunk_default # Set the splunk url and token in /etc/crowdsec/notifications/splunk.yaml before enabling this.
#   - http_default   # Set the required http parameters in /etc/crowdsec/notifications/http.yaml before enabling this.
#   - email_default  # Set the required email parameters in /etc/crowdsec/notifications/email.yaml before enabling this.
on_success: break

Как видим, по умолчанию блокировка на 4 часа. Чтобы изменить время блокировок, нужно отредактировать duration: 4h на нужное. Но в конфигурации есть "заготовка" для динамического времени блокировок: duration_expr: Sprintf('%dh', (GetDecisionsCount(Alert.GetValue()) + 1) * 4) -- каждый раз, когда зловред попадает в бан, время блокировки увеличивается на 4 часа. То есть, если зловред попался в бан 5 раз, то его блокировка будет 20 часов. И так далее (формулу, при желании, можно изменить). Это то, что нам нужно. Имейте в виду, что подключение duration_expr исключает возможность указать duration (время блокировки) в секции decisions. Таким образом получаем вот такой конфиг:

name: default_ip_remediation
#debug: true
filters:
 - Alert.Remediation == true && Alert.GetScope() == "Ip"
decisions:
 - type: ban
   # duration: 4h
duration_expr: Sprintf('%dh', (GetDecisionsCount(Alert.GetValue()) + 1) * 4)
on_success: break
---
name: default_range_remediation
#debug: true
filters:
 - Alert.Remediation == true && Alert.GetScope() == "Range"
decisions:
 - type: ban
   duration: 5h
on_success: break

Можно добавлять и свои правила. Например, для более длительных блокировок медленных брутфорсов, добавим в конце:

---
name: ssh_slow_bf_remediation
filters:
  - Alert.Remediation == true && Alert.Scenario == "crowdsecurity/ssh-slow-bf"
decisions:
  - type: ban
    duration: 10h
on_success: break

После сохранения конфига, перезапустим CrowdSec:

sudo systemctl restart crowdsec

И убедимся, что время блокировки увеличилось:

sudo cscli decisions list 
╭────────┬──────────┬───────────────────┬──────────────────────┬────────┬─────────┬──────────────────────┬────────┬────────────┬──────────╮
│   ID   │  Source  │    Scope:Value    │        Reason        │ Action │ Country │          AS          │ Events │ expiration │ Alert ID │
├────────┼──────────┼───────────────────┼──────────────────────┼────────┼─────────┼──────────────────────┼────────┼────────────┼──────────┤
│ 165247 │ crowdsec │ Ip:165.246.104.64 │ crowdsecurity/ssh-bf │ ban    │ KR      │ 9317 INHA UNIVERSITY │ 3      │ 91h25m24s  │ 258      │
╰────────┴──────────┴───────────────────┴──────────────────────┴────────┴─────────┴──────────────────────┴────────┴────────────┴──────────╯

Web-панель

Плюсом CrowdSec является то, что благодаря обмену информацией о блокировках, в личном кабинете на сайте CrowdSec можно посмотреть ваши локальные блокировки через веб-интерфейсе:

crowdsec--security-panel.png


Управление блокировками

Можно добавить бан вручную (по умолчанию: duration:4h и type:ban):

sudo cscli decisions add -i xxx.xxx.xxx.xxx
sudo cscli decisions add --ip xxx.xxx.xxx.xxx --duration 24h --reason "любопытный безопасник"
sudo cscli decisions add --ip xxx.xxx.xxx.xxx --reason "web bruteforce" --type captcha

Снять блокировку отдельного IP, подсети (диапазона) или вообще все:

sudo cscli decisions delete --ip xxx.xxx.xxx.xxx
sudo cscli decisions delete --range yyy.yyy.yyyy.yyy/24
sudo cscli decisions delete --all