metalnikovg.ru
MetalnikovG.ru

Повышение безопасности Docker с помощью CrowdSec и Traefik

Banner.png
Опубликовано
//
5 мин. чтения

CrowdSec — это бесплатный, современный и совместный механизм обнаружения угроз, связанный с глобальной сетью репутации IP-адресов. Он основан на философии fail2ban, но совместим с IPv6 и в 60 раз быстрее, так как написан на Go. CrowdSec разработан для современных инфраструктур на основе облака / контейнеров / виртуальных машин. После обнаружения вы можете устранить угрозы с помощью различных баунсеров (блокировка брандмауэра, nginx http 403, Captcha и т. д.), в то время как агрессивный IP-адрес может быть отправлен в CrowdSec для курирования, прежде чем будет распространен среди всех пользователей для дальнейшего повышения безопасности каждого.

Crowdsec состоит из 3 компонентов:

  • Local API (LAPI)
  • CSCLI - консоль управления
  • Bouncer (вышибала)

В этой заметке будет показан пример использования вместе с Traefik

1. Запуск Crowdsec

Запускать Crowdsec будем в docker-контейнере, для этого создадим файл со следующим содержимым:

docker-compose.yaml
---
services:
  crowdsec:
    image: crowdsecurity/crowdsec:latest
    container_name: crowdsec
    environment:
      GID: "${GID-1000}"
      COLLECTIONS: "crowdsecurity/linux crowdsecurity/traefik crowdsecurity/appsec-virtual-patching crowdsecurity/appsec-generic-rules"
      TZ: Europe/Moscow
    volumes:
      - ./acquis.yaml:/etc/crowdsec/acquis.yaml
      - ./db:/var/lib/crowdsec/data/
      - ./config:/etc/crowdsec/
      - /home/<user>/traefik/logs:/var/log/traefik/:ro
    networks:
      - proxy
    security_opt:
      - no-new-privileges:true
    restart: unless-stopped

networks:
  proxy:
    external: true

После этого создаем файл конфигурации acquis.yaml:

acquis.yaml
filenames:
  - /var/log/traefik/*
labels:
  type: traefik

---

listen_addr: 0.0.0.0:7422
appsec_config: crowdsecurity/virtual-patching
name: myAppSecComponent
source: appsec
labels:
  type: appsec

Теперь можем запускать контейнер

docker compose up -d

2. Подключаем плагин в Traefik

В качестве вышибалы будем использовать плагин Crowdsec Bouncer Traefik plugin. Для подключения, откроем файл статической конфигурации Traefik и добавим в конец следующие строки:

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

Перезапускаем контейнер на всякий случай с флагом пересоздания:

docker compose up -d --force-recreate

Проверяем что плагин загрузился в /log/traefik.log

2024-10-11T17:51:26+03:00 INF Loading plugins... plugins=["crowdsec-bouncer-traefik-plugin"]
2024-10-11T17:51:26+03:00 INF Plugins loaded. plugins=["crowdsec-bouncer-traefik-plugin"]

Проверяем что Crowdsec получает метрики из Traefik:

docker exec crowdsec cscli metrics

NOTE

Чтобы crowdsec смог считать логи из traefik, сначала должен быть запущен контейнер crowdsec

3. Подключаем Bouncer:

Для подключение баунсера необходимо получить LAPI-key, для этого используем команду:

docker exec crowdsec cscli bouncers add crowdsecBouncer

Копируем и сохраняем полученный ключ.

Создаем файл динамической конфигурации traefik crowdsec.yml

crowdsec.yml
http:
  middlewares:
    crowdsec:
      plugin:
        crowdsec-bouncer-traefik-plugin:
          enabled: true
          logLevel: INFO
          updateIntervalSeconds: 15
          updateMaxFailure: 0
          defaultDecisionSeconds: 15
          httpTimeoutSeconds: 10
          crowdsecMode: stream
          crowdsecAppsecEnabled: true
          crowdsecAppsecHost: crowdsec:7422
          crowdsecAppsecFailureBlock: true
          crowdsecAppsecUnreachableBlock: true
          crowdsecLapiKey: your-lapi-key  # Replace CrowdSec API key (docker exec crowdsec cscli bouncers add crowdsecBouncer)
          # crowdsecLapiKeyFile: /etc/traefik/cs-privateKey-foo
          crowdsecLapiHost: crowdsec:8080
          crowdsecLapiScheme: http
          forwardedHeadersTrustedIPs:
            - 172.18.0.0/24 # Reverse Proxy IP address
          clientTrustedIPs:
            - 192.168.78.0/24

Вставляем полученный lapi-key в строку crowdsecLapiKey, а в clientTrustedIPs указываем нашу локальную подсеть.

Теперь открываем файл статической конфигурации traefik.yml и добавляем в промежуточный слой - crowdsec@file

traefik.yml
api:
  dashboard: true
  debug: true
entryPoints:
  http:
    address: ":80"
    http:
      middlewares:
        - "crowdsec@file"
      redirections:
        entryPoint:
          to: https
          scheme: https
  https:
    address: ":443"
    http:
      middlewares:
        - "crowdsec@file"

serversTransport:
  insecureSkipVerify: true
providers:
  file:
    directory: /config
    watch: true
  docker:
    endpoint: "unix:///var/run/docker.sock"
    exposedByDefault: false
certificatesResolvers:
  cloudflare:
    acme:
      email: your-email@mail.com #add your email
      storage: acme.json
      dnsChallenge:
        provider: cloudflare
        resolvers:
          - "1.1.1.1:53"
          - "1.0.0.1:53"

log:
  level: "INFO"
  filePath: "/var/log/traefik/traefik.log"
accessLog:
  filePath: "/var/log/traefik/access.log"

Перезапускаем Traefik:

docker compose up -d

4. Автоматическое обновление баз Crowdsec

Для лучшей защиты нам необходимо получать постоянные обновления баз Crowdsec. Чтобы настроить автоматическое обновление баз Crowdsec, воспользуемся cron

crontab -e

Выбираем пункт 1 и вставляем в конец файла строку:

* 3 * * * docker exec crowdsec cscli hub update && docker exec crowdsec cscli hub upgrade
Это означает что локальные базы crowdsec будут обновляться каждые 3 часа.

5. Подключение дашборда

Для визуализации и алертов, Crowdsec предлагает свой онлайн панель управления. Чтоб подключить ее переходим на https://app.crowdsec.net/sign-in и создаем аккаунт. После входа в аккаунт нам предложат подключить наш Crowdsec Engine и дадут готовую команду для этого:

Но так как у нас Crowdsec запущен в docker-контейнере, мы ее немного изменим:

docker exec crowdsec cscli console enroll -e context cm24-----------------kzbi

Возвращаемся а личный кабинет и нажимаем Accept enroll

После этого внизу появится панелька:

Чтобы отобразились алерты надо перезапустить контейнер crowdsec.

6. Прогрессивное увеличение времени бана для Crowdsec

Для динамического увеличения продолжительности бана угрозы обнажаемой crowdsek необходимо изменить в файле /crowdsek/config/profiles.yaml строку параметра:

duration_expr: "Sprintf('%dh', (GetDecisionsCount(Alert.GetValue()) + 1) * 8)"

означает следующее:

  • GetDecisionsCount(Alert.GetValue()) — это функция, которая возвращает количество предыдущих решений (банов) для данного источника (например, IP-адреса).
  • + 1 — добавляет 1 к количеству предыдущих решений, чтобы учитывать текущее решение.
  • * 8 — умножает общее количество решений на 8, что означает, что время бана будет увеличиваться на 8 часа за каждое предыдущее решение.
  • Sprintf('%dh', ...) — форматирует результат в строку, представляющую количество часов.

Подробнее в документации: Format | CrowdSec

7. Команды crowdsec cscli

Для получения статуса системы:

docker exec crowdsec cscli metrics

Список заблокированных

docker exec crowdsec cscli decisions list

Ручная блокировка по IP

docker exec crowdsec cscli decisions add --ip <ip>

Снятие блокировки

docker exec crowdsec cscli decisions delete --ip <ip>

Обновление базы данных выполняется командами:

docker exec crowdsec cscli hub update && docker exec crowdsec cscli hub upgrade

Заключение

Мы настроили защиту нашего сервера с помощью Crowdsec и плагина-баунсера для Traefik. Настроили автоматическое обновление баз и подключили онлайн панель управления.

Спустя какое-то время зайдя в дашборд вы убедитесь в необходимости Crowdsec.

← Предыдущая заметкаCоздание Cloudflare Tunnel
Следующая заметка →Реализация SSO с помощью Authentik