# Архитектура Magos ## Обзор системы **Magos** - это система управления WAF (Web Application Firewall) контейнерами на базе Nginx/Angie, которая: - Автоматически разворачивает и управляет Docker-контейнерами с Nginx - Настраивает балансировщик Angie для распределения трафика - Интегрируется с API ServicePipe для получения конфигурации - Поддерживает graceful shutdown при масштабировании и миграции - Обеспечивает изоляцию клиентов через отдельные контейнеры - Поддерживает два WAF-вендора: **PTAF** (Docker-контейнеры) и **SW/SolidWall** (нативный процесс) ### Ключевые особенности: - **Многоклиентовая архитектура** - каждый клиент имеет свои контейнеры - **Поддержка двух вендоров** - PTAF (Docker) и SolidWall (нативный nginx) - **Динамическое управление портами** - автоматическое выделение портов из пулов с учётом всех состояний сокетов - **Кэширование данных** - минимизация обращений к API - **Failover БД** - автоматическое переключение между primary/secondary - **Graceful draining** - безопасное удаление контейнеров без потери трафика - **Умный lock-файл** - автоматическая очистка при падении процесса --- ## Компоненты системы ### 1. Основные файлы программы ``` main.go # Точка входа, основной цикл обработки config.go # Управление конфигурацией db.go # Работа с PostgreSQL api.go # Интеграция с ServicePipe API types.go # Структуры данных utils.go # Утилиты и вспомогательные функции ``` ### 2. Управление контейнерами ``` containers_part1.go # Создание и настройка контейнеров containers_part2.go # Управление жизненным циклом контейнеров drain.go # Graceful shutdown и миграция ``` ### 3. Генерация конфигураций ``` nginx.go # Генерация конфигов Nginx и Angie ports.go # Управление портами ptaf_processor.go # Обработка PTAF-клиентов sw_processor.go # Обработка SW/SolidWall-клиентов ``` --- ## Поддерживаемые WAF-вендоры ### PTAF (Positive Technologies Application Firewall) **Схема проксирования:** ``` Клиент → Angie (хост) → Docker-контейнер (PTAF nginx) → Origin ``` - Контейнеры поднимаются через docker-compose - Angie — фронтенд-балансировщик, конфиги в `/etc/angie/http.d/angie-ptaf-{clientTitle}.conf` - Nginx внутри контейнера — WAF-агент, конфиги в `/home/install/conf/ptaf-nginx/` - Порты выделяются автоматически из диапазонов 18000-20999 (HTTP) и 21000-23999 (HTTPS) ### SW / SolidWall **Схема проксирования:** ``` Клиент → solidwall-nginx (WAF, публичный) → solidwall-nginx (внутренний) → Origin ``` - Работает без Docker, напрямую на хосте - Двойное проксирование через внутренние порты 8000 (HTTP) и 9000 (HTTPS) - Конфиги: `/etc/solidwall-nginx/sites-available/solidwall-{clientTitle}-{l7ResourceID}.conf` - Симлинки в `sites-enabled/` - Утилита **не трогает**: `nginx.conf`, директорию `ssl/`, `default.conf` --- ## Архитектура данных ### База данных PostgreSQL #### Таблица `instances_new` Связь hostname → instance (waf_instance) ```sql hostname | instance ------------|------------ waf-host-01 | instance-a waf-host-01 | instance-b waf-host-02 | instance-c ``` #### Таблица `client_info` Основная информация о клиентах ```sql Поля: - client_title # Уникальный идентификатор клиента - containers_count # Количество контейнеров (0 = drain всех) - ptaf_config # Строка подключения к PTAF-серверу (CONNECTION_STRING) - fluent_bit_port # Порт для FluentBit логирования - waf_instance # Instance для привязки к хосту - docker_image # Docker-образ для контейнеров клиента (переопределяет глобальный) - docker_image_download # URL для скачивания образа - debug # Режим отладки (bool, влияет на лог-уровень) - shm_size # Размер /dev/shm в GB (дефолт: 1) - ptaf_fallback_code # Код ответа ptaf_fallback: число или 'pass' (дефолт: 418) - sp_antiddos # Использовать антиддос сети в set_real_ip (дефолт: true) - real_ip_networks # Кастомные сети для set_real_ip если sp_antiddos = false (inet[]) - worker_processes # Количество worker процессов nginx внутри контейнера (дефолт: 4) - one_container # Все SID в один контейнер (дефолт: true). При false — блочный режим - sid_block # Блоки SID для разбивки по контейнерам: {sid1,sid2}{sid3} (TEXT) ``` **Важно:** `waf_instance` определяет на каком хосте должен работать клиент **containers_count = 0:** все контейнеры клиента помечаются для drain, Angie-конфиг удаляется #### Таблица `apps_settings` Настройки каждого L7 ресурса (домена) ```sql Основные поля: - l7resourceid # ID ресурса из ServicePipe API - client_title # Связь с client_info - waf_enabled # Включен ли WAF - waf_vendor # 'ptaf' или 'sw' - mode # auto/manual/disabled Порты: - custom_input_http_ports[] # HTTP порты для прослушивания (Angie/SW) - custom_input_https_ports[] # HTTPS порты для прослушивания (Angie/SW) - custom_output_http_ports[] # HTTP порты для проксирования к origin - custom_output_https_ports[] # HTTPS порты для проксирования к origin Кастомизация Nginx (PTAF): - upstream_nginx_custom # Кастомные upstream директивы - server_nginx_custom # Кастомный server блок / SERVER_BLOCK - location_nginx_custom # Кастомные location директивы - server_directives_nginx_custom # Дополнительные server директивы Кастомизация Angie: - upstream_angie_custom # Кастомные upstream директивы - server_angie_custom # Кастомный server блок / SERVER_BLOCK - location_angie_custom # Кастомные location директивы - server_directives_angie_custom # Дополнительные server директивы - custom_angie_ssl # Полная замена SSL директив - custom_sw_nginx_ssl # Кастомные SSL директивы для SW Специальные настройки: - sni # 0 = keepalive on, 1 = keepalive off - ssl_enabled # true/false (по умолчанию true) - max_fails # Попыток до пометки сервера недоступным (дефолт 5) - fail_timeout # Время восстановления сервера (дефолт 15с) - balancing_method # Метод балансировки: least_conn, ip_hash, random и др. - proxy_next_upstream_codes # HTTP-коды для proxy_next_upstream (дефолт: 500,502,503,504) ``` #### Таблица `sp_info` (кэш API данных) Кэширует данные из ServicePipe API ```sql Поля: - sid # l7resourceid - domain_name # Основной домен - aliases # JSON массив алиасов - origins # JSON массив origin серверов - updated_at # Timestamp обновления ``` **TTL кэша:** 10 минут #### Таблица `manual_info` Ручное управление (альтернатива API) ```sql Поля: - sid # l7resourceid - domain_name # Основной домен - aliases # JSON массив алиасов - origins # JSON массив origin серверов ``` **Примечание:** Данные из `manual_info` не имеют TTL и всегда актуальны #### Таблица `ips` Настройки IP сетей ```sql Поля: - id (always = 1) - antibot_networks[] # Массив CIDR для antibot - waf_networks[] # Массив CIDR для WAF (фильтруются из origins) ``` --- ## Процесс работы ### 1. Инициализация ```go main() → initConfig() → connectToDB() ``` **Шаги:** 1. Создание lock-файла `/var/lock/ptaf-main.lock` с PID (умная проверка — автоматически удаляет если процесс уже не существует) 2. Подключение к БД (primary → secondary fallback) 3. Загрузка IP сетей из таблицы `ips` 4. Получение hostname текущего сервера 5. Определение instances для этого хоста 6. Для PTAF-хостов: проверка/скачивание Docker-образов (по одному на клиента) ### 2. Основной цикл обработки ``` ┌─────────────────────────────────────────┐ │ Глобальная проверка drain-контейнеров │ │ (processAllDrainingContainersGlobally) │ └─────────────────────────────────────────┘ ↓ ┌─────────────────────────────────────────┐ │ Для каждого instance на этом хосте │ └─────────────────────────────────────────┘ ↓ ┌─────────────────────────────────────────┐ │ Получить всех клиентов для instance │ │ (getClientInfoByInstance) │ └─────────────────────────────────────────┘ ↓ ┌─────────────────────────────────────────┐ │ Определить vendor (ptaf/sw) │ │ → processPTAFClient / processSWClient │ └─────────────────────────────────────────┘ ↓ ┌─────────────────────────────────────────┐ │ Финальная проверка drain Angie-конфигов│ │ (processDrainingAngieConfigs) │ └─────────────────────────────────────────┘ ``` ### 3. Обработка PTAF-клиента ``` 1. Проверка принадлежности хоста к WAF instance ├─ Не принадлежит → handleClientMigration (drain всех контейнеров + Angie конфига) └─ Принадлежит → продолжаем 2. containers_count = 0? └─ Да → drain всех контейнеров + Angie конфига, выход 3. cleanStaleDrainMarkers — очистка устаревших маркеров 4. fetchPTAFResourcesData — получение данных ресурсов из API/кеша 5. one_container = false И sid_block задан? ├─ Да → processPTAFClientBlocks (блочный режим, см. ниже) └─ Нет → стандартный режим: 6. resolvePortsForClient — загрузка/выделение портов ├─ .ports.json существует → переиспользуем порты ├─ Scale up → сохраняем старые порты, добавляем новые └─ Нет файла → выделяем все заново 7. generateAngieConfigsWithoutReload — генерация Angie конфига 8. setupContainers — генерация конфигов и управление контейнерами ├─ Запущен недавно, порты не слушают → пересоздаём ├─ Compose изменился → пересоздаём ├─ Конфиг изменился → nginx -s reload └─ Новый → запускаем (с ожиданием освобождения портов) 9. Проверка портов → reload Angie если нужно 10. processDrainingContainers — drain лишних контейнеров ``` ### 4. Блочный режим (one_container = false) Используется когда разные группы SID должны обслуживаться разными наборами контейнеров. ``` sid_block = '{10111,10231}{10112}{10113}' Блок 1 → SID 10111, 10231 → контейнеры {clientTitle}_block1_AZ3_hn01_a001..a{N} Блок 2 → SID 10112 → контейнеры {clientTitle}_block2_AZ3_hn01_a001..a{N} Блок 3 → SID 10113 → контейнеры {clientTitle}_block3_AZ3_hn01_a001..a{N} ``` - `containers_count` применяется к каждому блоку независимо - Каждый блок получает свои Angie конфиги и nginx конфиги только со своими SID - SID не указанные ни в одном блоке не обрабатываются - Имя контейнера: `{clientTitle}_block{N}_{AZx}_{hn/n}{NN}_a{001}` - Каждый блок обрабатывается через стандартный `resolvePortsForClient` → `generateAngieConfigsWithoutReload` → `setupContainers` ### 4. Обработка SW-клиента ``` 1. Проверка принадлежности хоста к WAF instance └─ Не принадлежит → пропускаем (миграция не реализована для SW) 2. Создание директорий: sites-available, sites-enabled, /var/log/solidwall 3. Для каждого ресурса: - Генерация конфига solidwall-{clientTitle}-{l7ResourceID}.conf - Создание симлинка в sites-enabled 4. solidwall-nginx -t + solidwall-nginx -s reload (если конфиги изменились) ``` ### 5. Сбор данных о ресурсах Для каждого ресурса определяется режим работы через поле `mode`: #### Режим `auto` (по умолчанию) ``` 1. Проверка кэша sp_info (TTL 10 мин) ├─ Данные свежие → использовать └─ Данные устарели → API запрос 2. API запросы (с retry × 3): ├─ GET /l7/resource/{id}/global → domain_name ├─ GET /l7/alias/global?l7ResourceId={id} → aliases └─ GET /l7/origin/global?l7ResourceId={id} → origins 3. Фильтрация origins (удалить WAF IP) 4. Сохранение в sp_info ``` #### Режим `manual` ``` 1. Чтение из таблицы manual_info 2. Фильтрация origins (удалить WAF IP) 3. API и кэш игнорируются ``` #### Режим `disabled` ``` Ресурс полностью пропускается ``` --- ## Управление портами ### Диапазоны портов ```go const ( HTTPPortStart = 18000 // HTTP: 18000-20999 (3000 портов) HTTPPortEnd = 20999 HTTPSPortStart = 21000 // HTTPS: 21000-23999 (3000 портов) HTTPSPortEnd = 23999 ) ``` **Важно:** На хостах необходимо зарезервировать этот диапазон чтобы ядро не использовало его для исходящих ephemeral-соединений: ```bash sysctl -w net.ipv4.ip_local_reserved_ports=18000-23999 ``` ### Алгоритм выделения портов ``` ┌────────────────────────────────────────────────┐ │ 1. Получить занятые порты (ss -tuanl) │ │ Включает: LISTEN, ESTAB, TIME-WAIT │ └────────────────────────────────────────────────┘ ↓ ┌────────────────────────────────────────────────┐ │ 2. Загрузить сохраненные порты │ │ из .ports.json (если есть) │ │ ├─ Scale up → сохранить старые, добавить │ │ └─ Нет файла → выделить все заново │ └────────────────────────────────────────────────┘ ↓ ┌────────────────────────────────────────────────┐ │ 3. Для каждого ресурса × контейнера: │ │ - Определить нужные порты │ │ - Выделить свободные Docker порты │ └────────────────────────────────────────────────┘ ↓ ┌────────────────────────────────────────────────┐ │ 4. Сохранить в .ports.json │ └────────────────────────────────────────────────┘ ``` ### Структура портов ```go type PortMapping struct { HTTPPorts map[int]int // map[customPort]dockerPort HTTPSPorts map[int]int // map[customPort]dockerPort } ``` --- ## Docker-образ Образ задаётся на двух уровнях с приоритетом клиента над глобальным: | Уровень | Источник | |---------|----------| | Глобальный | `DOCKER_IMAGE` в `/etc/magos/magos.env` | | Клиентский | `docker_image` в таблице `client_info` | Если образ отсутствует локально — скачивается tar-архив по URL из `docker_image_download` (или `DOCKER_IMAGE_URL`) и загружается через `docker load`. Одинаковые образы проверяются только один раз за запуск. --- ## Режим отладки (debug) Поле `debug` в `client_info`. При `debug = true`: **docker-compose.yml:** ```yaml - PTAF_DEBUG=True - ERROR_LOG_LEVEL=debug ``` **nginx.conf:** ```nginx env PTAF_LOG_LEVEL=DEBUG; env DEBUG=true; error_log stderr debug; ``` **Angie server-блоки:** ```nginx client_body_buffer_size 1m; ``` **Важно:** включение debug режима вызывает пересоздание контейнера. --- ## Graceful Shutdown и миграция ### Типы drain операций #### 1. Масштабирование вниз (Scale Down) **Timeout:** 90 секунд ``` Триггер: containers_count уменьшен в БД Действие: лишние контейнеры помечаются маркером /tmp/ptaf-drain-ptaf_{client}_{num} Через 90с: docker-compose down + удаление файлов ``` #### 2. Отключение клиента (containers_count = 0) **Timeout:** 90 секунд ``` Триггер: containers_count = 0 Действие: все контейнеры + Angie-конфиг помечаются для drain Через 90с: удаление контейнеров и конфига Angie ``` #### 3. Миграция между хостами **Timeout:** 3600 секунд (1 час) ``` Триггер: waf_instance изменился в БД Действие: контейнеры и Angie-конфиг помечаются маркером :migration Через 1ч: проверка актуальности → удаление если клиент не вернулся ``` ### Формат маркеров ``` /tmp/ptaf-drain-ptaf_{clientTitle}_{001} — контейнер (содержит timestamp или timestamp:migration) /tmp/ptaf-angie-drain-{clientTitle} — Angie конфиг (аналогичный формат) ``` --- ## Кастомизация конфигов через SERVER_BLOCK Формат для полей `server_nginx_custom` и `server_angie_custom`: ``` [SERVER_BLOCK:443:example.com:www.example.com] proxy_ssl_certificate /etc/ssl/certs/example.crt; proxy_ssl_certificate_key /etc/ssl/private/example.key; proxy_ssl_server_name on; [/SERVER_BLOCK] ``` Синтаксис: `[SERVER_BLOCK:{порт}:{server_name}:{alias1}:{alias2}...]` - Поддерживает произвольное количество алиасов - Несколько SERVER_BLOCK в одном поле — поддерживается - Для Angie: SERVER_BLOCK создаёт отдельный server-блок с проксированием на контейнеры - Для nginx: SERVER_BLOCK создаёт отдельный server-блок с проксированием на origin --- ## Метод балансировки Поле `balancing_method` в `apps_settings`. Записывается **без** точки с запятой: ```sql UPDATE apps_settings SET balancing_method = 'least_conn' WHERE l7resourceid = 12345; ``` Допустимые значения: `least_conn`, `ip_hash`, `random`, `random two least_conn` и др. Применяется первой строкой в upstream-блоке для Angie, nginx и SW. --- ## proxy_next_upstream Поле `proxy_next_upstream_codes` в `apps_settings`. Записывается через запятую **без** `http_` префикса: ```sql -- Убрать 500 из списка (бэкенд вернул 500, Angie не должен делать retry) UPDATE apps_settings SET proxy_next_upstream_codes = '502,503,504' WHERE l7resourceid = 12345; ``` Дефолт: `500,502,503,504`. Итоговая строка в конфиге: ```nginx proxy_next_upstream error timeout invalid_header http_502 http_503 http_504; ``` --- ## Запуск контейнеров ### Ожидание освобождения портов Перед запуском контейнера утилита проверяет занятость портов через `ss -tuanl` (все состояния включая TIME-WAIT и ESTAB). Порт считается занятым если: - Есть `LISTEN` сокет - Есть `ESTAB` от `docker-proxy` (старый контейнер ещё не остановился) После остановки контейнера при пересоздании: 1. Ожидаем закрытия ESTAB соединений Angie (до 30 сек) 2. Ожидаем полного освобождения портов (до 180 сек) 3. Запуск нового контейнера (до 3 попыток с паузой 3 сек) ### Сохранение портов `.ports.json` сохраняется **только после успешного запуска контейнера**: - При пересоздании контейнера (`recreateContainer`) — сохраняется если `recreateContainer` вернул `true` - При первом запуске нового контейнера — сохраняется если контейнер успешно запустился - При неизменённом compose — сохраняется сразу (порты не менялись) Если контейнер не запустился — `.ports.json` остаётся старым, и при следующем запуске magos порты будут перевыделены заново. ### Проверка после запуска Если контейнер запущен менее 5 минут и порты не слушают — автоматическое пересоздание. --- ## Именование контейнеров Имя Docker-контейнера формируется динамически на основе hostname хоста: ``` PTAF-TB-docker-AZ3-HW-node01 → {clientTitle}_AZ3_hn01_a001 PTAF-TB-docker-AZ1-node04 → {clientTitle}_AZ1_n04_a001 ``` **Правила парсинга hostname:** - `AZ{N}` — номер зоны доступности - Наличие `HW` в hostname → префикс `hn` (hardware node), отсутствие → `n` - `node{NN}` — номер ноды - `a{001}` — порядковый номер агента **Fallback:** если hostname не соответствует формату — используется старый формат `ptaf_{clientTitle}_{001}`. **Важно:** директории на диске (`/home/install/ptaf/{clientTitle}/{clientTitle}-ptaf-agent{001}/`) не меняются — только `container_name` и `hostname` в Docker. --- ### Производительность ```go DefaultWorkerProcesses = 4 // Nginx worker processes (дефолт, переопределяется в client_info) DefaultWorkerConnections = 64000 // Соединений на worker worker_rlimit_nofile = 1048576 // Лимит файловых дескрипторов ``` ### Timeouts ```go ContainerDrainTimeout = 90 // Секунд для scale down / отключения MigrationDrainTimeout = 3600 // Секунд для миграции (1 час) APITimeout = 120 // Секунд для API запросов CacheTTL = 600 // Секунд (10 минут) для sp_info MaxLockAge = 15 мин // После этого lock считается устаревшим ``` ### Буферы (Angie и nginx) ```nginx proxy_buffers 8 64k; proxy_buffer_size 64k; proxy_busy_buffers_size 128k; large_client_header_buffers 4 128k; ``` ### shm_size По умолчанию `1gb`. Управляется через поле `shm_size` в `client_info`. --- ## Безопасность ### Фильтрация IP адресов **WAF Networks** - исключаются из origins (предотвращение routing loops). Всегда добавляются в `set_real_ip_from` в Angie. **Antibot Networks** - используются для `set_real_ip_from` в Angie по умолчанию (`sp_antiddos = true`). **Custom Real IP Networks** - если у клиента `sp_antiddos = false` и заполнено поле `real_ip_networks` в `client_info` — используются вместо Antibot Networks в `set_real_ip_from`. Применяется для клиентов без антиддоса перед Angie. Внутри контейнера nginx всегда использует `set_real_ip_from 172.16.0.0/12` (Docker bridge сеть Angie). ### SSL/TLS **Дефолтные настройки (Angie):** ```nginx ssl_protocols TLSv1.2 TLSv1.3; ssl_ciphers HIGH:!aNULL:!MD5; ssl_prefer_server_ciphers on; ssl_session_cache shared:SSL:10m; ssl_session_timeout 10m; ``` **Кастомизация через `custom_angie_ssl`** — полная замена дефолтов для Angie **Кастомизация через `custom_sw_nginx_ssl`** — полная замена дефолтов для SW ### mTLS **Автоматическая замена путей:** ``` /etc/ssl/certs/ → /opt/ptaf/conf/main/ /etc/ssl/private/ → /opt/ptaf/conf/main/ ``` Применяется во всех custom директивах, содержащих `proxy_ssl_certificate` ### Lock-файл При старте утилита: 1. Читает PID из существующего lock-файла 2. Если процесс не существует → удаляет устаревший lock и продолжает 3. Если процесс работает > 15 минут → предупреждение и подсказка как убить 4. При завершении → lock удаляется через `defer` --- ## Логирование ### Структура логов nginx ``` /var/log/ptaf_nginx/{client-title}/ptaf-agent001/ ├── {sid}_{domain}_access.log └── {sid}_{domain}_error.log ``` ### Формат access лога (JSON) ```json { "SID": 12345, "server_name": "example.com", "request_id": "abc123", "app_name": "example.com", "proxyed_to": "192.168.1.1:443", "upstream_status": "200", "response_status_code": 200, "request_time": 0.056 } ``` Поле `request_id` берётся из заголовка `X-Request-ID`. ### Уровни логирования программы ``` ✓ — Успешная операция ○ — Информация (без изменений) ⚠ — Предупреждение → — Действие/переход └─ — Детали операции ❌ — Критическая ошибка ℹ — Информационное сообщение ``` --- ## Мониторинг и логирование ### FluentBit интеграция Активируется через поле `fluent_bit_port` в `client_info`: ```yaml environment: - EVENT_SENDER_ENABLED=1 - EVENT_SENDER_HOST=172.17.0.1 - EVENT_SENDER_PORT={fluent_bit_port} - EVENT_SENDER_TIMEOUT=3 ``` --- ## Troubleshooting ### Проблема: Контейнер не запускается **Проверить:** 1. `docker logs ptaf_{client}_{num}` 2. Наличие конфигов в `/home/install/conf/ptaf-nginx/` 3. Занятость портов: `ss -tuanl | grep {port}` 4. Права на `/var/log/ptaf_nginx/` (должны быть 0777) 5. Зомби docker-proxy процессы: `ps aux | grep docker-proxy | grep -v grep` ### Проблема: Порты конфликтуют **Действия:** 1. Проверить `ss -tuanl | grep :{port}` — все состояния сокетов 2. Проверить `cat /proc/net/tcp | grep -i "$(printf '%04X' {port})"` — таблица ядра 3. Убедиться что `ip_local_reserved_ports=18000-23999` установлен на хосте 4. Удалить `.ports.json` — порты будут перевыделены при следующем запуске ### Проблема: Lock-файл не удалился **Действия:** 1. Magos автоматически удалит lock если процесс уже не существует 2. Если процесс завис: `kill {PID} && rm /var/lock/ptaf-main.lock` 3. PID записан в lock-файле: `cat /var/lock/ptaf-main.lock` ### Проблема: Клиент не мигрирует **Проверить:** 1. `waf_instance` в `client_info` 2. Записи в `instances_new` 3. Наличие маркеров `/tmp/ptaf-drain-*` 4. Логи программы на обоих хостах ### Проблема: SW nginx не перезагружается **Проверить:** 1. `solidwall-nginx -t` 2. Наличие симлинков в `sites-enabled/` 3. Синтаксис в `sites-available/*.conf` --- ## Расширение системы ### Добавление нового клиента (PTAF) ```sql INSERT INTO client_info (client_title, containers_count, waf_instance) VALUES ('new-client', 2, 'instance-a'); INSERT INTO apps_settings (l7resourceid, client_title, waf_vendor, waf_enabled, mode) VALUES (12345, 'new-client', 'ptaf', true, 'auto'); ``` ### Добавление нового клиента (SW) ```sql INSERT INTO client_info (client_title, containers_count, waf_instance) VALUES ('new-sw-client', 0, 'sw-instance-a'); -- containers_count игнорируется для SW INSERT INTO apps_settings (l7resourceid, client_title, waf_vendor, waf_enabled, mode) VALUES (12346, 'new-sw-client', 'sw', true, 'auto'); ``` ### Включение debug-режима для клиента ```sql UPDATE client_info SET debug = true WHERE client_title = 'CLIENT001'; ``` ### Задать индивидуальный Docker-образ для клиента ```sql UPDATE client_info SET docker_image = 'ptaf-core-nginx-agent:release-4.3.1.431839-debian-bullseye-nginx-1.28.0', docker_image_download = 'https://example.com/image.tar' WHERE client_title = 'CLIENT001'; ``` ### Увеличить shared memory для контейнера ```sql UPDATE client_info SET shm_size = 8 WHERE client_title = 'CLIENT001'; ``` ### Настроить балансировку ```sql UPDATE apps_settings SET balancing_method = 'least_conn' WHERE l7resourceid = 12345; ``` ### Включить блочный режим (разбивка SID по контейнерам) ```sql -- Три блока SID, каждый в своём наборе контейнеров UPDATE client_info SET one_container = false, sid_block = '{10111,10231}{10112}{10113}' WHERE client_title = 'CLIENT001'; ``` Формат `sid_block`: `{sid1,sid2}{sid3}{sid4,sid5,sid6}` — каждая пара `{}` это один блок. ```sql -- Пропускать трафик если WAF недоступен UPDATE client_info SET ptaf_fallback_code = 'pass' WHERE client_title = 'CLIENT001'; -- Вернуть 503 вместо 418 UPDATE client_info SET ptaf_fallback_code = '503' WHERE client_title = 'CLIENT001'; ``` ### Настроить количество worker процессов ```sql UPDATE client_info SET worker_processes = 8 WHERE client_title = 'CLIENT001'; ``` Изменение вызывает `nginx -s reload` внутри контейнера без пересоздания контейнера. ```sql UPDATE client_info SET sp_antiddos = false, real_ip_networks = '{10.0.0.0/8, 192.168.1.0/24}' WHERE client_title = 'CLIENT001'; ```