magos/DATABASE_SCHEMA.md

588 lines
19 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# Magos - Схема базы данных
---
## Обзор
Magos работает с PostgreSQL базой данных, которая содержит конфигурации WAF платформы. Программа использует несколько основных таблиц для получения информации о хостах, клиентах, приложениях и backend серверах.
### Используемые таблицы
1. **instances_new** - информация о хостах/серверах
2. **client_info** - данные клиентов и контейнеров
3. **apps_settings** - настройки приложений и кастомные директивы
4. **sp_info** - кэш данных из API (origins, aliases)
5. **manual_info** - ручные данные (альтернатива API)
6. **ips** - IP адреса для WAF и antibot сетей
---
## Подключение к БД
### Параметры подключения
```bash
DB_USER=login
DB_PASSWORD=password
DB_NAME=waf_info
DB_PORT=5432
PRIMARY_DB_HOST=10.100.10.8
SECONDARY_DB_HOST=10.100.13.5
```
### Failover логика
1. Попытка подключения к Primary DB
2. Если неудача → подключение к Secondary DB
3. Если обе недоступны → программа останавливается
**Функция:** `connectToDB()`
---
## Таблица: instances_new
### Назначение
Хранит информацию о хостах/серверах в кластере WAF.
### Структура
| Поле | Тип | Описание | Пример |
|------|-----|----------|--------|
| `hostname` | TEXT | Hostname сервера | `host01.example.com` |
| `instance` | TEXT | Идентификатор инстанса | `waf-prod-01` |
### Используемые запросы
#### Получение instances по hostname
```sql
SELECT instance
FROM instances_new
WHERE hostname = $1;
```
**Функция:** `getInstancesByHostname(hostname string)`
Один хост может принадлежать нескольким instances.
#### Проверка принадлежности хоста к инстансу
```sql
SELECT COUNT(*)
FROM instances_new
WHERE hostname = $1 AND instance = $2;
```
**Функция:** `checkHostBelongsToInstance(hostname, instance string)`
---
## Таблица: client_info
### Назначение
Хранит информацию о клиентах: количество контейнеров, Docker-образ, режим отладки и привязка к инстансу.
### Структура
| Поле | Тип | Описание | Пример |
|------|-----|----------|--------|
| `client_title` | TEXT | Идентификатор клиента | `CLIENT001` |
| `containers_count` | INTEGER | Количество контейнеров (0 = drain всех) | `3` |
| `ptaf_config` | TEXT | Строка подключения к PTAF-серверу | `{...}` |
| `fluent_bit_port` | INTEGER | Порт Fluent Bit | `24224` |
| `waf_instance` | TEXT | Instance для привязки к хосту | `waf-prod-01` |
| `docker_image` | TEXT | Docker-образ (переопределяет глобальный) | `ptaf-core-nginx-agent:release-4.3.1...` |
| `docker_image_download` | TEXT | URL для скачивания tar-архива образа | `https://...` |
| `debug` | BOOLEAN | Режим отладки | `false` |
| `shm_size` | INTEGER | Размер /dev/shm в GB | `1` |
| `ptaf_fallback_code` | TEXT | Код ответа ptaf_fallback | `'418'` |
### Используемые запросы
#### Получение клиентов по instance
```sql
SELECT
containers_count,
ptaf_config,
client_title,
fluent_bit_port,
waf_instance,
docker_image,
docker_image_download,
debug,
shm_size
FROM client_info
WHERE waf_instance = $1;
```
**Функция:** `getClientInfoByInstance(instance string)`
#### Получение клиента по client_title
```sql
SELECT
containers_count,
ptaf_config,
client_title,
fluent_bit_port,
waf_instance,
docker_image,
docker_image_download,
debug,
shm_size
FROM client_info
WHERE client_title = $1;
```
**Функция:** `getClientInfoByClientTitle(clientTitle string)`
### Миграции
```sql
ALTER TABLE client_info
ADD COLUMN IF NOT EXISTS docker_image TEXT DEFAULT NULL;
ALTER TABLE client_info
ADD COLUMN IF NOT EXISTS docker_image_download TEXT DEFAULT NULL;
ALTER TABLE client_info
ADD COLUMN IF NOT EXISTS debug BOOLEAN DEFAULT FALSE;
ALTER TABLE client_info
ADD COLUMN IF NOT EXISTS shm_size INTEGER DEFAULT 1;
```
### Ключевые поля
#### containers_count
- `containers_count = 3` → создать ptaf_client_001, ptaf_client_002, ptaf_client_003
- При увеличении → новые контейнеры добавляются, существующие не трогаются
- При уменьшении → лишние контейнеры помечаются на graceful drain (90с)
- `containers_count = 0` → все контейнеры и Angie-конфиг помечаются на drain
#### docker_image / docker_image_download
Если заполнены — используются вместо глобальных настроек `DOCKER_IMAGE` и `DOCKER_IMAGE_URL` из `magos.env`. Позволяют иметь разные версии агента для разных клиентов.
#### debug
При `true`:
- В docker-compose добавляются `PTAF_DEBUG=True` и `ERROR_LOG_LEVEL=debug`
- В nginx.conf: `PTAF_LOG_LEVEL=DEBUG`, `DEBUG=true`, `error_log stderr debug`
- В Angie server-блоки добавляется `client_body_buffer_size 1m`
#### shm_size
Размер разделяемой памяти `/dev/shm` для Docker-контейнера в гигабайтах. Результат в docker-compose: `shm_size: '2gb'`. Дефолт: 1.
---
## Таблица: apps_settings
### Назначение
Основная таблица с настройками приложений и кастомными директивами Nginx/Angie.
### Структура
| Поле | Тип | Описание | Значение по умолчанию |
|------|-----|----------|----------------------|
| `l7resourceid` | INTEGER | ID ресурса | Первичный ключ |
| `client_title` | TEXT | Клиент (FK) | — |
| `waf_enabled` | BOOLEAN | WAF включен | `true` |
| `waf_vendor` | TEXT | Вендор: 'ptaf' или 'sw' | — |
| `mode` | TEXT | auto/manual/disabled | `auto` |
| `sni` | INTEGER | SNI режим (0=keepalive on, 1=keepalive off) | `0` |
| `ssl_enabled` | BOOLEAN | SSL на HTTPS портах | `true` |
| `custom_input_http_ports` | INTEGER[] | HTTP порты для прослушивания | `{80}` |
| `custom_input_https_ports` | INTEGER[] | HTTPS порты для прослушивания | `{443}` |
| `custom_output_http_ports` | INTEGER[] | HTTP порты к backend | `{80}` |
| `custom_output_https_ports` | INTEGER[] | HTTPS порты к backend | `{443}` |
| `upstream_angie_custom` | TEXT | Кастомные upstream директивы (Angie) | `NULL` |
| `upstream_nginx_custom` | TEXT | Кастомные upstream директивы (Nginx/SW) | `NULL` |
| `server_angie_custom` | TEXT | Кастомный server блок (Angie) | `NULL` |
| `server_nginx_custom` | TEXT | Кастомный server блок (Nginx/SW) | `NULL` |
| `server_directives_angie_custom` | TEXT | Кастомные server директивы (Angie) | `NULL` |
| `server_directives_nginx_custom` | TEXT | Кастомные server директивы (Nginx/SW) | `NULL` |
| `location_angie_custom` | TEXT | Кастомные location блоки (Angie) | `NULL` |
| `location_nginx_custom` | TEXT | Кастомные location блоки (Nginx/SW) | `NULL` |
| `custom_angie_ssl` | TEXT | Замена SSL директив (Angie) | `NULL` |
| `custom_sw_nginx_ssl` | TEXT | Замена SSL директив (SW) | `NULL` |
| `max_fails` | INTEGER | Попыток до пометки сервера недоступным | `5` |
| `fail_timeout` | INTEGER | Время восстановления сервера (сек) | `15` |
| `balancing_method` | TEXT | Метод балансировки upstream | `NULL` |
| `proxy_next_upstream_codes` | TEXT | HTTP-коды для proxy_next_upstream | `'500,502,503,504'` |
### Используемые запросы
#### Получение настроек по client_title
```sql
SELECT
l7resourceid,
waf_enabled,
waf_vendor,
mode,
custom_input_http_ports,
custom_input_https_ports,
custom_output_http_ports,
custom_output_https_ports,
upstream_angie_custom,
upstream_nginx_custom,
server_nginx_custom,
server_angie_custom,
location_angie_custom,
location_nginx_custom,
server_directives_angie_custom,
server_directives_nginx_custom,
custom_angie_ssl,
custom_sw_nginx_ssl,
client_title,
sni,
ssl_enabled,
max_fails,
fail_timeout,
balancing_method,
proxy_next_upstream_codes,
ptaf_fallback_code
FROM apps_settings
WHERE client_title = $1
ORDER BY l7resourceid ASC;
```
**Функция:** `getAppsSettingsByClientTitle(clientTitle string)`
### Миграции
```sql
ALTER TABLE apps_settings
ADD COLUMN IF NOT EXISTS custom_sw_nginx_ssl TEXT DEFAULT NULL;
ALTER TABLE apps_settings
ADD COLUMN IF NOT EXISTS balancing_method TEXT DEFAULT NULL;
ALTER TABLE apps_settings
ADD COLUMN IF NOT EXISTS proxy_next_upstream_codes TEXT DEFAULT '500,502,503,504';
ALTER TABLE client_info
ADD COLUMN IF NOT EXISTS ptaf_fallback_code TEXT DEFAULT '418';
```
### Кастомные поля (подробно)
#### balancing_method
Метод балансировки upstream. Записывается **без** точки с запятой. Вставляется первой строкой в upstream-блок.
```sql
-- Включить least_conn
UPDATE apps_settings SET balancing_method = 'least_conn' WHERE l7resourceid = 12345;
-- Вернуть round-robin (дефолт)
UPDATE apps_settings SET balancing_method = NULL WHERE l7resourceid = 12345;
```
Допустимые значения: `least_conn`, `ip_hash`, `random`, `random two least_conn`
#### proxy_next_upstream_codes
Коды HTTP ответов при которых Angie/nginx переключается на следующий upstream-сервер. Записывается через запятую **без** префикса `http_`.
```sql
-- Убрать 500 из retry (бэкенд вернул 500, не нужно делать retry)
UPDATE apps_settings
SET proxy_next_upstream_codes = '502,503,504'
WHERE l7resourceid = 12345;
-- Вернуть дефолт
UPDATE apps_settings
SET proxy_next_upstream_codes = NULL
WHERE l7resourceid = 12345;
```
Итоговая строка в конфиге:
```nginx
proxy_next_upstream error timeout invalid_header http_502 http_503 http_504;
```
#### ptaf_fallback_code
Код HTTP ответа который PTAF возвращает когда WAF-модуль недоступен.
```sql
-- Пропускать трафик если WAF недоступен
UPDATE client_info SET ptaf_fallback_code = 'pass' WHERE client_uuid = 12345;
-- Вернуть 503 вместо 418
UPDATE client_info SET ptaf_fallback_code = '503' WHERE client_uuid = 12345;
-- Вернуть дефолт (418)
UPDATE client_info SET ptaf_fallback_code = NULL WHERE client_uuid = 12345;
```
#### upstream_angie_custom / upstream_nginx_custom
**Режим:** REPLACE (полная замена keepalive директив)
```sql
-- Кастомный keepalive
UPDATE apps_settings
SET upstream_angie_custom = 'keepalive 200;
keepalive_timeout 90s;'
WHERE l7resourceid = 12345;
```
#### server_directives_angie_custom / server_directives_nginx_custom
**Режим:** REPLACE (замена блока дефолтных таймаутов/буферов)
**Важно:** при использовании кастома нужно указать ВСЕ нужные директивы, включая `proxy_set_header X-Request-ID`.
#### server_angie_custom / server_nginx_custom
Поддерживает формат SERVER_BLOCK для создания дополнительных server-блоков:
```
[SERVER_BLOCK:443:report.example.com:www.report.example.com]
proxy_read_timeout 3600s;
proxy_send_timeout 3600s;
[/SERVER_BLOCK]
```
Синтаксис: `[SERVER_BLOCK:{порт}:{server_name}:{alias1}:{alias2}...]`
#### custom_angie_ssl / custom_sw_nginx_ssl
Полная замена SSL директив. При NULL используются дефолтные:
```nginx
ssl_certificate ssl/cert.pem;
ssl_certificate_key ssl/key.pem;
ssl_protocols TLSv1.2 TLSv1.3;
```
---
## Таблица: sp_info (кэш)
### Назначение
Кэширует данные из ServicePipe API. TTL: 10 минут.
### Структура
| Поле | Тип | Описание |
|------|-----|----------|
| `sid` | INTEGER | l7resourceid |
| `domain_name` | TEXT | Основной домен |
| `aliases` | JSON | Массив алиасов |
| `origins` | JSON | Массив origin серверов |
| `updated_at` | TIMESTAMP | Время последнего обновления |
---
## Таблица: manual_info
### Назначение
Ручное управление данными ресурсов (альтернатива API). Используется при `mode = 'manual'`.
### Структура
| Поле | Тип | Описание |
|------|-----|----------|
| `sid` | INTEGER | l7resourceid |
| `domain_name` | TEXT | Основной домен |
| `aliases` | JSON | Массив алиасов |
| `origins` | JSON | Массив origin серверов |
Данные не имеют TTL и всегда актуальны.
---
## Таблица: ips
### Структура
| Поле | Тип | Описание |
|------|-----|----------|
| `id` | INTEGER | Всегда = 1 |
| `antibot_networks` | TEXT[] | CIDR сети antibot |
| `waf_networks` | TEXT[] | CIDR сети WAF (исключаются из origins) |
---
## Связи между таблицами
```
instances_new
↓ (hostname → instance)
client_info (waf_instance)
↓ (client_title)
apps_settings (client_title)
↓ (l7resourceid через API/manual_info)
Origins, Aliases
```
---
## Примеры типичных операций
### Добавить нового PTAF-клиента
```sql
INSERT INTO client_info (client_title, containers_count, waf_instance)
VALUES ('NewClient', 2, 'PTAFd_01');
INSERT INTO apps_settings (l7resourceid, client_title, waf_vendor, waf_enabled, mode)
VALUES (99999, 'NewClient', 'ptaf', true, 'auto');
```
### Добавить нового SW-клиента
```sql
INSERT INTO client_info (client_title, containers_count, waf_instance)
VALUES ('NewSWClient', 0, 'SWd_01');
INSERT INTO apps_settings (l7resourceid, client_title, waf_vendor, waf_enabled, mode)
VALUES (99998, 'NewSWClient', 'sw', true, 'auto');
```
### Изменить количество контейнеров
```sql
-- Увеличить до 5
UPDATE client_info SET containers_count = 5 WHERE client_title = 'CLIENT001';
-- Отключить клиента (drain всех контейнеров)
UPDATE client_info SET containers_count = 0 WHERE client_title = 'CLIENT001';
```
### Включить 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';
```
### Настроить балансировку
```sql
UPDATE apps_settings SET balancing_method = 'least_conn' WHERE l7resourceid = 12345;
```
### Убрать 500 из retry
```sql
UPDATE apps_settings
SET proxy_next_upstream_codes = '502,503,504'
WHERE l7resourceid = 12345;
```
### Добавить кастомные SSL для SW
```sql
UPDATE apps_settings
SET custom_sw_nginx_ssl = 'ssl_certificate /etc/solidwall-nginx/ssl/custom.crt;
ssl_certificate_key /etc/solidwall-nginx/ssl/custom.key;
ssl_protocols TLSv1.2 TLSv1.3;'
WHERE l7resourceid = 12345;
```
### Добавить SERVER_BLOCK с увеличенными таймаутами
```sql
UPDATE apps_settings
SET server_angie_custom = '[SERVER_BLOCK:443:report.example.com:www.report.example.com]
proxy_read_timeout 3600s;
proxy_send_timeout 3600s;
[/SERVER_BLOCK]'
WHERE l7resourceid = 12345;
```
---
## Best Practices
### NULL vs пустая строка
```sql
-- Правильно: NULL для дефолтов
UPDATE apps_settings SET upstream_angie_custom = NULL WHERE l7resourceid = 12345;
-- Неправильно: пустая строка может вызвать ошибки
UPDATE apps_settings SET upstream_angie_custom = '' WHERE l7resourceid = 12345;
```
### Массивы портов
```sql
-- Правильно: PostgreSQL array
UPDATE apps_settings SET custom_input_https_ports = '{443, 8443}' WHERE l7resourceid = 12345;
-- Неправильно: строка
UPDATE apps_settings SET custom_input_https_ports = '443,8443' WHERE l7resourceid = 12345;
```
### balancing_method — без точки с запятой
```sql
-- Правильно
UPDATE apps_settings SET balancing_method = 'least_conn' WHERE l7resourceid = 12345;
-- Неправильно
UPDATE apps_settings SET balancing_method = 'least_conn;' WHERE l7resourceid = 12345;
```
---
## Мониторинг БД
```sql
-- Количество клиентов на каждом instance
SELECT waf_instance, COUNT(*) as clients_count
FROM client_info
GROUP BY waf_instance;
-- Клиенты с debug-режимом
SELECT client_title FROM client_info WHERE debug = true;
-- Клиенты с индивидуальным образом
SELECT client_title, docker_image FROM client_info WHERE docker_image IS NOT NULL;
-- Ресурсы с кастомной балансировкой
SELECT client_title, l7resourceid, balancing_method
FROM apps_settings
WHERE balancing_method IS NOT NULL;
-- Ресурсы с кастомными upstream директивами
SELECT client_title, l7resourceid
FROM apps_settings
WHERE upstream_angie_custom IS NOT NULL
OR upstream_nginx_custom IS NOT NULL;
```
---
## Индексы (рекомендуемые)
```sql
CREATE INDEX idx_instances_new_hostname ON instances_new(hostname);
CREATE INDEX idx_client_info_waf_instance ON client_info(waf_instance);
CREATE INDEX idx_client_info_client_title ON client_info(client_title);
CREATE INDEX idx_apps_settings_client_title ON apps_settings(client_title);
CREATE INDEX idx_apps_settings_l7resourceid ON apps_settings(l7resourceid);
```