bolt Valebyte VPS от $4/мес — NVMe, запуск за 60 секунд.

Получить VPS arrow_forward
eco Начальный Туториал

CrowdSec на VPS: коллективный fail2ban для SSH, Nginx и Docker

calendar_month Sep 23, 2026 schedule 21 мин. чтения visibility 30 просмотров
CrowdSec на VPS: коллективный fail2ban для SSH, Nginx и Docker
info

Нужен сервер для этого гайда? Мы предлагаем выделенные серверы и VPS в 50+ странах с мгновенной настройкой.

Нужен сервер для этого гайда?

Разверните VPS или выделенный сервер за минуты.

CrowdSec на VPS: коллективный fail2ban для SSH, Nginx и Docker

TL;DR

CrowdSec устанавливается на VPS как демон анализа логов: он обнаруживает подозрительную активность в SSH, Nginx и контейнерах Docker, а затем через firewall-bouncer блокирует вредоносные IP-адреса. В отличие от классического fail2ban, CrowdSec может использовать коллективную репутацию IP, но решение о блокировке и применение санкций остаются на вашем сервере.

  • Для небольшого production-сервера достаточно 2 vCPU, 2–4 ГБ RAM и 40–80 ГБ SSD.
  • Будут настроены SSH, Nginx, Docker-логи и firewall-bouncer для nftables.
  • Для HTTPS используется Caddy с автоматическим получением сертификатов Let’s Encrypt.
  • Конфигурация CrowdSec хранится отдельно от автоматически обновляемых файлов.
  • В конце будут настроены проверка, резервное копирование, обновления и диагностика типичных ошибок.

1. TL;DR

CrowdSec — современная система обнаружения и блокировки атак, которую часто называют коллективным fail2ban. Она читает системные и прикладные логи, применяет сценарии обнаружения и передаёт решения firewall-bouncer. В результате перебор SSH-паролей, сканирование Nginx и часть атак на Docker-сервисы блокируются до того, как злоумышленник получит много попыток.

Ни CrowdSec, ни fail2ban не заменяют обновления, SSH-ключи, минимальные права и правильную публикацию Docker-портов. Основная цель этой инструкции — получить многоуровневую защиту одного VPS без установки отдельной управляющей платформы.

  • Операционная система: Debian 12 или Ubuntu Server 24.04 LTS.
  • CrowdSec: ветка 1.6.x, актуальная стабильная ветка на 2026 год.
  • Reverse proxy: Nginx 1.26+ или Caddy 2.9+; в примере используются оба компонента по разным сценариям.
  • Файрвол: nftables через firewall-bouncer.
  • Docker Engine: актуальная стабильная ветка 27/28, установленная из официального репозитория Docker.

2. Содержание

Инструкция рассчитана на чистый VPS с публичным IPv4-адресом. Команды приведены для Debian 12 и Ubuntu 24.04; названия пакетов и пути в этих системах практически одинаковы.

Если на сервере уже работают Nginx, Docker или fail2ban, перед установкой сохраните их конфигурацию. Особенно важно проверить, какие порты опубликованы Docker-контейнерами: публикация порта через Docker может обходить обычные правила ufw, поэтому для production лучше контролировать доступ на уровне Docker, nftables и reverse proxy.

  1. Сначала создаётся отдельный администратор и ограничивается SSH.
  2. Затем устанавливаются базовые компоненты и CrowdSec.
  3. После этого подключаются коллекции сценариев для Linux, SSH, Nginx и Docker.
  4. Включается firewall-bouncer, который превращает решения CrowdSec в реальные блокировки.
  5. Выполняется тестирование логов, сценариев, firewall и HTTPS.

3. Что мы настраиваем и зачем

Схема: 3. Что мы настраиваем и зачем
Схема: 3. Что мы настраиваем и зачем

Как работает CrowdSec

CrowdSec состоит из нескольких логических частей. Local API хранит решения и принимает события от security engine. Engine читает логи, передаёт строки парсерам и сценариям, а сценарии определяют поведение: перебор паролей, сканирование путей, большое число ошибок или признаки известного exploit-паттерна.

После срабатывания сценария появляется решение, например блокировка IP на четыре часа. Bouncer получает это решение и применяет его к входящему трафику. Для Linux с nftables это обычно отдельная цепочка в netfilter, поэтому веб-серверу не нужно самостоятельно реализовывать блокировку.

Компонент Назначение Что проверять
Security engine Читает логи и запускает сценарии cscli metrics
Парсеры Преобразуют строки журналов в события cscli hub list
Scenarios Определяют подозрительные последовательности cscli scenarios list
Firewall-bouncer Блокирует IP через nftables cscli bouncers list
Central API Публикует и получает коллективную репутацию Статус регистрации и pull

Почему это не просто замена fail2ban

Fail2ban обычно анализирует только локальные логи и создаёт локальное правило блокировки. Это хорошо работает против повторяющихся атак на конкретный сервер. CrowdSec добавляет единый движок сценариев, удобное управление коллекциями и возможность использовать сигналы от других инсталляций через Central API.

Коллективная репутация не означает, что каждый адрес автоматически считается опасным навсегда. Решения имеют тип, источник и срок действия. Администратор может посмотреть решение, удалить его или добавить собственное. Для критичных систем рекомендуется сначала включить наблюдение и проверить false positive, а затем расширять блокировки.

Что будет защищено

  • SSH: перебор паролей, большое количество неуспешных подключений, попытки сканирования.
  • Nginx: массовые запросы к несуществующим путям, подозрительные URL и некоторые известные шаблоны атак.
  • Docker: защита не контейнера сама по себе, а логов приложений и reverse proxy. Если приложение пишет полезные события в stdout, их можно собирать через Docker logging driver или файл.
  • Системный firewall: блокировка IP на уровне ядра, до обработки запросов приложением.

Self-hosted и cloud-managed варианты

Cloud-managed WAF, CDN и security gateway удобны, когда нужно защищать много доменов, распределять трафик по регионам или автоматически фильтровать volumetric DDoS. За это приходится платить ежемесячно, направлять DNS через стороннюю сеть и принимать ограничения провайдера.

Self-hosted CrowdSec на VPS подходит для одного сервера, небольшой команды, private API, Git-сервера, панели администрирования и приложений, где важен полный контроль над логами. При этом VPS не способен остановить крупную DDoS-атаку: если забит канал или виртуальный NIC провайдера, локальный firewall уже не поможет.

4. Какой VPS-конфиг нужен под эту задачу

Схема: 4. Какой VPS-конфиг нужен под эту задачу
Схема: 4. Какой VPS-конфиг нужен под эту задачу

CrowdSec потребляет немного CPU и памяти. Основная нагрузка зависит не от самого агента, а от объёма логов, числа сценариев, скорости запросов Nginx и количества контейнеров. Для SSH и одного сайта требования минимальны; для нескольких приложений нужно учитывать их собственную RAM-потребность.

Сценарий CPU RAM Диск Сеть
SSH и небольшой Nginx 1 vCPU 1 ГБ 20–30 ГБ SSD 100 Мбит/с
Docker, 2–5 сервисов и CrowdSec 2 vCPU 4 ГБ 60–80 ГБ NVMe 1 Гбит/с
Несколько сайтов и CI-задачи 4 vCPU 8 ГБ 100–160 ГБ NVMe 1 Гбит/с

Практический вариант для большинства установок

Для этого руководства разумно взять 2 vCPU, 4 ГБ RAM, 60–80 ГБ NVMe, один публичный IPv4 и порт 1 Гбит/с. Такой запас позволяет одновременно запустить CrowdSec, Nginx или Caddy, Docker Compose и несколько небольших приложений. Если контейнеры используют PostgreSQL, Elasticsearch, GitLab или сборку образов, RAM следует увеличить отдельно.

В качестве одного из вариантов можно взять VPS с такими характеристиками. Важны именно ресурсы, стабильность диска, наличие резервного копирования и возможность задать обратную DNS-запись, а не название конкретного тарифа.

Когда нужен dedicated

Выделенный сервер нужен не из-за самого CrowdSec. Он становится оправданным, если на машине работают базы данных с высоким I/O, десятки контейнеров, CI/CD-воркеры, игровые серверы, большой GitLab, собственная нода блокчейна или несколько виртуальных машин.

Для CrowdSec следует выделять минимум один vCPU и 512 МБ RAM, но на dedicated удобно зарезервировать 2–4 vCPU и 4–8 ГБ RAM под security stack и системные сервисы. Не размещайте единственную копию резервных архивов на том же физическом сервере.

Влияние локации

Локация влияет прежде всего на задержку до пользователей и на юридические требования к данным. Для CrowdSec расстояние до Central API обычно не критично: события анализируются локально. Для web-приложения выбирайте регион ближе к основной аудитории, а для административного VPS учитывайте маршрут от вашего рабочего места.

Проверьте, выдаёт ли провайдер PTR-запись, IPv6, фильтрацию исходящего SMTP и возможность открыть необходимые входящие порты. Отдельно уточните политику по security-сканерам: CrowdSec не должен использоваться для активного сканирования чужих сетей.

5. Подготовка сервера

Вход и создание администратора

Ниже используется имя deploy. Замените его на собственное. Выполняйте первый вход под root только для начальной настройки, а затем используйте sudo. Перед изменением SSH держите текущую сессию открытой и проверяйте новый вход во втором терминале.

# Обновляем индексы пакетов
sudo apt update

# Устанавливаем обновления безопасности и исправления
sudo apt full-upgrade -y

# Создаём отдельного пользователя
sudo adduser deploy

# Разрешаем ему выполнять административные команды
sudo usermod -aG sudo deploy

# Создаём каталог для публичных SSH-ключей
sudo install -d -m 700 -o deploy -g deploy /home/deploy/.ssh

С локального компьютера добавьте публичный ключ. Не копируйте приватный ключ на сервер.

# Выполняется на вашем рабочем компьютере
ssh-copy-id deploy@SERVER_IP

# Проверяем вход новым пользователем в отдельном терминале
ssh deploy@SERVER_IP

Базовые пакеты

# Устанавливаем диагностику, шифрование, редактор и управление репозиториями
sudo apt install -y \
  ca-certificates curl gnupg jq git vim htop lsof unzip \
  apt-transport-https software-properties-common \
  nftables rsyslog logrotate

# Проверяем время и синхронизацию часов
timedatectl status

# Включаем системную синхронизацию времени
sudo timedatectl set-ntp true

SSH hardening

Сначала убедитесь, что вход по ключу работает. После этого отключите парольную аутентификацию и root-вход. Если у вас есть автоматизация, которая всё ещё использует пароль, она перестанет работать после применения файла.

# Создаём отдельный drop-in для sshd
sudo tee /etc/ssh/sshd_config.d/10-hardening.conf >/dev/null <<'EOF'
PermitRootLogin no
PasswordAuthentication no
KbdInteractiveAuthentication no
PubkeyAuthentication yes
MaxAuthTries 3
LoginGraceTime 20
X11Forwarding no
AllowUsers deploy
EOF

# Проверяем синтаксис до перезапуска
sudo sshd -t

# Применяем конфигурацию без закрытия текущих сессий
sudo systemctl reload ssh

Firewall до установки CrowdSec

Откройте только SSH, HTTP и HTTPS. Если SSH работает на другом порту, замените значение в правилах. Не открывайте порты баз данных и Docker-сервисов во внешний интернет без необходимости.

# Включаем nftables при загрузке
sudo systemctl enable --now nftables

# Создаём базовый firewall: loopback, established, SSH и web
sudo tee /etc/nftables.conf >/dev/null <<'EOF'
#!/usr/sbin/nft -f
flush ruleset

table inet filter {
    chain input {
        type filter hook input priority filter; policy drop;

        iifname "lo" accept
        ct state established,related accept
        ct state invalid drop

        ip protocol icmp accept
        ip6 nexthdr ipv6-icmp accept

        tcp dport 22 accept
        tcp dport { 80, 443 } accept
    }

    chain forward {
        type filter hook forward priority filter; policy drop;
    }

    chain output {
        type filter hook output priority filter; policy accept;
    }
}
EOF

# Загружаем правила
sudo nft -f /etc/nftables.conf

# Проверяем активный набор правил
sudo nft list ruleset

Нужен ли fail2ban

В задании fail2ban устанавливается как базовая страховка, но нельзя бездумно запускать два независимых баннера с одинаковыми порогами. Иначе системы могут блокировать адреса каждая по своим правилам, а диагностика станет сложнее. После проверки CrowdSec обычно оставляют только его для SSH и web, а fail2ban выключают либо используют для отдельного приложения.

# Устанавливаем fail2ban как временный или резервный механизм
sudo apt install -y fail2ban

# Создаём безопасный локальный конфиг SSH jail
sudo tee /etc/fail2ban/jail.d/sshd.local >/dev/null <<'EOF'
[sshd]
enabled = true
backend = systemd
port = ssh
maxretry = 6
findtime = 10m
bantime = 10m
EOF

# Перезапускаем fail2ban и смотрим состояние
sudo systemctl enable --now fail2ban
sudo fail2ban-client status sshd

После ввода CrowdSec в эксплуатацию можно отключить этот jail и оставить fail2ban установленным для ручного аварийного включения:

# Отключаем дублирующий SSH-jail после успешной проверки CrowdSec
sudo sed -i 's/^enabled = true/enabled = false/' /etc/fail2ban/jail.d/sshd.local
sudo systemctl restart fail2ban

6. Установка CrowdSec, Nginx и Docker

Схема: 6. Установка CrowdSec, Nginx и Docker
Схема: 6. Установка CrowdSec, Nginx и Docker

Установка CrowdSec

На Debian и Ubuntu используйте официальный репозиторий CrowdSec, а не случайные PPA. Версия пакета может быть новее указанной в статье. В 2026 году ориентируйтесь на стабильную ветку 1.6.x и проверяйте пакет перед фиксацией версии.

# Добавляем официальный signing key CrowdSec
curl -fsSL https://packagecloud.io/crowdsec/crowdsec/gpgkey \
  | sudo gpg --dearmor -o /usr/share/keyrings/crowdsec-archive-keyring.gpg

# Добавляем официальный apt-репозиторий
echo "deb [signed-by=/usr/share/keyrings/crowdsec-archive-keyring.gpg] https://packagecloud.io/crowdsec/crowdsec/debian/ bookworm main" \
  | sudo tee /etc/apt/sources.list.d/crowdsec.list

# Обновляем индексы и устанавливаем CrowdSec 1.6.x
sudo apt update
sudo apt install -y crowdsec

# Включаем сервис и проверяем установленную версию
sudo systemctl enable --now crowdsec
sudo cscli version

На Ubuntu 24.04 замените кодовое имя репозитория на поддерживаемое официальным репозиторием, если текущая запись не подходит. Проверка apt policy crowdsec покажет, откуда взят пакет.

# Показываем источник и доступную версию пакета
apt policy crowdsec

# Проверяем состояние systemd-сервиса
sudo systemctl status crowdsec --no-pager

Установка базовых коллекций

Коллекция — это набор парсеров, сценариев и файлов журналов для конкретного сервиса. Не устанавливайте всё подряд: лишние сценарии увеличивают шум и расход ресурсов.

# Обновляем индекс Hub
sudo cscli hub update

# Устанавливаем сценарии Linux и SSH
sudo cscli collections install crowdsecurity/linux
sudo cscli collections install crowdsecurity/sshd

# Устанавливаем парсеры и сценарии Nginx
sudo cscli collections install crowdsecurity/nginx

# Проверяем установленные коллекции
sudo cscli collections list

Установка firewall-bouncer

Для nftables нужен пакет firewall-bouncer с backend nftables. Название пакета может различаться в зависимости от дистрибутива и репозитория, поэтому сначала найдите доступный пакет.

# Ищем доступные варианты bouncer
apt-cache search crowdsec | grep -i bouncer

# Устанавливаем bouncer для nftables
sudo apt install -y crowdsec-firewall-bouncer-nftables

# Включаем применение решений на firewall
sudo systemctl enable --now crowdsec-firewall-bouncer

# Проверяем состояние bouncer
sudo systemctl status crowdsec-firewall-bouncer --no-pager

Установка Nginx

Nginx нужен для понятного access log и проксирования приложений. Если reverse proxy уже реализован Caddy, Nginx устанавливать не обязательно; в таком случае подключается коллекция для Caddy или журнал приложения. Для основной схемы оставим Nginx.

# Устанавливаем Nginx из системного репозитория
sudo apt install -y nginx

# Запускаем web-сервер и добавляем его в автозагрузку
sudo systemctl enable --now nginx

# Проверяем локальный HTTP-ответ
curl -I http://127.0.0.1

Установка Docker Engine

Для production используйте официальный Docker Engine, а не устаревший пакет docker.io, если вам нужны актуальные Compose plugin и исправления. Версия 27/28 подходит для типовой установки CrowdSec на 2026 год.

# Добавляем ключ официального репозитория Docker
sudo install -m 0755 -d /etc/apt/keyrings
curl -fsSL https://download.docker.com/linux/debian/gpg \
  | sudo gpg --dearmor -o /etc/apt/keyrings/docker.gpg
sudo chmod a+r /etc/apt/keyrings/docker.gpg

# Подключаем репозиторий Docker для Debian 12
echo "deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.gpg] https://download.docker.com/linux/debian bookworm stable" \
  | sudo tee /etc/apt/sources.list.d/docker.list

# Устанавливаем Engine, CLI и Compose plugin
sudo apt update
sudo apt install -y docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin

# Разрешаем deploy работать с Docker без sudo
sudo usermod -aG docker deploy

# Проверяем Docker и Compose
sudo docker version
sudo docker compose version

После добавления группы нужно заново войти в SSH. Группа docker фактически даёт root-права, поэтому не добавляйте в неё случайных пользователей и не монтируйте Docker socket внутрь недоверенных контейнеров.

7. Конфигурация и проверка

Подключение журналов SSH и Nginx

В Debian SSH обычно пишет в journald или в /var/log/auth.log. Nginx по умолчанию использует /var/log/nginx/access.log и /var/log/nginx/error.log. Посмотрите активную конфигурацию CrowdSec: она подскажет, какие acquisition-файлы уже созданы пакетом.

# Показываем источники логов CrowdSec
sudo cscli acquisitions list

# Проверяем наличие системных и Nginx-журналов
sudo ls -l /var/log/auth.log /var/log/nginx/access.log /var/log/nginx/error.log

# Читаем последние сообщения CrowdSec
sudo journalctl -u crowdsec -n 100 --no-pager

Если acquisition-файл не создан, добавьте отдельную конфигурацию. Формат может немного отличаться между версиями, поэтому после изменения всегда проверяйте синтаксис перезапуском сервиса.

# Создаём источник логов Nginx
sudo tee /etc/crowdsec/acquis.d/nginx.yaml >/dev/null <<'EOF'
filenames:
  - /var/log/nginx/access.log
  - /var/log/nginx/error.log
labels:
  type: nginx
EOF

# Создаём источник системного auth.log
sudo tee /etc/crowdsec/acquis.d/sshd.yaml >/dev/null <<'EOF'
filenames:
  - /var/log/auth.log
labels:
  type: syslog
EOF

# Перезапускаем engine после изменения источников
sudo systemctl restart crowdsec

# Проверяем источники ещё раз
sudo cscli acquisitions list

Конфигурация Nginx

Сайт должен проксировать приложение только через loopback или внутреннюю Docker-сеть. Не публикуйте порт приложения напрямую, если доступ к нему должен проходить через Nginx.

# Создаём виртуальный хост для example.com
sudo tee /etc/nginx/sites-available/example.com >/dev/null <<'EOF'
server {
    listen 80;
    listen [::]:80;
    server_name example.com www.example.com;

    access_log /var/log/nginx/example.access.log;
    error_log  /var/log/nginx/example.error.log warn;

    location / {
        proxy_pass http://127.0.0.1:8080;
        proxy_http_version 1.1;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto $scheme;
        proxy_read_timeout 60s;
    }
}
EOF

# Включаем сайт
sudo ln -s /etc/nginx/sites-available/example.com /etc/nginx/sites-enabled/example.com

# Удаляем дефолтный сайт при необходимости
sudo rm -f /etc/nginx/sites-enabled/default

# Проверяем конфигурацию и применяем её
sudo nginx -t
sudo systemctl reload nginx

В production замените домен на настоящий и направьте DNS A-запись на IPv4 VPS. Для IPv6 добавьте AAAA-запись только после проверки, что firewall и приложение корректно обрабатывают IPv6.

HTTPS через Caddy

Если вы не хотите вручную обслуживать сертификаты в Nginx, Caddy может стать единственным reverse proxy. Не запускайте одновременно Caddy и Nginx на портах 80 и 443. Ниже показан отдельный вариант с Docker Compose: остановите Nginx либо назначьте ему внутренний порт.

# Создаём каталог Caddy
sudo mkdir -p /opt/caddy/data /opt/caddy/config
sudo chown -R deploy:deploy /opt/caddy

# Переходим в каталог проекта
cd /opt/caddy

# Создаём файл с reverse proxy и автоматическим HTTPS
cat > Caddyfile <<'EOF'
example.com {
    encode gzip zstd

    reverse_proxy app:8080

    header {
        X-Content-Type-Options nosniff
        X-Frame-Options SAMEORIGIN
        Referrer-Policy strict-origin-when-cross-origin
    }
}
EOF

# Описываем Caddy и приложение в Compose
cat > compose.yaml <<'EOF'
services:
  app:
    image: nginx:1.27-alpine
    restart: unless-stopped
    expose:
      - "8080"

  caddy:
    image: caddy:2.9-alpine
    restart: unless-stopped
    ports:
      - "80:80"
      - "443:443"
    volumes:
      - ./Caddyfile:/etc/caddy/Caddyfile:ro
      - ./data:/data
      - ./config:/config
    depends_on:
      - app
EOF

# Запускаем стек и проверяем контейнеры
docker compose up -d
docker compose ps

В реальном проекте замените тестовый образ приложения на собственный. Caddy сам запросит сертификат, если DNS уже указывает на VPS и входящие 80/443 доступны. Если Nginx остаётся внешним reverse proxy, Caddy должен слушать только внутренний порт, а TLS терминируется в Nginx.

Сбор логов Docker

CrowdSec не должен читать бинарную базу Docker напрямую. Для небольшого сервера проще настроить JSON-файлы Docker и направить их в acquisition. Ограничение размера логов обязательно, иначе один noisy-контейнер может заполнить диск.

# Ограничиваем размер стандартных Docker-логов
sudo mkdir -p /etc/docker
sudo tee /etc/docker/daemon.json >/dev/null <<'EOF'
{
  "log-driver": "json-file",
  "log-opts": {
    "max-size": "10m",
    "max-file": "5"
  }
}
EOF

# Перезапускаем Docker; контейнеры могут кратко прерваться
sudo systemctl restart docker

# Проверяем конфигурацию Docker
docker info --format '{{.LoggingDriver}}'

Коллекция Docker может анализировать события через подходящий парсер, но конкретный формат зависит от версии CrowdSec и приложения. Сначала установите коллекцию и посмотрите её acquisition-файлы:

# Обновляем Hub и устанавливаем коллекцию Docker
sudo cscli hub update
sudo cscli collections install crowdsecurity/docker

# Просматриваем файлы коллекции
sudo find /etc/crowdsec -type f | grep -i docker

# Перезапускаем CrowdSec после установки коллекции
sudo systemctl restart crowdsec

Регистрация bouncer и проверка решений

При установке пакет обычно автоматически создаёт API-ключ bouncer. Если ключ не создан, сгенерируйте его вручную и внесите в конфигурацию bouncer. Не публикуйте этот ключ в Git и не отправляйте его в открытые issue.

# Смотрим зарегистрированные bouncer
sudo cscli bouncers list

# При необходимости создаём новый ключ
sudo cscli bouncers add firewall-local

# Проверяем локальные решения
sudo cscli decisions list

# Смотрим статистику чтения логов и срабатывания сценариев
sudo cscli metrics

Безопасный тест блокировки

Не тестируйте бан с вашего основного рабочего IP: можно потерять доступ. Используйте временный адрес, консоль провайдера или локальный decision с коротким сроком. После теста удалите решение.

# Добавляем тестовый адрес на одну минуту; замените TEST_IP
sudo cscli decisions add --ip TEST_IP --duration 1m --reason "manual-test"

# Проверяем, что решение появилось
sudo cscli decisions list

# Проверяем цепочки CrowdSec в nftables
sudo nft list ruleset | grep -i crowdsec -A 12

# Удаляем тестовое решение
sudo cscli decisions delete --ip TEST_IP

Проверка SSH и HTTP

# Проверяем открытые TCP-порты на самом сервере
sudo ss -lntup

# Проверяем локальный Nginx
curl -I http://127.0.0.1

# Проверяем HTTPS с внешнего компьютера
curl -I https://example.com

# Проверяем сообщения bouncer
sudo journalctl -u crowdsec-firewall-bouncer -n 100 --no-pager

# Проверяем ошибки Nginx за последние строки
sudo tail -n 50 /var/log/nginx/error.log

Настройка уведомлений

Для начала достаточно периодически проверять метрики и systemd-журналы. В production полезно подключить мониторинг: Prometheus node exporter, Uptime Kuma, Zabbix или другой уже используемый инструмент. Не отправляйте в уведомления полные строки логов, если они могут содержать токены, URL с секретами или персональные данные.

8. Бэкапы и обслуживание

Что необходимо сохранять

  • /etc/crowdsec/ — acquisition, локальные настройки и сценарии, которые вы изменяли.
  • /etc/crowdsec/bouncers/ — конфигурация firewall-bouncer.
  • /etc/ssh/, /etc/nginx/, /etc/nftables.conf и конфигурация Caddy.
  • Compose-файлы, Docker secrets-шаблоны и переменные окружения без раскрытия секретов в логах.
  • Данные приложений: базы данных, пользовательские загрузки, сертификаты и persistent volumes.
  • Список пакетов и вывод конфигурации, чтобы восстановить окружение на новом VPS.

Не следует считать Docker image резервной копией данных. Образ можно скачать заново, а содержимое volume, базу данных и ключи — нет. Для PostgreSQL делайте логический dump, а для MySQL или MariaDB используйте соответствующий dump-инструмент до копирования файлов.

Пример дампа PostgreSQL

# Создаём каталог для локальных временных дампов
sudo install -d -m 700 /var/backups/postgres

# Выполняем сжатый дамп конкретной базы
sudo -u postgres pg_dump -Fc appdb \
  > /var/backups/postgres/appdb-$(date +%F).dump

# Удаляем локальные дампы старше семи дней
sudo find /var/backups/postgres -type f -mtime +7 -delete

Restic во внешний S3

Резервные копии должны находиться вне VPS: в S3-совместимом объектном хранилище, на отдельном сервере или в двух независимых местах. Секреты Restic передавайте через environment file с правами 600. В примере используется S3-совместимое хранилище; URL и bucket замените на свои.

# Устанавливаем restic
sudo apt install -y restic

# Создаём файл секретов с закрытыми правами
sudo tee /root/.restic-env >/dev/null <<'EOF'
export AWS_ACCESS_KEY_ID='CHANGE_ME'
export AWS_SECRET_ACCESS_KEY='CHANGE_ME'
export RESTIC_REPOSITORY='s3:https://s3.example.net/server-backups'
export RESTIC_PASSWORD='CHANGE_ME_LONG_RANDOM_PASSWORD'
EOF
sudo chmod 600 /root/.restic-env

# Инициализируем репозиторий один раз
sudo bash -c 'source /root/.restic-env && restic init'

Не включайте в архив каталоги с временными файлами и Docker-кэшем. Секретный файл Restic нельзя бэкапить в том же виде вместе с архивом: храните пароль менеджере секретов или в офлайн-копии.

# Создаём скрипт резервного копирования
sudo tee /usr/local/sbin/backup-server.sh >/dev/null <<'EOF'
#!/usr/bin/env bash
set -Eeuo pipefail

source /root/.restic-env

restic backup \
  /etc/crowdsec \
  /etc/nginx \
  /etc/ssh \
  /etc/docker \
  /etc/nftables.conf \
  /opt \
  /var/backups/postgres \
  --tag "$(hostname)-$(date +%F)"

restic forget \
  --keep-daily 7 \
  --keep-weekly 4 \
  --keep-monthly 6 \
  --prune
EOF

# Разрешаем запускать скрипт только root
sudo chmod 700 /usr/local/sbin/backup-server.sh

# Выполняем первый backup вручную
sudo /usr/local/sbin/backup-server.sh

# Проверяем список snapshots
sudo bash -c 'source /root/.restic-env && restic snapshots'

Cron и проверка восстановления

# Запускаем backup ежедневно в 03:15
echo '15 3   * root /usr/local/sbin/backup-server.sh >> /var/log/backup-server.log 2>&1' \
  | sudo tee /etc/cron.d/backup-server

# Проверяем структуру cron-файла
sudo chmod 644 /etc/cron.d/backup-server
sudo cat /etc/cron.d/backup-server

# Тестируем восстановление одного файла в отдельный каталог
sudo mkdir -p /tmp/restic-restore
sudo bash -c 'source /root/.restic-env && restic restore latest --target /tmp/restic-restore --include /etc/crowdsec/config.yaml'

Бэкап считается рабочим только после восстановления. Раз в месяц создайте временный VPS или отдельный каталог и проверьте, что конфигурация читается, база импортируется, а Docker Compose запускается с восстановленными переменными.

Обновления

CrowdSec, bouncer и парсеры можно обновлять без остановки пользовательских приложений, но изменение firewall всегда нужно проверять. Перед обновлением сохраните текущие решения и конфигурацию. Для одного VPS лучше выбрать короткое maintenance window, особенно если обновляется ядро, Docker или Nginx.

# Сохраняем список установленных пакетов
dpkg-query -W -f='${binary:Package}\t${Version}\n' \
  | sudo tee /var/backups/packages-$(date +%F).txt

# Обновляем пакеты
sudo apt update
sudo apt upgrade -y

# Обновляем коллекции CrowdSec из Hub
sudo cscli hub update
sudo cscli hub upgrade

# Проверяем сервисы после обновления
sudo systemctl --failed
sudo systemctl status crowdsec crowdsec-firewall-bouncer nginx --no-pager

Для нескольких серверов используйте staged rollout: сначала обновите один тестовый VPS, проверьте метрики и логи, затем остальные. Rolling update возможен только при наличии второго reverse proxy или балансировщика. Один сервер без резервного узла требует обычного окна обслуживания.

9. Troubleshooting и FAQ

Почему CrowdSec не видит события SSH?

Проверьте, куда пишет sshd: journalctl -u ssh, /var/log/auth.log или другой файл. Затем выполните sudo cscli acquisitions list и убедитесь, что источник имеет правильный label. Проверьте права чтения и перезапустите CrowdSec. Если используется journald без файла, настройте acquisition для systemd в соответствии с документацией установленной версии, а не добавляйте несуществующий путь.

Решения создаются, но IP не блокируются. Что проверить?

Сначала выполните sudo cscli bouncers list и убедитесь, что bouncer зарегистрирован и имеет недавний последний pull. Затем проверьте systemctl status crowdsec-firewall-bouncer и наличие цепочек CrowdSec в nft list ruleset. Частая причина — установлен iptables-вариант bouncer при системе на nftables. Установите правильный пакет и проверьте backend в конфигурации bouncer.

Какой VPS-конфиг минимально подойдёт?

Для одного SSH и небольшого Nginx технически хватит 1 vCPU, 1 ГБ RAM и 20–30 ГБ SSD. Практический минимум для Docker и нескольких сервисов — 2 vCPU, 4 ГБ RAM и 60 ГБ NVMe. Нужен публичный IPv4, стабильная сеть и возможность открыть TCP 22, 80 и 443. Если планируются база данных, CI-сборки или тяжёлые контейнеры, ориентируйтесь на 8 ГБ RAM и выше.

Что выбрать — VPS или dedicated для этой задачи?

Для CrowdSec, SSH, Nginx и нескольких контейнеров достаточно VPS. Dedicated оправдан не самим security stack, а высокой нагрузкой приложений, большим объёмом RAM, интенсивным дисковым I/O или требованием к физической изоляции. Если VPS-провайдер даёт гарантированные ресурсы, отдельный диск и резервные копии, он будет проще и дешевле в обслуживании. Dedicated выбирайте при устойчивой нагрузке, а не «на всякий случай».

Почему Docker-контейнер доступен из интернета, хотя порт не разрешён в nftables?

Docker изменяет правила forwarding и NAT, поэтому опубликованный порт может обходить ожидаемую модель фильтрации. Лучшее исправление — не публиковать порт наружу: используйте expose и подключайте контейнер к внутренней сети reverse proxy. Если публикация обязательна, добавьте явные правила в цепочки Docker или используйте отдельную архитектуру firewall, предварительно проверив её на тестовом сервере.

Как убрать ошибочную блокировку своего IP?

Посмотрите решения командой sudo cscli decisions list. Удалите конкретный адрес через sudo cscli decisions delete --ip YOUR_IP. Если адрес снова появляется, найдите источник в метриках и логах. Причиной может быть неправильный reverse proxy: CrowdSec видит IP балансировщика вместо клиента, либо ваш мониторинг генерирует слишком много запросов. Настройте trusted proxies только для известных адресов и не доверяйте произвольному заголовку X-Forwarded-For.

Можно ли оставить fail2ban и CrowdSec одновременно?

Технически можно, но одинаковые SSH-jails создают дублирование и усложняют расследование. Для простой схемы оставьте CrowdSec единственным источником блокировок, а fail2ban отключите. Одновременная работа оправдана, если fail2ban защищает отдельный сервис, для которого нет подходящего CrowdSec-парсера. В таком случае разделите jails, сроки блокировки и цепочки firewall, затем документируйте, какой компонент отвечает за каждый тип событий.

HTTPS не выпускается Caddy. Что проверить?

Убедитесь, что DNS A и AAAA указывают на правильный сервер, а порты 80 и 443 доступны извне. Если AAAA существует, но IPv6 не настроен, ACME-клиент может обращаться к неправильному адресу: временно исправьте IPv6 или настройте его корректно. Проверьте логи docker compose logs caddy, убедитесь, что другой процесс не занял порты, и не запускайте одновременно внешний Nginx и Caddy на одном socket.

Диск быстро заполняется логами. Как исправить?

Проверьте размер каталогов командами sudo du -xhd1 /var/log /var/lib/docker. Настройте logrotate для Nginx, лимиты Docker max-size и max-file, а также retention для journald. Не удаляйте активные логи вручную: после ротации отправьте сервису reload. Затем проверьте, что CrowdSec читает новый файл и не потерял позицию после ротации.

10. Выводы и следующие шаги

Схема: 10. Выводы и следующие шаги
Схема: 10. Выводы и следующие шаги

На VPS теперь работают CrowdSec engine, сценарии для SSH и Nginx, firewall-bouncer на nftables и контролируемые Docker-сервисы. Вход по SSH ограничен ключами, web-трафик проходит через reverse proxy, а конфигурации и данные подготовлены к резервному копированию.

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

  1. Проверьте false positive на реальном трафике и добавьте исключения только для доверенных сетей.
  2. Настройте staged updates, внешний backup и ежемесячный disaster recovery test.
  3. Для нескольких доменов или серверов добавьте внешний WAF/CDN, не заменяя им локальную защиту CrowdSec.

Был ли этот гайд полезен?

Ваш отзыв помогает нам улучшать гайды.

Поделиться записью:

Отправьте гайд тому, кому он может пригодиться.

Telegram VKVK WhatsApp Facebook LinkedIn XX

crowdsec на vps: коллективный fail2ban для ssh, nginx и docker
support_agent
Valebyte Support
Usually replies within minutes
Hi there!
Send us a message and we'll reply as soon as possible.