Перейти к содержанию

Деплой Docker‑образа WAF‑ноды в AWS

Данная инструкция содержит краткое руководство по деплою Docker‑образа WAF‑ноды (NGINX) с помощью облачной платформы AWS. Для деплоя Docker-образа используется сервис Amazon Elastic Container Service (Amazon ECS).

Ограничение инструкции

В данной инструкции не описана конфигурация для балансировки нагрузки и автоматического масштабирования WAF‑нод. Чтобы выполнить конфигурацию самостоятельно, рекомендуем ознакомиться с соответствующими шагами в инструкции AWS.

Требования

  • Аккаунт AWS и данные пользователя с ролью admin

  • Установленный и настроенный AWS CLI (вы можете использовать любую версию AWS CLI: 1 или 2)

  • Доступ к аккаунту с ролью Деплой или Администратор и отключенная двухфакторная аутентификация в Консоли управления Валарм для RU‑облака или EU‑облака

Способы конфигурации Docker-контейнера с WAF-нодой

При деплое необходимо передать в Docker‑контейнер параметры WAF‑ноды одним из способов:

  • Через доступные переменные окружения. С помощью переменных окружения задаются базовые настройки WAF-ноды. Большинство доступных директив не могут быть переданы через переменные.

  • В примонтированном конфигурационном файле. С помощью конфигурационного файла можно выполнить полную настройку WAF-ноды, используя любые доступные директивы. При этом способе конфигурации параметры для подключения к Облаку Валарм передаются в переменных окружения.

Деплой контейнера с настройкой WAF-ноды через переменные окружения

Для деплоя контейнера с настройками WAF-ноды, переданными только в переменных окружения, используется Консоль AWS и AWS CLI.

  1. Войдите в Консоль AWS и в списке Services выберите Elastic Container Service.

  2. Перейдите к созданию кластера по кнопке Create Cluster:

    1. Выберите шаблон EC2 Linux + Networking.
    2. Задайте имя кластера, например waf-cluster.
    3. Если требуется, задайте другие настройки по инструкции.
    4. Сохраните кластер.
  3. Сохраните чувствительные данные для подключения WAF-ноды к Облаку Валарм в AWS Secrets Manager или AWS Systems Manager → Parameter Store. К чувствительным данным относятся следующие переменные окружения:

    • DEPLOY_USER: email для аккаунта пользователя Деплой или Администратор в Консоли управления Валарм.
    • DEPLOY_PASSWORD: пароль для аккаунта пользователя Деплой или Администратор в Консоли управления Валарм.

    В данной инструкции для хранения чувствительных данных используется AWS Secrets Manager.

    Доступ к хранилищу с чувствительными данными

    Чтобы Docker-контейнер прочитал зашифрованные данные из хранилища, необходимо:

    • Убедиться, что данные хранятся в том же регионе, в котором вы запускаете Docker-контейнер.
    • Убедиться, что для роли, заданной в определении задания в параметре executionRoleArn, добавлена политика SecretsManagerReadWrite. Подробнее о настройке IAM-политик →
  4. Создайте локально следующий JSON-файл с определением задания (в определении задания описывается схема работы Docker-контейнера с WAF-нодой):

    {
        "executionRoleArn": "arn:aws:iam::<AWS_ACCOUNT_ID>:role/ecsTaskExecutionRole",
        "containerDefinitions": [
            {
                "memory": 128,
                "portMappings": [
               {
                   "hostPort": 80,
                   "containerPort": 80,
                   "protocol": "tcp"
               }
           ],
           "essential": true,
           "environment": [
               {
                   "name": "NGINX_BACKEND",
                   "value": "<HOST_TO_PROTECT_WITH_WAF>"
               }
           ],
           "secrets": [
               {
                   "name": "DEPLOY_PASSWORD",
                   "valueFrom": "arn:aws:secretsmanager:<SECRETS_MANAGER_AWS_REGION>:<AWS_ACCOUNT_ID>:secret:<SECRET_NAME>:<DEPLOY_PASSWORD_PARAMETER_NAME>::"
               },
               {
                   "name": "DEPLOY_USER",
                   "valueFrom": "arn:aws:secretsmanager:<SECRETS_MANAGER_AWS_REGION>:<AWS_ACCOUNT_ID>:secret:<SECRET_NAME>:<DEPLOY_USER_PARAMETER_NAME>::"
               }
           ],
           "name": "waf-container",
           "image": "registry-1.docker.io/wallarm/node:2.18.1-3"
           }
       ],
       "family": "wallarm-waf-node"
       }
    
    {
        "executionRoleArn": "arn:aws:iam::<AWS_ACCOUNT_ID>:role/ecsTaskExecutionRole",
        "containerDefinitions": [
            {
                "memory": 128,
                "portMappings": [
               {
                   "hostPort": 80,
                   "containerPort": 80,
                   "protocol": "tcp"
               }
           ],
           "essential": true,
           "environment": [
               {
                   "name": "WALLARM_API_HOST",
                   "value": "api.wallarm.ru"
               },
               {
                   "name": "NGINX_BACKEND",
                   "value": "<HOST_TO_PROTECT_WITH_WAF>"
               }
           ],
           "secrets": [
               {
                   "name": "DEPLOY_PASSWORD",
                   "valueFrom": "arn:aws:secretsmanager:<SECRETS_MANAGER_AWS_REGION>:<AWS_ACCOUNT_ID>:secret:<SECRET_NAME>:<DEPLOY_PASSWORD_PARAMETER_NAME>::"
               },
               {
                   "name": "DEPLOY_USER",
                   "valueFrom": "arn:aws:secretsmanager:<SECRETS_MANAGER_AWS_REGION>:<AWS_ACCOUNT_ID>:secret:<SECRET_NAME>:<DEPLOY_USER_PARAMETER_NAME>::"
               }
           ],
           "name": "waf-container",
           "image": "registry-1.docker.io/wallarm/node:2.18.1-3"
           }
       ],
       "family": "wallarm-waf-node"
       }
    
    • <AWS_ACCOUNT_ID>: ID вашего аккаунта AWS.
    • В объекте environment передаются переменные окружения для Docker-контейнера в текстовом виде. Набор доступных переменных окружения приведен в таблице ниже. Рекомендуется передавать переменные DEPLOY_USER и DEPLOY_PASSWORD в объекте secrets.
    • В объекте secrets передаются переменные окружения для Docker-контейнера в виде ссылки на хранилище с чувствительными данными. Формат значений зависит от выбранного хранилища (подробнее в документации AWS Secrets Manager или AWS Systems Manager → Parameter Store).

      Рекомендуется передавать переменные DEPLOY_USER и DEPLOY_PASSWORD в объекте secrets.

      Переменная окружения Описание Обязательная?
      DEPLOY_USER Email для аккаунта пользователя Деплой или Администратор в Консоли управления Валарм. Да
      DEPLOY_PASSWORD Пароль для аккаунта пользователя Деплой или Администратор в Консоли управления Валарм. Да
      NGINX_BACKEND Домен или IP‑адрес ресурса, который необходимо защитить с помощью WAF. Да
      WALLARM_API_HOST Адрес Валарм API:
      • api.wallarm.com для EU‑облака
      • api.wallarm.ru для RU‑облака
      По умолчанию: api.wallarm.com.
      Нет
      WALLARM_MODE Режим работы WAF‑ноды:
      • block, чтобы блокировать вредоносные запросы
      • monitoring, чтобы анализировать, но не блокировать запросы
      • off, чтобы не обрабатывать входящий трафик
      По умолчанию: monitoring.
      Нет
      TARANTOOL_MEMORY_GB Размер оперативной памяти для Tarantool в гигабайтах. Значение может быть целым или дробным (разделитель целой и дробной части — точка). По умолчанию: 0.2 гигабайта. Нет
      WALLARM_ACL_ENABLE Включает блокировку IP‑адресов с настройками по умолчанию. Принимает значения:
      • true, чтобы включить блокировку
      • false, чтобы отключить блокировку
      По умолчанию (если переменная не указана явно): false.
      Чтобы включить блокировку IP‑адресов с другими настройками, необходимо определить соответствующие директивы NGINX и запустить контейнер с примонтированным конфигурационным файлом.

      Значения on / enabled / ok / yes

      Начиная с образа WAF‑ноды 2.16.0-8, значения переменной on / enabled / ok / yes отключают блокировку по IP‑адресам. Мы рекомендуем использовать последнюю версию образа, указанную в данном документе, и передавать в переменной значение true или false.

      Нет
      DEPLOY_FORCE Заменяет существующую WAF‑ноду на новую, если название WAF‑ноды соответствует идентификатору контейнера, который вы запускаете. Принимает значения:
      • true, чтобы заменить WAF‑ноду
      • false, чтобы отключить замену WAF‑ноды
      По умолчанию (если переменная не указана явно): false.
      WAF‑ноде Валарм присваивается название, соответствующее идентификатору контейнера. Данная опция полезна, если идентификаторы Docker‑контейнеров в вашей среде статичные и вы повторно запускаете Docker‑контейнер с WAF‑нодой Валарм (например, с новой версией образа). Если в этом случае значение переменной равно false, процесс создания WAF‑ноды завершится с ошибкой.
      Нет
    • Описание всех параметров конфигурационного файла приведено в документации AWS.

  5. Создайте определение задания из конфигурационного файла с помощью команды aws ecs register‑task‑definition:

    aws ecs register-task-definition --cli-input-json file://<PATH_TO_JSON_FILE>/<JSON_FILE_NAME>
    
    • <PATH_TO_JSON_FILE>: путь до JSON-файла с определением задания на вашей локальной машине.
    • <JSON_FILE_NAME>: название и расширение JSON-файла с определением задания.
  6. Запустите задание в кластере с помощью команды aws ecs run-task:

    aws ecs run-task --cluster <CLUSTER_NAME> --launch-type EC2 --task-definition <FAMILY_PARAM_VALUE>
    
    • <CLUSTER_NAME>: название кластера, созданного на шаге 1. Например, waf-cluster.
    • <FAMILY_PARAM_VALUE>: название созданного определения задания. Значение должно соответствовать параметру family из JSON-файла с определением задания. Например, wallarm-waf-node.
  7. Перейдите в Консоль AWS → Elastic Container Service → кластер, в котором вы запустили задание → Tasks и убедитесь, что задание появилось в списке.

  8. Протестируйте работу WAF-ноды.

Деплой контейнера с настройкой WAF-ноды через примонтированный файл

Для деплоя контейнера с настройками WAF-ноды, переданными через переменные окружения и примонтированный конфигурационный файл, используется Консоль AWS и AWS CLI.

В данной инструкции конфигурационный файл монтируется из файловой системы AWS EFS. Вы также можете ознакомиться с другими способами монтирования файла в документации AWS.

Чтобы запустить контейнер с переменными окружения и конфигурационным файлом, который монтируется из AWS EFS:

  1. Войдите в Консоль AWS и в списке Services выберите Elastic Container Service.

  2. Перейдите к созданию кластера по кнопке Create Cluster и задайте следующие настройки:

    • Шаблон: EC2 Linux + Networking.
    • Имя кластера: например, waf-cluster.
    • Provisioning Model: On-Demand Instance.
    • EC2 instance type: t2.micro.
    • Number of instances: 1.
    • EC2 AMI ID: Amazon Linux 2 Amazon ECS-optimized AMI.
    • Key pair: пара ключей для подключения к инстансу по SSH. Подключение по SSH потребуется для загрузки конфигурационного файла в хранилище.
    • Другие настройки по умолчанию. При изменении других настроек, рекомендуем следовать инструкции по настройке AWS EFS.
  3. Настройте хранилище AWS EFS, следуя шагам 2-4 из инструкции AWS.

  4. На шаге 4 инструкции AWS создайте конфигурационный файл default в директории, из которой по умолчанию монтируются файлы. В файле default необходимо описать настройки WAF-ноды. Пример файла с минимальными настройками:

    server {
        listen 80 default_server;
        listen [::]:80 default_server ipv6only=on;
        #listen 443 ssl;
    
        server_name localhost;
    
        #ssl_certificate cert.pem;
        #ssl_certificate_key cert.key;
    
        root /usr/share/nginx/html;
    
        index index.html index.htm;
    
        wallarm_mode monitoring;
        # wallarm_instance 1;
        # wallarm_acl default;
    
        location / {
                proxy_pass http://example.com;
                include proxy_params;
        }
    }
    

    Набор директив, которые могут быть указаны в конфигурационном файле →

  5. Сохраните чувствительные данные для подключения WAF-ноды к Облаку Валарм в AWS Secrets Manager или AWS Systems Manager → Parameter Store. К чувствительным данным относятся следующие переменные окружения:

    • DEPLOY_USER: email для аккаунта пользователя Деплой или Администратор в Консоли управления Валарм.
    • DEPLOY_PASSWORD: пароль для аккаунта пользователя Деплой или Администратор в Консоли управления Валарм.

    В данной инструкции для хранения чувствительных данных используется AWS Secrets Manager.

    Доступ к хранилищу с чувствительными данными

    Чтобы Docker-контейнер прочитал зашифрованные данные из хранилища, необходимо:

    • Убедиться, что данные хранятся в том же регионе, в котором вы запускаете Docker-контейнер.
    • Убедиться, что для роли, заданной в определении задания в параметре executionRoleArn, добавлена политика SecretsManagerReadWrite. Подробнее о настройке IAM-политик →
  6. Создайте локально следующий JSON-файл с определением задания (в определении задания описывается схема работы Docker-контейнера с WAF-нодой):

    {
        "executionRoleArn": "arn:aws:iam::<AWS_ACCOUNT_ID>:role/ecsTaskExecutionRole",
        "containerDefinitions": [
            {
                "memory": 128,
                "portMappings": [
               {
                   "hostPort": 80,
                   "containerPort": 80,
                   "protocol": "tcp"
               }
           ],
           "essential": true,
           "mountPoints": [
               {
                   "containerPath": "/etc/nginx/sites-enabled",
                   "sourceVolume": "default"
               }
           ],
           "secrets": [
               {
                   "name": "DEPLOY_PASSWORD",
                   "valueFrom": "arn:aws:secretsmanager:<SECRETS_MANAGER_AWS_REGION>:<AWS_ACCOUNT_ID>:secret:<SECRET_NAME>:<DEPLOY_PASSWORD_PARAMETER_NAME>::"
               },
               {
                   "name": "DEPLOY_USER",
                   "valueFrom": "arn:aws:secretsmanager:<SECRETS_MANAGER_AWS_REGION>:<AWS_ACCOUNT_ID>:secret:<SECRET_NAME>:<DEPLOY_USER_PARAMETER_NAME>::"
               }
           ],
           "name": "waf-container",
           "image": "registry-1.docker.io/wallarm/node:2.18.1-3"
           }
       ],
       "volumes": [
           {
               "name": "default",
               "efsVolumeConfiguration": {
                   "fileSystemId": "<EFS_FILE_SYSTEM_ID>",
                   "transitEncryption": "ENABLED"
               }
           }
       ],
       "family": "wallarm-waf-node"
       }
    
    {
        "executionRoleArn": "arn:aws:iam::<AWS_ACCOUNT_ID>:role/ecsTaskExecutionRole",
        "containerDefinitions": [
            {
                "memory": 128,
                "portMappings": [
               {
                   "hostPort": 80,
                   "containerPort": 80,
                   "protocol": "tcp"
               }
           ],
           "essential": true,
           "mountPoints": [
               {
                   "containerPath": "<PATH_FOR_MOUNTED_CONFIG>",
                   "sourceVolume": "<NAME_FROM_VOLUMES_OBJECT>"
               }
           ],
           "environment": [
               {
                   "name": "WALLARM_API_HOST",
                   "value": "api.wallarm.ru"
               }
           ],
           "secrets": [
               {
                   "name": "DEPLOY_PASSWORD",
                   "valueFrom": "arn:aws:secretsmanager:<SECRETS_MANAGER_AWS_REGION>:<AWS_ACCOUNT_ID>:secret:<SECRET_NAME>:<DEPLOY_PASSWORD_PARAMETER_NAME>::"
               },
               {
                   "name": "DEPLOY_USER",
                   "valueFrom": "arn:aws:secretsmanager:<SECRETS_MANAGER_AWS_REGION>:<AWS_ACCOUNT_ID>:secret:<SECRET_NAME>:<DEPLOY_USER_PARAMETER_NAME>::"
               }
           ],
           "name": "waf-container",
           "image": "registry-1.docker.io/wallarm/node:2.18.1-3"
           }
       ],
       "volumes": [
           {
               "name": "<VOLUME_NAME>",
               "efsVolumeConfiguration": {
                   "fileSystemId": "<EFS_FILE_SYSTEM_ID>",
                   "transitEncryption": "ENABLED"
               }
           }
       ],
       "family": "wallarm-waf-node"
       }
    
    • <AWS_ACCOUNT_ID>: ID вашего аккаунта AWS.
    • <PATH_FOR_MOUNTED_CONFIG>: директория контейнера, в которую монтируется конфигурационный файл. Конфигурационный файл может быть примонтирован в директории контейнера, которые использует NGINX:

      • /etc/nginx/conf.d — общие настройки
      • /etc/nginx/sites-enabled — настройки виртуальных хостов
      • /var/www/html — статические файлы

      Директивы WAF‑ноды описываются в файле контейнера /etc/nginx/sites-enabled/default.

    • <NAME_FROM_VOLUMES_OBJECT>: название объекта volumes, в котором описано хранилище AWS EFS (значение должно быть идентично <VOLUME_NAME>).

    • <VOLUME_NAME>: название объекта volumes, в котором необходимо описать хранилище AWS EFS.
    • <EFS_FILE_SYSTEM_ID>: ID файловой системы AWS EFS, в которой хранится конфигурационный файл для монтирования. ID отображается в Консоли AWS → ServicesEFSFile systems.
    • В объекте environment передаются переменные окружения для Docker-контейнера в текстовом виде. Набор доступных переменных окружения приведен в таблице ниже. Рекомендуется передавать переменные DEPLOY_USER и DEPLOY_PASSWORD в объекте secrets.
    • В объекте secrets передаются переменные окружения для Docker-контейнера в виде ссылки на хранилище с чувствительными данными. Формат значений зависит от выбранного хранилища (подробнее в документации AWS Secrets Manager или AWS Systems Manager → Parameter Store).

      Рекомендуется передавать переменные DEPLOY_USER и DEPLOY_PASSWORD в объекте secrets.

      Переменная окружения Описание Обязательная?
      DEPLOY_USER Email для аккаунта пользователя Деплой или Администратор в Консоли управления Валарм. Да
      DEPLOY_PASSWORD Пароль для аккаунта пользователя Деплой или Администратор в Консоли управления Валарм. Да
      WALLARM_API_HOST Адрес Валарм API:
      • api.wallarm.com для EU‑облака
      • api.wallarm.ru для RU‑облака
      По умолчанию: api.wallarm.com.
      Нет
      DEPLOY_FORCE Заменяет существующую WAF‑ноду на новую, если название WAF‑ноды соответствует идентификатору контейнера, который вы запускаете. Принимает значения:
      • true, чтобы заменить WAF‑ноду
      • false, чтобы отключить замену WAF‑ноды
      По умолчанию (если переменная не указана явно): false.
      WAF‑ноде Валарм присваивается название, соответствующее идентификатору контейнера. Данная опция полезна, если идентификаторы Docker‑контейнеров в вашей среде статичные и вы повторно запускаете Docker‑контейнер с WAF‑нодой Валарм (например, с новой версией образа). Если в этом случае значение переменной равно false, процесс создания WAF‑ноды завершится с ошибкой.
      Нет
    • Описание всех параметров конфигурационного файла приведено в документации AWS.

  7. Создайте определение задания из конфигурационного файла с помощью команды aws ecs register‑task‑definition:

    aws ecs register-task-definition --cli-input-json file://<PATH_TO_JSON_FILE>/<JSON_FILE_NAME>
    
    • <PATH_TO_JSON_FILE>: путь до JSON-файла с определением задания на вашей локальной машине.
    • <JSON_FILE_NAME>: название и расширение JSON-файла с определением задания.
  8. Запустите задание в кластере с помощью команды aws ecs run-task:

    aws ecs run-task --cluster <CLUSTER_NAME> --launch-type EC2 --task-definition <FAMILY_PARAM_VALUE>
    
    • <CLUSTER_NAME>: название кластера, созданного на шаге 1. Например, waf-cluster.
    • <FAMILY_PARAM_VALUE>: название созданного определения задания. Значение должно соответствовать параметру family из JSON-файла с определением задания. Например, wallarm-waf-node.
  9. Перейдите в Консоль AWS → Elastic Container Service → кластер, в котором вы запустили задание → Tasks и убедитесь, что задание появилось в списке.

  10. Протестируйте работу WAF-ноды.

Тестирование работы WAF-ноды

  1. В Консоли AWS откройте запущенное задание и скопируйте IP-адрес контейнера из поля External Link.

    Настройка экземпляра контейнера

    Если IP-адрес отсутствует, убедитесь, что задание и контейнер находятся в статусе RUNNING.

  2. Отправьте тестовый запрос с атаками SQLI и XSS на скопированный адрес:

    curl http://<COPIED_IP>/?id='or+1=1--a-<script>prompt(1)</script>'
    
  3. Перейдите в Консоль управления Валарм → секция События для EU‑облака или для RU‑облака и убедитесь, что атаки появились в списке.

    Атаки в интерфейсе

Сообщения об ошибках запуска контейнера отображаются в информации о задании в Консоли AWS. Если контейнер недоступен, убедитесь, что в контейнер переданы корректные значения всех обязательных параметров WAF-ноды.