Обеспечение отказоустойчивой работы Nemesida WAF API | Немезида ВАФ

Модуль Nemesida WAF API является ключевым звеном взаимодействия всех компонентов Немезида ВАФ, поэтому необходимо обеспечить его отказоустойчивую работу. В этой статье мы расскажем как это сделать.

В статье будут использоваться два IP-адреса: 10.0.0.1 (основной сервер, используемый по умолчанию) и 10.0.0.2 (сервер репликации, используемый в случае недоступности основного).

Настройка основного сервера

Основной сервер предназначен для полноценной работы — получения данных от всех компонентов Немезида ВАФ и их записи в БД. Активация функционала репликации на основном сервере выполняется в несколько шагов:

1. Добавьте разрешающее правило в iptables для обращения к порту PostgreSQL (по умолчанию, 5432):

-A INPUT -p tcp --dport 5432 -j ACCEPT

2. Создайте пользователя PostgreSQL, от имени которого будет выполняться репликация данных, например, repluser:

# su postgres
$ createuser --replication -P repluser

После выполнения команды задаем пароль для пользователя repluser.

3. Внесите изменения в файле /etc/postgresql/13/main/postgresql.conf:

...
listen_addresses = '*'
checkpoint_timeout = 30s
max_wal_size = 1GB
min_wal_size = 80MB
wal_level = hot_standby
max_wal_senders = 2 (количество клиентов репликации +1)
max_replication_slots = 2 (количество клиентов репликации +1)
hot_standby = on
hot_standby_feedback = on
...

4. Внесите изменения в файле /etc/postgresql/13/main/pg_hba.conf:

host replication repluser 127.0.0.1/32 md5
host replication repluser 10.0.0.2/32 md5

5. Добавьте слот:

# su postgres
$ psql -c "SELECT pg_create_physical_replication_slot('slave01');"

slave01 — имя сервера репликации, которое задается при его настройке.

6. Перезапустите PostgreSQL, чтобы применить настройки:

# service postgresql restart

Настройка сервера репликации

Сервер репликации позволяет поддерживать минимальное функционирование модуля Nemesida WAF API (режим «только чтение») во время недоступности основного сервера Nemesida WAF API. В этом режиме Nemesida WAF API позволяет запрашивать данные из БД (настройки Немезида ВАФ, поведенческие модели и т.д.), без возможности производить запись в нее (например, новые записи об атаках, изменение параметров Немезида ВАФ и т.д.). Активация функционала репликации выполняется в несколько шагов:

1. Внесите изменения в конфигурационный файл /etc/postgresql/13/main/postgresql.conf:

...
data_directory = '/var/lib/postgresql/13/main'
hba_file = '/etc/postgresql/13/main/pg_hba.conf'
ident_file = '/etc/postgresql/13/main/pg_ident.conf'
cluster_name = '13/slave'
stats_temp_directory = '/var/run/postgresql/13-main.pg_stat_tmp'
port = 5433
max_connections = 1000
primary_conninfo = 'user=repluser password=<REPLUSER_PASSWORD> host=10.0.0.1 port=5432 sslmode=prefer sslcompression=0 krbsrvname=postgres target_session_attrs=any'
primary_slot_name = 'slave01'
hot_standby = on
...

2. Произведите копирование базы данных:

# su postgres
$ rm -rf /var/lib/postgresql/13/main/*
$ pg_basebackup -h 10.0.0.1 -U repluser -D /var/lib/postgresql/13/main --write-recovery-conf

3. Запустите кластер slave после выполнения репликации:

# pg_ctlcluster 13 slave start

4. Проверьте статус кластера:

# pg_ctlcluster 13 slave status

5. Проверьте корректность настройки репликации, созданием тестовой таблицы на основном сервере:

# su postgres
$ psql -c "CREATE TABLE test_table (id INT, name TEXT);"
$ psql -c "INSERT INTO test_table (id, name) VALUES (1, 'test');"

Если все настроено корректно, то в базе данных сервера репликации отобразится созданная таблица test_table.

Настройка Nemesida WAF API

После настройки репликации необходимо настроить Nemesida WAF API на работу в режиме «только чтение». Для этого необходимо:

1. Внесите изменения в конфигурационный файл /var/www/nw-api/settings.py:

RO_MODE = true

2. Перезапустите сервис Nemesida WAF API:

# service nwaf-api restart

Настройка отказоустойчивости

После настройки репликации и Nemesida WAF API на сервере репликации, необходимо настроить балансировку нагрузки. Для этого настраиваем приоритет обработки запросов для каждого из серверов с Nemesida WAF API, например, следующим образом:


Схема распределения нагрузки

Обработка запроса происходит в несколько этапов:

1. Веб-сервер Nginx, с установленным динамическим модулем, обращается к DNS-серверу для получения списка IP-адресов веб-серверов Nginx c функцией распределения нагрузки.

2. Методом Round Robin DNS выбирается один из веб-серверов, куда будет отправлен запрос. Каждый веб-сервер Nginx, предназначенный для распределения нагрузки, находится в независимом контуре, состоящем из самого веб-сервера, модуля Nemesida WAF API и СУБД PostgreSQL и настроен, например, следующим образом:

Пример конфигурации
upstream nw-api.example.com {
    server 10.0.0.1 max_fails=3 fail_timeout=30s;
    server 10.0.0.2 backup;
}

server {
    ...
    location / {
        proxy_pass http://nw-api.example.com;
        }
    ...
}

При такой конфигурации, независимо от того, на какой Nginx поступит запрос, он будет сначала отправлен на сервер с IP-адресом 10.0.0.1 (зеленое направление), где работает модуль Nemesida WAF API в стандартном режиме.

3. Если сервер 10.0.0.1 недоступен, то запрос будет отправлен на сервер с IP-адресом 10.0.0.2 (оранжевое направление), где работает модуль Nemesida WAF API в режиме «Read Only».

Устранение ошибок синхронизации

В случаях ошибок при синхронизации базы данных можно запустить повторную синхронизацию. Для этого необходимо:

1. Остановить PostgreSQL или кластер:

# service postgresql stop

или

# pg_ctlcluster 13 slave stop

2. Создать резервную копию файла pg_hba.conf:

# cp /etc/postgresql/13/main/pg_hba.conf /etc/postgresql/13/main/pg_hba.conf.bak

3. Удалить рассинхронизированные базы данных:

# rm -rf /var/lib/postgresql/13/main/*

4. Запустить повторную синхронизацию:

# su postgres
$ pg_basebackup -h 10.0.0.1 -U repluser -D /var/lib/postgresql/13/main --write-recovery-conf

5. Убедиться, что новый файл pg_hba.conf идентичен предыдущему:

# diff /etc/postgresql/13/main/pg_hba.conf /etc/postgresql/13/main/pg_hba.conf.bak

6. Запустить сервис PostgreSQL или кластер:

# service postgresql start

или

# pg_ctlcluster 13 slave start

7. Проверить статус кластера:

# pg_ctlcluster 13 slave status