Безопасность сервера 15 мин чтения 2026-10-28

Интеллектуальный WAF BunkerWeb в Docker Compose: комплексная защита веб-приложений от ботов, сканеров уязвимостей и L7-атак на базе Nginx и OWASP CRS

Практическое руководство по развертыванию Web Application Firewall BunkerWeb v1.6.17 в Docker Compose на VDS: защита от L7-атак, поведенческий анти-бот (JS-challenge, капча), автообнаружение контейнеров через Docker Socket Proxy, интеграция с OWASP CRS v4 и автопродление Let's Encrypt SSL.

Инженерная редакция SysKit Проверено инженерами SysKit.ru

Каждый публичный веб-сайт или интернет-магазин ежедневно подвергается тысячам паразитных запросов: автоматические сканеры уязвимостей (sqlmap, nikto, wpscan) ищут бреши в коде, нелегитимные парсеры выгружают цены и перегружают базы данных, а ботнеты предпринимают попытки L7-флуда и подбора паролей. Долгое время стандартом защиты считался облачный прокси Cloudflare, однако в российских реалиях зависимость от зарубежного CDN несет критические риски: регулярные замедления и фильтрация трафика операторами связи из-за протоколов ECH и QUIC, а также риск внезапной блокировки аккаунта. При этом коммерческие российские WAF-сервисы тарифицируются от 15 000 до 50 000 рублей в месяц. Открытый защитный комплекс BunkerWeb (более 11 000 звёзд на GitHub, стабильный релиз v1.6.17) решает эту задачу фундаментально: он разворачивает полноценный Web Application Firewall корпоративного уровня на базе Nginx 1.30, WAF-движка libmodsecurity (ModSecurity v3) и официального набора правил OWASP CRS v4 прямо в Docker Compose на вашем собственном VDS.

1. Архитектура BunkerWeb v1.6: как устроен модульный WAF на базе Nginx 1.30 и OWASP CRS

В отличие от примитивных Nginx-модулей ограничения частоты запросов (rate limiting), BunkerWeb v1.6.17 представляет собой многоуровневый эшелон безопасности (Web Application and API Protection — WAAP), спроектированный по принципу микросервисной изоляции.

Комплекс состоит из пяти ключевых компонентов, взаимодействующих через изолированные сетевые сегменты:

  • Шлюз фильтрации (BunkerWeb Core): фронтальный реверс-прокси на базе Nginx 1.30.6 с интегрированным WAF-движком libmodsecurity (ModSecurity v3 с крипто-бэкендом Mbed TLS). Он принимает входящий HTTP/HTTPS и HTTP/3 (QUIC) трафик на портах 80 и 443, нормализует заголовки, проверяет тело запросов по сигнатурам OWASP Core Rule Set (CRS v4), блокирует SQL-инъекции, XSS, RCE, Path Traversal и выдает браузерам поведенческие проверки (JS-challenge, captcha).
  • Оркестратор конфигураций (BunkerWeb Scheduler): «мозг» системы. Он хранит состояние в базе данных MariaDB, динамически компилирует защитные директивы Nginx, управляет выпуском и автопродлением SSL-сертификатов Let's Encrypt и пушит обновления конфигурации в ядро BunkerWeb без разрыва текущих пользовательских соединений.
  • Служба автообнаружения (BunkerWeb Autoconf & Docker Socket Proxy): динамически опрашивает Docker Engine API. Контейнер подключается к защищенному прокси-шлюзу tecnativa/docker-socket-proxy:v0.5.0, который предоставляет доступ к сокету /var/run/docker.sock строго в режиме «только чтение» и ограничивает вызовы API исключительно чтением контейнеров. Как только вы поднимаете приложение с лейблами bunkerweb.*, WAF автоматически подхватывает его и ставит под защиту.
  • Память состояний и бан-лист (Redis 8): высокоскоростное in-memory хранилище. В Redis в реальном времени сохраняются счетчики запросов для лимитирования частоты (Rate Limiting), временные токены пройденных JS-проверок и глобальные списки заблокированных IP-адресов.
  • База данных и веб-панель (MariaDB 11 & BunkerWeb UI): панель управления с двухфакторной аутентификацией для визуального мониторинга инцидентов, анализа подозрительных запросов, инспекции логов блокировок и ручного управления белыми/черными списками.

💡 Почему связка с Socket Proxy критически важна для безопасности

Монтировать исходный сокет /var/run/docker.sock напрямую в контейнеры WAF, смотрящие в публичный интернет — опасная практика, эквивалентная предоставлению root-доступа к хосту. В архитектуре BunkerWeb служба автоконфигурации вынесена в изолированный бэкенд и общается с демоном Docker исключительно через прокси Docker Socket Proxy, где заблокированы любые команды на создание, остановку или изменение контейнеров хоста.

2. Сравнение BunkerWeb, Cloudflare и классического ModSecurity: почему self-hosted WAF надежнее в РФ

При организации защиты сайтов инженеры чаще всего выбирают между публичным облачным прокси, сложной ручной сборкой ModSecurity и готовым программным WAF.

Критерий BunkerWeb (v1.6.17) Cloudflare WAF Ручной Nginx + ModSec
Устойчивость в РФ 100% (трафик идет напрямую на ваш VDS) Риск замедлений и блокировок ECH/QUIC 100% (собственный сервер)
Стоимость владения 0 ₽ (только стоимость VDS от 450 ₽/мес) Бесплатно базово / от $20–$200/мес за расширенный WAF 0 ₽ (но требует десятков часов на поддержку)
Анти-бот функционал JS-challenge, капча, блокировка спам-сетей Managed Challenge / Turnstile Отсутствует (только статический rate limit)
Интеграция с Docker Автоматическая по labels контейнеров Ручная привязка IP / DNS Ручное редактирование upstream в nginx.conf
Конфиденциальность данных Полная (SSL-сертификаты и трафик не покидают VDS) SSL расшифровывается на серверах третьей стороны Полная (на сервере)

3. Системные требования и сетевая топология: изоляция сетей bw-universe, bw-services и bw-docker

Для корректной работы WAF и надежной изоляции сетевого трафика используется строгая сегментация сетей Docker:

  • bw-services: внешняя сеть взаимодействия с вашими клиентскими веб-сервисами (FastAPI, WordPress, Node.js). Ваши контейнеры не имеют доступа к служебным портам базы данных или сокета Docker;
  • bw-universe (подсеть 10.20.30.0/24): внутренняя служебная сеть для обмена данными между BunkerWeb Core, планировщиком Scheduler и Redis;
  • bw-db: полностью изолированная сеть для взаимодействия с базой данных MariaDB;
  • bw-docker: изолированная сеть между автоконфигуратором Autoconf и прокси-шлюзом Docker Socket Proxy.
Профиль сервера Конфигурация VDS Параметр CRS Пропускная способность
Базовый (Starter) 2 vCPU • 2–4 ГБ RAM • 40 ГБ NVMe USE_MODSECURITY_GLOBAL_CRS=yes До 150–300 rps при глубокой инспекции OWASP CRS, 3–5 небольших сайтов.
Боевой (Production) 4 vCPU • 8 ГБ RAM • 60 ГБ NVMe Стандартный режим + Анти-бот До 1000–2000 rps, интернет-магазины, порталы и API под L7-нагрузкой.
Кластерный (High-Load) 8+ vCPU • 16+ ГБ RAM • 100 ГБ NVMe Multi-Worker ModSecurity v3 3000–5000+ rps с фильтрацией распределенных атак и флуда.

4. Подготовка сервера: системный фаервол UFW, сокет Docker и защита ядра Linux

Для развертывания WAF рекомендуется чистый сервер с Ubuntu 24.04 LTS или Debian 12. Перед запуском контейнеров необходимо настроить фильтрацию трафика на уровне ядра и системного фаервола.

1. Тюнинг сетевого стека ядра Linux (sysctl)

Для устойчивости к SYN-флуду, переполнению очередей сокетов и оптимизации производительности HTTPS добавим параметры защиты в файл /etc/sysctl.d/99-waf-security.conf:

sudo tee /etc/sysctl.d/99-waf-security.conf << 'EOF'
# Защита от SYN-флуда (SYN cookies)
net.ipv4.tcp_syncookies = 1
net.ipv4.tcp_max_syn_backlog = 8192
net.ipv4.tcp_synack_retries = 2

# Оптимизация очередей сетевых пакетов
net.core.somaxconn = 8192
net.core.netdev_max_backlog = 16384

# Защита от спуфинга IP-адресов
net.ipv4.conf.all.rp_filter = 1
net.ipv4.conf.default.rp_filter = 1

# Отключение приема ICMP-редиректов
net.ipv4.conf.all.accept_redirects = 0
net.ipv6.conf.all.accept_redirects = 0
EOF

# Применение параметров
sudo sysctl --system

2. Настройка фаервола UFW

BunkerWeb поддерживает как классический стек TCP (HTTP/1.1 и HTTP/2), так и современный протокол HTTP/3 (QUIC), работающий поверх UDP на порту 443. Откроем соответствующие порты в фаерволе:

sudo ufw default deny incoming
sudo ufw default allow outgoing
sudo ufw allow 22/tcp comment 'SSH'
sudo ufw allow 80/tcp comment 'HTTP BunkerWeb'
sudo ufw allow 443/tcp comment 'HTTPS BunkerWeb'
sudo ufw allow 443/udp comment 'HTTP3 QUIC BunkerWeb'
sudo ufw enable
sudo ufw status

🔒 Полная изоляция служебных портов

Обратите внимание: веб-панель управления bw-ui, база данных MariaDB и кэш Redis не публикуют свои порты наружу. Панель мониторинга будет безопасно проксироваться через сам BunkerWeb по выделенному защищенному поддомену с аутентификацией, что предотвращает прямое сканирование админки ботами.

5. Развертывание боевого стека BunkerWeb v1.6.17 в Docker Compose

Создадим рабочую директорию /opt/bunkerweb и файл окружения .env для хранения паролей к базе данных:

sudo mkdir -p /opt/bunkerweb
cd /opt/bunkerweb

# Генерация надежного пароля для MariaDB
DB_PASS=$(openssl rand -hex 16)
cat << EOF > .env
BW_DB_PASSWORD=${DB_PASS}
EOF

chmod 600 .env

Сформируем боевой файл /opt/bunkerweb/docker-compose.yml со строгими ограничениями вычислительных ресурсов (cgroups deploy.resources.limits и mem_limit) для стабильной работы под нагрузкой:

x-bw-ui-env: &bw-ui-env
  AUTOCONF_MODE: "yes"
  DATABASE_URI: "mariadb+pymysql://bunkerweb:${BW_DB_PASSWORD}@bw-db:3306/db"

services:
  bunkerweb:
    image: bunkerity/bunkerweb:1.6.17
    restart: unless-stopped
    ports:
      - "80:8080/tcp"
      - "443:8443/tcp"
      - "443:8443/udp"
    labels:
      - "bunkerweb.INSTANCE=yes"
    environment:
      AUTOCONF_MODE: "yes"
      API_WHITELIST_IP: "127.0.0.0/8 10.20.30.0/24"
      USE_MODSECURITY_GLOBAL_CRS: "yes"
    networks:
      - bw-universe
      - bw-services
    deploy:
      resources:
        limits:
          cpus: "1.5"
          memory: 1024M
    mem_limit: 1024m
    cpus: 1.5

  bw-scheduler:
    image: bunkerity/bunkerweb-scheduler:1.6.17
    restart: unless-stopped
    environment:
      <<: *bw-ui-env
      BUNKERWEB_INSTANCES: ""
      SERVER_NAME: ""
      API_WHITELIST_IP: "127.0.0.0/8 10.20.30.0/24"
      MULTISITE: "yes"
      UI_HOST: "http://bw-ui:7000"
      USE_REDIS: "yes"
      REDIS_HOST: "redis"
    volumes:
      - bw-storage:/data
    networks:
      - bw-universe
      - bw-db
    deploy:
      resources:
        limits:
          cpus: "1.0"
          memory: 512M
    mem_limit: 512m
    cpus: 1.0

  bw-autoconf:
    image: bunkerity/bunkerweb-autoconf:1.6.17
    restart: unless-stopped
    depends_on:
      - bw-docker
    environment:
      <<: *bw-ui-env
      DOCKER_HOST: "tcp://bw-docker:2375"
    networks:
      - bw-universe
      - bw-docker
      - bw-db
    deploy:
      resources:
        limits:
          cpus: "0.5"
          memory: 256M
    mem_limit: 256m
    cpus: 0.5

  bw-docker:
    image: tecnativa/docker-socket-proxy:v0.5.0
    restart: unless-stopped
    volumes:
      - /var/run/docker.sock:/var/run/docker.sock:ro
    environment:
      CONTAINERS: "1"
      LOG_LEVEL: "warning"
    networks:
      - bw-docker
    deploy:
      resources:
        limits:
          cpus: "0.3"
          memory: 128M
    mem_limit: 128m
    cpus: 0.3

  bw-ui:
    image: bunkerity/bunkerweb-ui:1.6.17
    restart: unless-stopped
    environment:
      <<: *bw-ui-env
    volumes:
      - bw-ui-data:/data
    networks:
      - bw-universe
      - bw-db
    deploy:
      resources:
        limits:
          cpus: "0.8"
          memory: 512M
    mem_limit: 512m
    cpus: 0.8

  bw-db:
    image: mariadb:11
    restart: unless-stopped
    command: --max-allowed-packet=67108864
    environment:
      MYSQL_RANDOM_ROOT_PASSWORD: "yes"
      MYSQL_DATABASE: "db"
      MYSQL_USER: "bunkerweb"
      MYSQL_PASSWORD: "${BW_DB_PASSWORD}"
    volumes:
      - bw-data:/var/lib/mysql
    networks:
      - bw-db
    deploy:
      resources:
        limits:
          cpus: "0.8"
          memory: 512M
    mem_limit: 512m
    cpus: 0.8

  redis:
    image: redis:8-alpine
    restart: unless-stopped
    command: >
      redis-server
      --maxmemory 256mb
      --maxmemory-policy volatile-lru
      --save 60 1000
      --appendonly yes
    volumes:
      - redis-data:/data
    networks:
      - bw-universe
    deploy:
      resources:
        limits:
          cpus: "0.5"
          memory: 256M
    mem_limit: 256m
    cpus: 0.5

volumes:
  bw-data:
  bw-storage:
  redis-data:
  bw-ui-data:

networks:
  bw-universe:
    name: bw-universe
    ipam:
      driver: default
      config:
        - subnet: 10.20.30.0/24
  bw-services:
    name: bw-services
  bw-db:
    name: bw-db
  bw-docker:
    name: bw-docker

Запустите защитный стек в фоновом режиме:

docker compose up -d
docker compose ps

Через 20–30 секунд все компоненты WAF синхронизируются через Redis и MariaDB, после чего стек готов принимать под защиту любые веб-сервисы.

6. Безопасное подключение веб-приложений через Docker Labels: маршрутизация и SSL

Одно из главных преимуществ BunkerWeb с модулем bw-autoconf — работа по модели Edge-роутеров вроде Traefik v3. Вам больше не нужно вручную редактировать файлы nginx.conf и перезагружать веб-сервер при добавлении каждого нового сайта.

1. Пример манифеста клиентского приложения (FastAPI + WAF)

Чтобы поставить любое приложение под защиту WAF, достаточно подключить его контейнер к внешней сети bw-services и прописать лейблы в секции labels:

services:
  myapi:
    image: python:3.12-slim
    command: uvicorn main:app --host 0.0.0.0 --port 8000
    restart: unless-stopped
    networks:
      - bw-services
    deploy:
      resources:
        limits:
          cpus: "1.0"
          memory: 512M
    mem_limit: 512m
    cpus: 1.0
    labels:
      - "bunkerweb.SERVER_NAME=api.example.com"
      - "bunkerweb.USE_REVERSE_PROXY=yes"
      - "bunkerweb.REVERSE_PROXY_URL=/"
      - "bunkerweb.REVERSE_PROXY_HOST=http://myapi:8000"
      - "bunkerweb.AUTO_LETS_ENCRYPT=yes"
      - "bunkerweb.USE_MODSECURITY=yes"
      - "bunkerweb.USE_MODSECURITY_CRS=yes"
      - "bunkerweb.USE_LIMIT_REQ=yes"
      - "bunkerweb.LIMIT_REQ_RATE=25r/s"
      - "bunkerweb.LIMIT_REQ_BURST=50"

networks:
  bw-services:
    external: true
    name: bw-services

Как только контейнер стартует, bw-autoconf обнаружит его через Docker Socket Proxy, планировщик bw-scheduler сгенерирует защитную конфигурацию, а ядро BunkerWeb автоматически запросит бесплатный сертификат Let's Encrypt и настроит редирект с HTTP на HTTPS. Корректность цепочки шифрования можно мгновенно проверить через онлайн-тест SSL.

2. Подключение защищенного доступа к веб-панели BunkerWeb UI

Чтобы безопасно открывать дашборд управления (например, по адресу waf.example.com), настроим для него отдельный виртуальный хост прямо через переменные окружения планировщика bw-scheduler:

      # Добавление в environment сервиса bw-scheduler:
      waf.example.com_SERVER_NAME: "waf.example.com"
      waf.example.com_USE_REVERSE_PROXY: "yes"
      waf.example.com_REVERSE_PROXY_URL: "/"
      waf.example.com_REVERSE_PROXY_HOST: "http://bw-ui:7000"
      waf.example.com_AUTO_LETS_ENCRYPT: "yes"

Примените изменения командой docker compose up -d. После этого панель администрирования станет доступна по защищенному протоколу HTTPS.

7. Настройка поведенческого анти-бота: JS-challenge, капча и защита от парсеров без Cloudflare

Традиционный Rate Limiting защищает только от банального флуда, но бессилен против распределенных парсеров, которые меняют IP-адреса через пулы резидентных прокси. BunkerWeb предоставляет встроенный модуль поведенческого анализа Antibot.

1. Активация невидимого JavaScript Challenge

При включении режима USE_ANTIBOT=javascript при первом обращении к сайту BunkerWeb возвращает легковесную страницу с криптографическим JS-испытанием. Настоящий браузер пользователя выполняет вычисление за 100–150 мс, сохраняет выданный защищенный cookie-токен и бесшовно перенаправляется на целевую страницу:

    labels:
      - "bunkerweb.USE_ANTIBOT=javascript"
      - "bunkerweb.ANTIBOT_TIMEOUT=86400" # Токен валиден 24 часа

Любой автоматический парсер на базе cURL, Python Requests или стандартных библиотек не умеет исполнять JavaScript и немедленно отсекается, даже не достигая бэкенда вашего приложения.

2. Режим капчи (Captcha Challenge) для критических маршрутов

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

    labels:
      - "bunkerweb.USE_ANTIBOT=captcha"

3. Белые списки для поисковых ботов (Яндекс и Google) через Reverse DNS (rDNS)

Чтобы поведенческий анти-бот не заблокировал индексацию сайта поисковыми роботами, в BunkerWeb предусмотрен надежный механизм криптографической верификации обратного DNS (Forward-Confirmed Reverse DNS — FCrDNS).

В отличие от уязвимой проверки заголовка User-Agent (который любой вредоносный скрипт может подделать за одну строчку кода), директива WHITELIST_RDNS заставляет WAF выполнять PTR-запрос к IP-адресу клиента и проверять его подлинность по официальным доменным зонам поисковых систем:

    labels:
      # Пропуск роботов Яндекс и Google по доверенным суффиксам rDNS
      - "bunkerweb.WHITELIST_RDNS=.googlebot.com .google.com .yandex.ru .yandex.net .yandex.com"
      - "bunkerweb.WHITELIST_RDNS_GLOBAL=yes" # Проверка только для публичных глобальных IP

Проверить отсутствие попадания IP вашего сервера в базы спам-сетей можно через проверку DNSBL.

Рекомендуемые VDS-провайдеры

Отказоустойчивые сервера с быстрыми NVMe и каналом до 1 Гбит/с

Выбор редакции
⚡

Timeweb Cloud — Быстрые NVMe VDS с защитой от DDoS

Высокочастотные процессоры с базовой защитой от сетевых атак для эффективной фильтрации трафика WAF-модулями ModSecurity v3 и Nginx.

Конфигурация
2 vCPU 3.3 ГГц • 4 ГБ RAM • 50 ГБ NVMe • Трафик без лимита
Премиум Tier III
🔷

Selectel — Корпоративные серверы для критических веб-сервисов

Надежная сетевая инфраструктура уровня Tier III с гарантированной полосой пропускания и резервированием каналов связи.

Конфигурация
2 vCPU • 4 ГБ RAM • 60 ГБ NVMe • Защита от DDoS
Быстрый старт
🟠

Beget — Доступные серверы для защиты сайтов и API

Удобная панель управления, моментальная установка Ubuntu 24.04 LTS и посекундная тарификация вычислительных ресурсов.

Конфигурация
2 vCPU 3.0 ГГц • 2 ГБ RAM • 30 ГБ NVMe • Бесплатные бэкапы

8. Настройка правил WAF и OWASP CRS: тюнинг ложных срабатываний для WordPress, Next.js и REST API

По умолчанию набор правил OWASP Core Rule Set (CRS v4) работает в строгом режиме инспекции запросов. На популярных CMS (WordPress, Bitrix) или современных API/SPA-сервисах (FastAPI, Next.js) это может вызывать ложные срабатывания (False Positives) при передаче валидного JSON, редактировании статей блога или сохранении настроек.

1. Включение официальных плагинов совместимости CRS

BunkerWeb v1.6 нативно поддерживает архитектуру OWASP CRS Plugins. Для отключения заведомо конфликтующих сигнатур под конкретный движок достаточно активировать плагин правил через лейблы:

    labels:
      # Включение механизма плагинов OWASP CRS
      - "bunkerweb.USE_MODSECURITY_CRS_PLUGINS=yes"
      # Подключение плагина исключений правил для WordPress (или nextcloud, drupal)
      - "bunkerweb.MODSECURITY_CRS_PLUGINS=wordpress-rule-exclusions"

Плагин wordpress-rule-exclusions автоматически добавляет необходимые директивы tx.crs_exclusions_wordpress=1 на первой фазе обработки, гарантируя бесперебойную работу REST API Gutenberg и медиабиблиотеки без снижения общего уровня защиты.

2. Подавление ложных правил ModSecurity по ID через CUSTOM_CONF

Если легитимный запрос вашего сервиса блокируется с кодом 403 Forbidden, найдите идентификатор сработавшего правила в журнале аудита:

docker compose logs bunkerweb | grep "ModSecurity: Access denied"

В строке ошибки будет зафиксирован код правила, например [id "942100"] (подозрение на SQL-инъекцию при передаче поискового фильтра). В Docker Autoconf отключение конкретных правил выполняется через синтаксис кастомных директив bunkerweb.CUSTOM_CONF_MODSEC_<имя>:

    labels:
      # Подавление конкретного правила CRS по его ID для всего сервиса
      - |
        bunkerweb.CUSTOM_CONF_MODSEC_disable-sql-rule=
        SecRuleRemoveById 942100
      # Либо точечное отключение правила только для заданного пути API:
      # - |
      #   bunkerweb.CUSTOM_CONF_MODSEC_api-path-rule=
      #   SecRule REQUEST_FILENAME "^/api/search" "id:1001,ctl:ruleRemoveById=942100"

9. Защита от L7-флуда и перебора паролей: лимиты запросов, черные списки IP и фильтрация Bad Bots

Для отражения атак перебора паролей (Brute-Force) на формы авторизации и предотвращения L7 HTTP-флуда BunkerWeb задействует связку из модуля Rate Limiting, поведенческого детектора Bad Behavior и черных списков.

1. Тонкая настройка лимитов частоты запросов (Rate Limiting)

Определите базовую частоту запросов и допустимый кратковременный всплеск (burst) для защиты бэкенда от перегрузки:

    labels:
      - "bunkerweb.USE_LIMIT_REQ=yes"
      - "bunkerweb.LIMIT_REQ_RATE=20r/s"
      - "bunkerweb.LIMIT_REQ_BURST=40"

При превышении установленной границы клиент немедленно получает стандартный ответ 429 Too Many Requests.

2. Поведенческий бан источников через модуль Bad Behavior

В отличие от статических списков, модуль Bad Behavior отслеживает генерацию клиентом подозрительных HTTP-ответов (400, 401, 403, 404, 429, 444) в скользящем временном окне. Если сканер или бот накапливает заданное число ошибок, WAF помещает его IP-адрес в бан-лист Redis:

    labels:
      # Включение детектора подозрительного поведения
      - "bunkerweb.USE_BAD_BEHAVIOR=yes"
      - "bunkerweb.BAD_BEHAVIOR_STATUS_CODES=400 401 403 404 429 444"
      # Порог: 10 ошибок за 1 минуту вызывают временный бан
      - "bunkerweb.BAD_BEHAVIOR_THRESHOLD=10"
      - "bunkerweb.BAD_BEHAVIOR_COUNT_TIME=1m"
      # Срок бана: 600 секунд (10 минут) или 1d (сутки)
      - "bunkerweb.BAD_BEHAVIOR_BAN_TIME=600"
      - "bunkerweb.BAD_BEHAVIOR_BAN_SCOPE=service"

3. Черные списки URI и вредоносных ботов (Blacklist)

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

    labels:
      # Включение фильтрации по черным спискам
      - "bunkerweb.USE_BLACKLIST=yes"
      # Блокировка попыток запроса скрытых системных файлов и дампов
      - "bunkerweb.BLACKLIST_URI=^/\\.env ^/\\.git ^/\\.aws ^/\\.config"
      # Подключение внешнего регулярно обновляемого списка вредоносных User-Agent
      - "bunkerweb.BLACKLIST_USER_AGENT_URLS=https://raw.githubusercontent.com/mitchellkrogza/nginx-ultimate-bad-bot-blocker/master/_generator_lists/bad-user-agents.list"

Если требуется заблокировать сетевых сканеров на уровне пакетного фильтра Linux ещё до обработки веб-сервером, настройте связку по нашему руководству по настройке Fail2ban и UFW.

10. Резервное копирование конфигурации, SSL-сертификатов и базы данных MariaDB

Все рабочее состояние защитного комплекса состоит из служебной базы MariaDB (пользователи, виртуальные хосты, параметры), конфигурационных файлов и Docker-тома bw-storage, где хранятся выпущенные SSL-сертификаты Let's Encrypt, сессионные ключи и кэш.

1. Скрипт автоматического резервного копирования WAF

Создадим скрипт /root/backup_bunkerweb.sh для создания целостного архива:

#!/usr/bin/env bash
set -euo pipefail

BACKUP_DIR="/var/backups/bunkerweb"
TIMESTAMP=$(date +"%Y%m%d_%H%M%S")
mkdir -p "${BACKUP_DIR}"

echo "[$(date)] Старт резервного копирования BunkerWeb WAF..."

# 1. Дамп базы данных MariaDB из запущенного контейнера
DB_CONTAINER=$(docker ps -q -f name=bunkerweb-bw-db-1 | head -n 1)
if [[ -z "${DB_CONTAINER}" ]]; then
  # Альтернативный поиск по образу
  DB_CONTAINER=$(docker ps -q -f ancestor=mariadb:11 | head -n 1)
fi

# Получение пароля базы данных из файла .env
ENV_FILE="/opt/bunkerweb/.env"
if [[ -f "${ENV_FILE}" ]]; then
  BW_DB_PASSWORD=$(grep '^BW_DB_PASSWORD=' "${ENV_FILE}" | cut -d '=' -f2)
else
  echo "[ОШИБКА] Файл .env не найден в /opt/bunkerweb!" >&2
  exit 1
fi

docker exec "${DB_CONTAINER}" mariadb-dump -u bunkerweb -p"${BW_DB_PASSWORD}" db > "${BACKUP_DIR}/bw_db_${TIMESTAMP}.sql"

# 2. Горячая архивация тома bw-storage с SSL-сертификатами Let's Encrypt
BW_STORAGE_VOL=$(docker volume ls -q -f name=bw-storage | head -n 1)
if [[ -z "${BW_STORAGE_VOL}" ]]; then
  echo "[ОШИБКА] Том bw-storage не найден!" >&2
  exit 1
fi

docker run --rm \
  -v "${BW_STORAGE_VOL}:/data:ro" \
  -v "${BACKUP_DIR}:/backup" \
  alpine tar -czf "/backup/bw_storage_${TIMESTAMP}.tar.gz" -C /data .

# 3. Упаковка конфигураций .env/compose, дампа БД и архива сертификатов в единый файл
tar -czf "${BACKUP_DIR}/bunkerweb_full_${TIMESTAMP}.tar.gz" \
    -C /opt/bunkerweb .env docker-compose.yml \
    -C "${BACKUP_DIR}" "bw_db_${TIMESTAMP}.sql" "bw_storage_${TIMESTAMP}.tar.gz"

# Удаление промежуточных файлов
rm -f "${BACKUP_DIR}/bw_db_${TIMESTAMP}.sql" "${BACKUP_DIR}/bw_storage_${TIMESTAMP}.tar.gz"

# 4. Проверка успешности создания и ненулевого размера
if [[ ! -s "${BACKUP_DIR}/bunkerweb_full_${TIMESTAMP}.tar.gz" ]]; then
  echo "[ОШИБКА] Резервная копия пуста или не была создана!" >&2
  exit 1
fi

chmod 600 "${BACKUP_DIR}/bunkerweb_full_${TIMESTAMP}.tar.gz"

# 5. Ротация: удаление локальных бэкапов старше 14 дней
find "${BACKUP_DIR}" -name "bunkerweb_full_*.tar.gz" -type f -mtime +14 -delete

echo "[$(date)] Резервная копия успешно создана: ${BACKUP_DIR}/bunkerweb_full_${TIMESTAMP}.tar.gz"

Сделайте скрипт исполняемым и добавьте ночную задачу в планировщик cron (ежедневно в 04:00):

sudo chmod +x /root/backup_bunkerweb.sh
# В crontab: 00 04 * * * /root/backup_bunkerweb.sh >> /var/log/bunkerweb_backup.log 2>&1

11. Чек-лист готовности WAF BunkerWeb к продакшен-эксплуатации

Перед переводом продуктовых сайтов под защиту BunkerWeb сверьте параметры по ключевым стандартам надежности и отказоустойчивости:

Параметр Рекомендуемое значение Инженерный смысл
Доступ к сокету Docker Через Socket Proxy (v0.5.0, ro) Исключает root-эскалацию и побег из контейнера при компрометации веб-сервисов.
Порты MariaDB и Redis Не опубликованы наружу Служебные хранилища доступны только внутри изолированных сетей Docker (bw-universe, bw-db).
Ограничение ресурсов (cgroups) Заданы mem_limit и cpus Предотвращает отказ операционной системы по OOM Killer при всплесках трафика.
Поведенческий анти-бот USE_ANTIBOT=javascript Отсекает автоматические скраперы и скрипты без полноценного браузерного JS-движка.
Поисковые роботы WHITELIST_RDNS (.yandex, .google) Гарантирует индексацию через криптографическую проверку PTR/FCrDNS без подделки User-Agent.
Резервное копирование Дамп БД + том bw-storage Позволяет восстановить полный контур WAF и SSL-сертификаты за считанные минуты.

🛡️ Надежная инфраструктура для WAF и защищенных веб-сервисов

Эффективная работа анализатора OWASP CRS и анти-бота требует стабильных процессоров и быстрой памяти. Запустите собственный защитный комплекс BunkerWeb на скоростном VDS с защитой от сетевого флуда.

Инструменты SysKit по теме статьи

Бесплатные утилиты для проверки и диагностики вашего сервера

Вопросы и ответы (FAQ)

Популярные вопросы вебмастеров и сисадминов по данной теме

Сколько оперативной памяти требуется серверу для работы BunkerWeb под нагрузкой?
В минимальной конфигурации с включенной оптимизацией USE_MODSECURITY_GLOBAL_CRS=yes ядро BunkerWeb, база MariaDB, планировщик и Redis суммарно потребляют около 400–600 МБ RAM. Это позволяет запускать WAF на тарифах от 2 ГБ RAM. Для нагруженных проектов с десятками сайтов, анти-ботом и потоком свыше 500 rps рекомендуется сервер с 4–8 ГБ оперативной памяти.
Может ли включение JS-challenge повредить индексации сайта поисковыми роботами Яндекс и Google?
Нет, при условии настройки директивы bunkerweb.WHITELIST_RDNS=.googlebot.com .google.com .yandex.ru .yandex.net .yandex.com. BunkerWeb выполняет проверку подлинности роботов через механизм Forward-Confirmed Reverse DNS (FCrDNS), подтверждая принадлежность IP-адресов официальным подсетям Yandex и Google, и пропускает их к контенту напрямую без показа JavaScript-испытания и капчи.
Как восстановить доступ к сайту, если правила WAF ложно блокируют легитимный запрос пользователя?
Для стандартных CMS (WordPress, Nextcloud) достаточно включить официальный плагин правил bunkerweb.USE_MODSECURITY_CRS_PLUGINS=yes и bunkerweb.MODSECURITY_CRS_PLUGINS=wordpress-rule-exclusions. Если же точечно блокируется ваш REST API, найдите в логах строку с кодом правила [id "XXXXXX"] и добавьте директиву bunkerweb.CUSTOM_CONF_MODSEC_disable-rule=SecRuleRemoveById XXXXXX прямо в секцию labels сервиса в docker-compose.yml.

Читайте также в блоге SysKit

Смежные руководства и полезные технические статьи