Обо мне Блог Контакты

Установка и настройка CrowdSec в связке с Traefik

Введение

Те, кто прочитал предыдущую статью, уже примерно имеют представление о том, что такое CrowdSec. Тем, кто не читал, советую ознакомиться.

В этой статье я расскажу, как я установил и настроил CrowdSec у себя в LXC-контейнере Proxmox — там, где работают Traefik и WireGuard.

Как я уже описывал в вводной статье про обратный прокси Traefik, этот LXC-контейнер является точкой входа на мой домашний сервер, где Traefik проксирует запросы к нужным сервисам. Соответственно, поставить дополнительную защиту именно в этот контейнер — логичное решение.

Напомню, что этот LXC-контейнер принимает HTTPS-трафик только через WireGuard-туннель от нашего внешнего VPS сервера. Traefik ловит весь этот трафик и ведёт Access-лог всех запросов. Именно этот лог будет анализировать наш CrowdSec и на основе него блокировать нежелательных клиентов.


Установка CrowdSec

Установка сводится к тому, что нужно добавить в наш пакетный менеджер apt дополнительный репозиторий и затем, используя его, установить сам CrowdSec. Вот две команды для этого:

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

Warning

Вобще, перед тем как выполнять curl | bash, рекомендуется сначала скачать скрипт и проверить его содержимое — это хорошая практика с точки зрения безопасности.

Проверяем, что всё установилось корректно:

cscli version

Если команда показывает версию — значит, установка прошла успешно.

Установка коллекций

Теперь настроим CrowdSec для работы с Traefik. Для начала нам нужно добавить необходимые коллекции. Коллекции — это наборы парсеров и сценариев, по которым CrowdSec определяет вредоносную активность.

cscli collections install crowdsecurity/base-http-scenarios
cscli collections install crowdsecurity/http-cve
cscli collections install crowdsecurity/linux
cscli collections install crowdsecurity/sshd
cscli collections install crowdsecurity/whitelist-good-actors

А также самое главное — коллекция для работы с логами Traefik:

cscli collections install crowdsecurity/traefik

Проверить все установленные коллекции можно командой:

cscli collections list

Белый список локальных адресов

Чтобы CrowdSec случайно не забанил устройства из локальной сети (например, при активном тестировании или отладке), рекомендуется добавить локальные IP-адреса в белый список. Для этого отредактируем файл /etc/crowdsec/parsers/s02-enrich/whitelist-local.yaml:

nano /etc/crowdsec/parsers/s02-enrich/whitelist-local.yaml
name: custom/whitelist-local
description: Whitelist local networks
whitelist:
  reason: local network
  cidr:
    - 192.168.1.0/24

Здесь 192.168.1.0/24 — подсеть вашей локальной сети. Если у вас другая адресация, измените на свою. Можно также добавить конкретные IP-адреса отдельными строками. IP-адреса из указанной подсети будут полностью игнорироваться при анализе логов и никогда не попадут в бан.

Подключение Access-лога Traefik

Далее нам нужно указать CrowdSec, где находится Access-лог Traefik. Путь к файлу лога мы задавали в статической конфигурации Traefik. У меня он /var/log/traefik/access.log.

Редактируем (или создаём) файл /etc/crowdsec/acquis.d/traefik.yaml:

nano /etc/crowdsec/acquis.d/traefik.yaml

Вставляем туда следующее:

filenames:
  - /var/log/traefik/access.log
labels:
  type: traefik

Перезапускаем CrowdSec и проверяем его статус:

systemctl restart crowdsec
systemctl status crowdsec

Теперь можем посмотреть метрики CrowdSec, чтобы убедиться, что он уже работает и читает логи Traefik:

cscli metrics

В выводе вы должны увидеть строку с файлом access.log и количеством прочитанных строк — это значит, что CrowdSec успешно парсит логи.

Подключение Traefik-bouncer

Теперь нам нужно связать Traefik и CrowdSec между собой. CrowdSec сам по себе только анализирует логи и принимает решения о блокировке. А чтобы эти решения реально применялись, нужен bouncer — компонент, который запрашивает у CrowdSec, стоит ли пропускать тот или иной IP-адрес.

Создаём bouncer и копируем ключ. Обязательно сохраните его — он покажется только один раз:

cscli bouncers add traefik-bouncer

Установка плагина CrowdSec в Traefik

Для работы с CrowdSec в Traefik существует внешний плагин crowdsec-bouncer-traefik-plugin. Он устанавливается путём добавления нескольких строк в статическую конфигурацию Traefik.

Открываем файл traefik.yaml и добавляем в конец:

experimental:
  plugins:
    crowdsec:
      moduleName: github.com/maxlerebourg/crowdsec-bouncer-traefik-plugin
      version: v1.4.6

Note

Версия v1.4.6 актуальна на момент написания статьи. Рекомендую проверить последнюю версию в репозитории плагина.

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

systemctl restart traefik

Настройка middleware

Теперь нам нужно создать middleware, который будет использовать установленный плагин. Добавляем его в динамическую конфигурацию Traefik (файл config.yaml) внутри блока http.middlewares:

http:
  middlewares:
    crowdsec:
      plugin:
        crowdsec:
          enabled: true
          crowdsecLapiHost: 127.0.0.1:8080
          crowdsecLapiKey: <КЛЮЧ_КОТОРЫЙ_ВЫ_СКОПИРОВАЛИ>
          crowdsecMode: live
          updateIntervalSeconds: 5
          defaultDecisionSeconds: 14400
          crowdsecLapiTLSInsecureVerify: true
          clientTrustedIPs:
            - 192.168.1.0/24
          forwardedHeadersTrustedIPs:
            - 10.0.0.1/32

Разберём ключевые параметры:

  • crowdsecLapiHost — адрес CrowdSec LAPI. Поскольку CrowdSec работает в этом же LXC-контейнере, указываем 127.0.0.1:8080.
  • crowdsecLapiKey — ключ от traefik-bouncer, который мы скопировали выше.
  • crowdsecMode: livebouncer проверяет каждый запрос в реальном времени, обращаясь к CrowdSec LAPI.
  • updateIntervalSeconds: 5 — как часто bouncer обновляет кэш решений (в секундах).
  • defaultDecisionSeconds: 14400 — время бана по умолчанию на стороне bouncer, то есть 4 часа (14400 секунд).
  • crowdsecLapiTLSInsecureVerify: true — отключает проверку TLS-сертификата при обращении к LAPI. Это безопасно в нашем случае, так как bouncer и LAPI работают на одной машине и общаются через localhost.
  • clientTrustedIPs — IP-адреса, которые никогда не будут заблокированы. Указываем нашу локальную сеть, чтобы CrowdSec случайно не забанил нас самих.
  • forwardedHeadersTrustedIPs — IP-адреса, от которых мы доверяем заголовку X-Forwarded-For. Указываем адрес нашего VPS в WireGuard-сети. Это важно, потому что именно через этот заголовок Traefik определяет реальный IP-адрес клиента, и если не доверять источнику заголовка, CrowdSec не сможет корректно идентифицировать злоумышленников.

Применение middleware к маршрутам

Теперь нам нужно применить этот middleware ко всем внешним запросам. У меня есть несколько middleware chains для внешнего трафика. К каждому из них я добавляю новый middleware crowdsec первым в цепочке, чтобы проверка IP-адреса происходила до всех остальных обработок:

http:
  middlewares:
    external-chain:
      chain:
        middlewares:
          - crowdsec
          - rate-limit
          - headers

    external-chain-strict:
      chain:
        middlewares:
          - crowdsec
          - rate-limit-strict
          - headers

    external-chain-no-rate-limit:
      chain:
        middlewares:
          - crowdsec
          - headers

Кроме этого, нужно добавить этот middleware к нашему роутеру заглушке catch-all, чтобы весь грязный трафик на несуществующие адреса тоже анализировался CrowdSec и своевременно банился:

http:
  routers:
    catch-all:
      rule: 'HostRegexp(`.+`) || PathPrefix(`/`)'
      service: noop@internal
      middlewares:
        - crowdsec
        - block-all
      tls: {}
      priority: 1

После изменения динамической конфигурации Traefik подхватит её автоматически — перезапуск не требуется.

Проверка работоспособности

Чтобы убедиться, что всё работает, можно посмотреть текущие решения о блокировке:

cscli decisions list

А также проверить, что bouncer подключён и функционирует:

cscli bouncers list

В колонке "Last API pull" должно отображаться свежее время — это значит, что bouncer регулярно запрашивает решения у CrowdSec.

Регистрация в CrowdSec Console (опционально)

CrowdSec предоставляет бесплатную web-консоль по адресу https://app.crowdsec.net, через которую можно мониторить свой инстанс и, что важнее, подключить community blocklists — общие списки заблокированных IP-адресов от всего сообщества CrowdSec. Это одна из ключевых фишек CrowdSec, которая отличает его от классического Fail2Ban.

Для регистрации вашего инстанса в консоли выполните:

cscli console enroll <ENROLLMENT_KEY>

Ключ можно получить после регистрации на сайте CrowdSec Console. После энролла подтвердите инстанс в web-интерфейсе.

Итог

Вот и всё. Теперь, когда будут происходить запросы извне с IP-адресов, которые уже находятся в базе CrowdSec как вредоносные, они будут блокироваться сразу, не доходя до наших сервисов. Кроме того, если CrowdSec обнаружит в Access-логе подозрительный сценарий поведения — IP-адрес, с которого идёт такой трафик, тоже будет заблокирован.

В сочетании с community blocklists это даёт нам проактивную защиту: мы блокируем не только тех, кто уже атаковал нас, но и тех, кого обнаружили другие участники сообщества CrowdSec по всему миру.