Интеграция CrowdSec с ispmanager 6
CrowdSec - это современная open-source система безопасности с принципами, схожими с «коллективным фаерволом». Она анализирует логи, выявляет подозрительную активность (например, bruteforce, сканирование портов, DDoS) и автоматически применяет решения для блокировки или ограничения доступа IP-адресов злоумышленников.
Установка и настройка
Установка пакетов
Установите CrowdSec на сервер с панелью ispmanager:
curl -s https://packagecloud.io/install/repositories/crowdsec/crowdsec/script.deb.sh | bash
apt install -y crowdsec crowdsec-firewall-bouncer-nftables
curl -s https://packagecloud.io/install/repositories/crowdsec/crowdsec/script.rpm.sh | bash -s -- os=el dist=9
dnf install -y crowdsec crowdsec-firewall-bouncer-nftables
Коллекции nginx, sshd, linux - встроенные и устанавливаются автоматически.
Настройка сетевых параметров
По умолчанию, CrowdSec использует порт 8080, поэтому необходимо изменить его в файлах конфигурации /etc/crowdsec/config.yaml и /etc/crowdsec/local_api_credentials.yaml на 8070.
В /etc/crowdsec/config.yamlизмените следующую строку:
api:
server:
listen_uri: 127.0.0.1:8070
Другие параметры в /etc/crowdsec/config.yamlизменять не нужно.
После изменения порта, необходимо пересоздать файл /etc/crowdsec/local_api_credentials.yaml с новыми данными:
rm -f /etc/crowdsec/local_api_credentials.yaml
cscli machines add --auto
sed -i 's|url: http://127.0.0.1:8080|url: http://127.0.0.1:8070|' /etc/crowdsec/local_api_credentials.yaml
Учтите, что панель использует ряд портов для своей работы.
Также в файле /etc/crowdsec/parsers/s02-enrich/whitelists.yaml можно сразу указать IP-адреса, которые являются исключениями.
Настройка парсеров и сценариев
Парсеры преобразуют сырые строки журналов в структурированные события с мета-полями (log_type, source_ip, service и т.д.). Сценарии затем используют эти поля для принятия решений. Парсеры находятся в каталоге /etc/crowdsec/parsers.
Сценарии анализируют поток событий от парсеров и принимают решение при превышении порога аномальной активности: если порог был превышен, то создаётся уведомление remediation: true, которое меняет профиль решений в бан на 4 часа. Сценарии находятся в каталоге /etc/crowdsec/scenarios. Профили решений указаны в файле /etc/crowdsec/profiles.yaml.
Сначала создайте создайте коллекцию журналов в файле /etc/crowdsec/acquis.yaml, указав следующее содержимое для файла:
filenames:
- /var/log/nginx/*.log
labels:
type: nginx
---
filenames:
- /var/log/auth.log
- /var/log/syslog
labels:
type: syslog
---
filenames:
- /var/log/apache2/*.log
labels:
type: apache2
---
filenames:
- /var/www/httpd-logs/*.log
labels:
type: nginx
service: nginx
---
filenames:
- /usr/local/mgr5/var/ispmgr.auth.log
labels:
type: syslog
service: ispmanager
---
filenames:
- /usr/local/mgr5/var/ihttpd.log
labels:
type: ihttpd-log
service: ispmanager
filenames:
- /var/log/secure
- /var/log/messages
labels:
type: syslog
---
filenames:
- /var/log/nginx/*.log
labels:
type: nginx
---
filenames:
- /var/log/httpd/*access_log
labels:
type: apache2
---
filenames:
- /var/www/httpd-logs/*.access.log
labels:
type: nginx
service: nginx
---
filenames:
- /usr/local/mgr5/var/ispmgr.auth.log
labels:
type: syslog
service: ispmanager
---
filenames:
- /usr/local/mgr5/var/ihttpd.log
labels:
type: ihttpd-log
service: ispmanager
В AlmaLinux потребуется установить и включить rsyslog:
dnf install -y rsyslog
systemctl enable --now rsyslog
Каждый блок, который отделен символами --- (три минуса) - отдельный источник. Параметр type определяет, какой парсер будет обрабатывать строки из файла:
type: syslog- подключает парсер crowdsecurity/syslog-logs, извлекает сообщения типов program, timestamp и message.type: nginx- подключает парсер crowdsecurity/nginx-logs, разбирает сообщения от Nginx типа access.type: apache2- подключает парсер crowdsecurity/apache2-logs, разбирает сообщения от Apache типа access и error.type: ihttpd-log- пользовательский тип, который обрабатывается парсером панели ihttpd-connections.yaml.
Отключите парсер GeoIP:
mv /etc/crowdsec/parsers/s02-enrich/geoip-enrich.yaml{,.disabled}
cscli parsers remove crowdsecurity/geoip-enrich --force
cscli parsers remove crowdsecurity/auditd-logs --force
Парсеры и сценарии для ispmanager 6
Пользовательские парсеры создаются помещаются в каталог /etc/crowdsec/parsers/s01-parse/.
Создайте парсер по пути /etc/crowdsec/parsers/s01-parse/ispmanager-auth.yaml для отслеживания успешных входов в панель:
name: crowdsecurity/ispmanager-auth
description: "Parse ispmanager ispmgr.auth.log"
filter: "evt.Parsed.program == 'ispmgr'"
onsuccess: next_stage
grok:
pattern: '^%{TIMESTAMP_ISO8601:timestamp}\t%{IP:source_ip}\t%{DATA:user}$'
apply_on: message
statics:
- target: evt.Meta.log_type
value: ispmanager_auth_success
- target: evt.Meta.service
value: ispmanager
- meta: username
expression: evt.Parsed.user
Создайте парсер по пути /etc/crowdsec/parsers/s01-parse/ispmanager-connections.yaml для отслеживания подключений к панели:
name: crowdsecurity/ihttpd-connections
description: "Parse ihttpd.log for connections and errors"
filter: "evt.Parsed.program == 'ihttpd-log'"
onsuccess: next_stage
nodes:
- grok:
pattern: '%{GREEDYDATA}add connection %{INT:conn_id} from %{IP:source_ip}:%{INT:port}%{GREEDYDATA}'
apply_on: message
statics:
- target: evt.Meta.log_type
value: ihttpd_panel_connection
- target: evt.Meta.service
value: ispmanager
- meta: source_ip
expression: evt.Parsed.source_ip
- grok:
pattern: '%{GREEDYDATA}ERROR Error [%{IP:source_ip}]: manager %{GREEDYDATA}'
apply_on: message
statics:
- target: evt.Meta.log_type
value: ihttpd_panel_error
- target: evt.Meta.service
value: ispmanager
- meta: source_ip
expression: evt.Parsed.source_ip
- grok:
pattern: '%{GREEDYDATA}WARNING Shutdown bad connection%{GREEDYDATA}'
apply_on: message
statics:
- target: evt.Meta.log_type
value: ihttpd_bad_connection
- target: evt.Meta.service
value: ispmanager
Все сценарии помещаются в каталог /etc/crowdsec/scenarios/.
Создайте сценарий по пути /etc/crowdsec/scenarios/ihttpd-bruteforce.yaml для определения брутфорса:
type: leaky
name: crowdsecurity/ihttpd-bruteforce
description: "Detect bruteforce on ispmanager panel"
filter: "evt.Meta.log_type == 'ihttpd_panel_connection' && !IpInRange(evt.Meta.source_ip, '127.0.0.0/8') && !IpInRange(evt.Meta.source_ip, '10.0.0.0/8') && !IpInRange(evt.Meta.source_ip, '192.168.0.0/16') && !IpInRange(evt.Meta.source_ip, '172.16.0.0/12')"
leakspeed: "10s"
capacity: 15
groupby: evt.Meta.source_ip
blackhole: 1m
labels:
service: ispmanager
type: bruteforce
remediation: true
Создайте сценарий по пути /etc/crowdsec/scenarios/http-generic-test.yaml для определения проверочных запросов к HTTP:
type: trigger
name: crowdsecurity/http-generic-test
description: "HTTP generic test for Health Check"
filter: "evt.Meta.log_type == 'http_access-log' && evt.Parsed.request contains '/crowdsec-test-NtktlJHV4TfBSK3wvlhiOBnl'"
groupby: evt.Meta.source_ip
labels:
type: test
service: http
remediation: false
Настройка Bouncer
Bouncer получает от LAPI список забаненных IP-адресов и добавляет их в nftables, где создаётся таблица со списком забаненных этих адресов и правилом DROP в INPUT/FORWARD цепочках.
Зарегистрируйте bouncer:
cscli bouncers add crowdsec-firewall-bouncer
В выводе команды будет указан ключ - укажите его для параметра api_key в файле /etc/crowdsec/bouncers/crowdsec-firewall-bouncer.yaml; также измените порт в параметре api_url на 8070:
mode: nftables
update_frequency: 10s
api_url: http://127.0.0.1:8070/
api_key: <ключ_из_предыдущей_команды>
deny_action: DROP
supported_decisions_types:
- ban
blacklists_ipv4: crowdsec-blacklists
blacklists_ipv6: crowdsec6-blacklists
nftables:
ipv4:
enabled: true
set-only: false
table: crowdsec
chain: crowdsec-chain
priority: -10
ipv6:
enabled: true
set-only: false
table: crowdsec6
chain: crowdsec6-chain
priority: -10
nftables_hooks:
- input
- forward
Запуск и проверка
Запустите службы и проверьте их статус:
systemctl restart crowdsec
systemctl start crowdsec-firewall-bouncer
systemctl status crowdsec
systemctl status crowdsec-firewall-bouncer
Проверка метрик
Таблицу с текущими метриками можно получить командой:
cscli metrics
- Lines read - строк прочитано из файла с момента старта CrowdSec (tail-режим);
- Lines parsed - строк успешно разобрано парсерами;
- Lines unparsed - строк не разобрано парсерами; наличие таких строк для журналов панели (ispmgr.log и ihttpd.log) - нормально, поскольку часто новых событий может не быть);
- Lines poured to bucket - строки, которые попали в сценарии.
Проверка HTTP Health Check
Проверить, что HTTP-логи считываются и CrowdSec реагирует на такие запросы, можно с помощью следующих трех команд:
curl -s -o /dev/null -I "http://ваш-домен/crowdsec-test-NtktlJHV4TfBSK3wvlhiOBnl"
sleep 5
cscli alerts list -s crowdsecurity/http-generic-test -o human
В выводе будет указан IP-адрес сервера, с которого был выполнен запрос.
На AlmaLinux встроенный whitelist отсекает приватные IP (127.0.0.0/8, 10.0.0.0/8, 192.168.0.0/16, 172.16.0.0/12) и запрос с сервера локально будет отфильтрован: необходимо отправлять запрос с внешней машины.
Проверка брутфорса
Чтобы проверить работу сценария для защиты от брутфорса, необходимо сымитировать подбор пароля к панели с помощью команды:
for i in $(seq 1 20); do
curl -sk -o /dev/null -d "sock=1&func=auth&username=admin&password=wrong$i" \
"https://IP_СЕРВЕРА:1500/ispmgr" &
done
wait
sleep 10
cscli alerts list -s crowdsecurity/ihttpd-bruteforce -o human
cscli decisions list -o human | grep ihttpd-bruteforce
На удаленной машине выполните команду:
for i in $(seq 1 20); do
curl -sk -o /dev/null -d "sock=1&func=auth&username=admin&password=wrong$i" \
"https://IP_СЕРВЕРА:1500/ispmgr" &
done
wait
Вернитесь к серверу с панелью и проверьте результат работы сценария:
cscli alerts list -s crowdsecurity/ihttpd-bruteforce -o human
Чтобы снять бан с IP-адреса, выполните команду:
cscli decisions delete -i <ip-адрес>
SaaS-панель и бесплатные черные списки
Зарегистрируйтесь в Crowdsec, перейдите в раздел Security Engines - Engines, нажмите Enroll command, скопируйте команду для подключения сервера к SaaS CrowdSec Console и перезапустите службу:
cscli console enroll %ТОКЕН%
systemctl restart crowdsec
После подключения сервера, в личном кабинете CrowdSec подтвердите запрос на подключение.
Затем в CrowdSec подпишитесь на три бесплатных черных списка в разделе Blocklists - Featured:
- Firehol BotScout
- Firehol greensnow.co
- OTX Georgs Honeypot
Уведомления по серверу будут доступны по адресу https://app.crowdsec.net/alerts.
Настройка уведомлений в Telegram
Для включения уведомлений в Telegram, предварительно потребуется настроить Telegram-бота.
После этого в файле /etc/crowdsec/profiles.yaml раскомментируйте строки с параметрами notifications и http_default, а содержимое файла /etc/crowdsec/notifications/http.yaml замените следующим:
type: http # Don't change
name: http_default # Must match the registered plugin in the profile
# One of "trace", "debug", "info", "warn", "error", "off"
log_level: info
# group_wait: # Time to wait collecting alerts before relaying a message to this plugin, eg "30s"
# group_threshold: # Amount of alerts that triggers a message before <group_wait> has expired, eg "10"
# max_retry: # Number of attempts to relay messages to plugins in case of error
# timeout: # Time to wait for response from the plugin before considering the attempt a failure, eg "10s"
#-------------------------
# plugin-specific options
# The following template receives a list of models.Alert objects
# The output goes in the http request body
format: |
{
"chat_id": "-%ID_ЧАТА_TELEGRAM%",
"text": "
{{range . -}}
{{$alert := . -}}
{{range .Decisions -}}
{{.Value}} will get {{.Type}} for next {{.Duration}} for triggering {{.Scenario}}.
{{end -}}
{{end -}}
",
"reply_markup": {
"inline_keyboard": [
{{ $arrLength := len . -}}
{{ range $i, $value := . -}}
{{ $V := $value.Source.Value -}}
[
{
"text": "See {{ $V }} on shodan.io",
"url": "https://www.shodan.io/host/{{ $V -}}"
},
{
"text": "See {{ $V }} on crowdsec.net",
"url": "https://app.crowdsec.net/cti/{{ $V -}}"
}
]{{if lt $i ( sub $arrLength 1) }},{{end }}
{{end -}}
]
}
url: https://api.telegram.org/bot%ID_БОТА_TELEGRAM%/sendMessage
method: POST
headers:
Content-Type: "application/json"
Замените значения %ID_ЧАТА_TELEGRAM% и %ID_БОТА_TELEGRAM% на собственные, например:
"chat_id": "-890567234"url: https://api.telegram.org/bot321654987:AEEB1kNTGzgli7LyiIGlr6hW9mXJs4Dvo1P/sendMessage
После внесения изменений, перезапустите службу:
systemctl restart crowdsec
Проверить статус плагинов для уведомлений можно с помощью команды:
cscli notifications list
Для проверки работы уведомлений, заблокируйте фиктивный IP-адрес, а затем удалите его из списка:
cscli decisions add --ip 4.3.2.1 --duration 1h
cscli decisions delete --ip 4.3.2.1
Полезные команды
Основные:
- Перезапуск CrowdSec:
systemctl restart crowdsec - Перезапуск Bouncer:
systemctl restart crowdsec-firewall-bouncer
Журналы:
- Последние записи журнала CrwodSec в реальном времени:
tail -f /var/log/crowdsec.log - Последние записи журнала Bouncer в реальном времени:
tail -f /var/log/crowdsec-firewall-bouncer.log
Уведомления:
- Все активные уведомления:
cscli alerts list - Уведомления по указанному сценарию:
cscli alerts list -s crowdsecurity/<имя-сценария> - Список уведомления в человекочитаемом формате:
cscli alerts list -o human
Решения и баны:
- Все активные баны:
cscli decisions list - Все активные баны в человекочитаемом формате:
cscli decisions list -o human - Снять бан с IP-адреса:
cscli decisions delete -i <ip-адрес> - Снять все баны:
cscli decisions delete --all
Метрики:
- Вывод текущих метрик CrowdSec:
cscli metrics
Парсеры и сценарии:
- Установленные компоненты:
cscli hub list - Обновить индекс:
cscli hub update - Обновить указанный парсер:
cscli upgrade crowdsecurity/nginx-logs
Проверка nftables:
- Список забаненых адресов в ядре:
nft list set ip crowdsec crowdsec-blacklists-crowdsec - Список цепочек с правилом DROP:
nft list chain ip crowdsec crowdsec-chain-input