Недавно на одном из проектов для телекоммуникационной компании нам пришлось дополнительно (не без помощи коллег из ИБ) проработать вопрос безопасного использования паролей для подключения к базе данных PostgreSQL кластера Zabbix.

Прописывать пароль для доступа к базе данных в явном виде в конфигурационном файле небезопасно. В таких случаях обычно ограничиваются возможностями разграничения прав к конфигурационным файлам Zabbix на уровне операционных систем.

Но вернемся к нашей задаче. Изучив входные данные об инфраструктуре заказчика, мы сразу обратили внимание, что коллеги в сегменте ИБ уже используют решение от HashiCorp — Vault, что и стало для нас отправной точкой:

  • во-первых, Zabbix отлично интегрируется с решениями от HashiCorp;

  • во-вторых, у нас есть опыт работы с HashiCorp Vault.

Основной целью было обезопасить конфигурацию HA Zabbix, убрав указываемые в явном виде логины и пароли для подключения к базе данных PostgreSQL. Сделать это нужно было так, чтобы наше решение было совместимо с уже применяемым стеком на стороне заказчика.

Итак, в этом посте пройдемся по нескольким шагам:

  1. Рассмотрим нашу схему работы HA Zabbix и дадим краткую характеристику данному стеку.

  2. Рассмотрим предполагаемый вариант использования Vault в связке с HA Zabbix.

  3. Предложим конфигурацию для данного решения.

Схема работы HA Zabbix

В части сбора, хранения и анализа метрик от сервисов мы достаточно часто используем связку HA Zabbix и Patroni (рис. 1).

Рисунок 1. Общая схема HA Zabbix-PostgreSQL

Почему выбрана именно такая технология? Patroni позволяет создавать высокодоступный кластер PostgreSQL на основе потоковой репликации. Учитывая наличие автоматического контролируемого и аварийного переключения между нодами (master-standby-replica) Patroni PostgreSQL, использование Zabbix в связке с PostgreSQL позволяет нам, по большей степени, не беспокоиться о доступности базы данных.

Не будем углубленно рассматривать схему реализации HA Zabbix, она немало изучена в других статьях, а лишь напомним, что Zabbix, начиная с версии 6.0, под «капотом» имеет механизм кластеризации. В нашей мониторинговой «теме» принципиально важно иметь высокодоступный «монитор» — в нашем случае это HA Zabbix 6.0

Включается режим HA в zabbix_server.conf в переменных HANodeName и NodeAddress и для zabbix_agentd.conf в переменных Server и ServerActive. Получится что-то наподобие такой схемы, как на рис. 2.

Рисунок 2. HA Zabbix кластер

Здесь у нас есть два хоста в статусе Active и Standby. Учитывая наличие в нашей схеме HAProxy и keepalived (рис. 1), мы имеем VIP IP 10.125.140.90. Именно по этому IP мы и подключаемся к Active ноде нашего Zabbix. Пример конфигурации для балансировки HA Zabbix:

listen Zabbix

    bind 10.125.140.90:8118

    default_backend zabbix_server

    option httpchk OPTIONS /zabbix

backend zabbix_server

    balance roundrobin

    server zbx01 10.125.140.80:80 check #port 80

    server zbx02 10.125.140.81:80 check #port 80

где server zbx01 и server zbx02 — ноды Zabbix, bind 10.125.140.90 — VIP IP.

Балансировка кластера Patroni также настраивается в HAProxy.

Напомним, что для доступа к PostgreSQL в конфигурационном файле Zabbix — zabbix_server.conf — нужно заполнить две переменные: DBUser и DBPassword, соответственно, логин и пароль от базы данных Zabbix в PostgreSQL. Важно не забыть это сделать не только на Active ноде, но и на Standby (рис. 1).

Используем Vault в связке с HA Zabbix

К нашим входным данным мы добавим Vault и остановимся на составляющих (рис. 3).

Рисунок 3. Общая схема HashiCorp Consul и HA Vault

Для работы Vault используется key-value хранилище Consul.

В нашем мониторинговом решении также присутствовала одна база данных по типу key-value — etcd (рис. 1). Patroni вполне хорошо работает и с Consul, но мы учитываем требование коллег из ИБ не смешивать две системы Consul/HA Vault и Zabbix/Patroni.

Глубокий анализ настроек Consul и Vault в этом посте мы разбирать не будем (как и с HA Zabbix/Patroni, этот вопрос неоднократно уже изучался на Хабр), выделим лишь составные хосты HashiCorp Consul и HA Vault.

У нас есть две ноды Vault в статусах Active и StandBy (рис. 4) и три ноды Consul, одна из которых в статусе Leader (рис. 5).

Рисунок 4. HA Vault
Рисунок 5. Основной состав кластера Consul

После этого краткого обзора кластера HashiCorp Consul и HA Vault предполагаемая схема приобретает вид, показанный на рис. 6.

Рисунок 6. Схема HA Zabbix/Patroni – Vault/Consul

Обратим внимание, что кластер HashiCorp Consul и HA Vault пока никак не связан с нашими сервисами (HAproxy – Zabbix/Patroni), поэтому перейдем к основной части нашей работы.

Настраиваем конфигурацию

Для включения Vault в Zabbix переменные DBUser и DBPassword в конфигурационном файле zabbix_server.conf необходимо выключить (что мы и сделаем):

#DBUser=*****

#DBPassword=*****

Переменные VaultToken, VaultURL, VaultDBPath включить.

VaultURLвнимание! — это адрес нашей Active ноды Vault (см. выше), ну и VaultDBPath — путь к нашим секретам. Все эти данные нам предоставлены.

Но если с VaultToken и VaultDBPath всё понятно (на всякий случай можно почитать тут), то по VaultURL требуется уточнение.

Переменная VaultURL в zabbix_server.conf принимает только один сетевой адрес, но, как мы помним, у нас две ноды HA Vault (Active-StandBy). Если указать Active, всё хорошо до тех пор, пока она активна, а если потребуется ноду вывести из обслуживания, что тогда? Выход — наш балансировшик HAProxy.

Вспомним, что у нас решение по балансировке HA Zabbix уже есть, мы ходим на одну из нод Zabbix (Active) по VIP IP (10.125.140.90), так почему бы не воспользоваться схожей конфигурацией и не «забалансить» наш HA Vault?

Решаем!

Конфигурация на первом и на втором узле HAProxy идентична:

frontend vault

     mode tcp

     bind *:8200

     bind *:443 ssl cert /etc/haproxy/cert

     redirect scheme https code 301 if !{ ssl_fc }

     log global

     option tcplog

     default_backend ha_vault

backend ha_vault

     mode tcp

     timeout check 5000

     timeout server 30000

     timeout connect 5000

     option httpchk GET /v1/sys/health

     http-check expect status 200

     server node5 ***.***.***.***:8200check ssl check-ssl verify none

     server node6 ***.***.***.***:8200check ssl check-ssl verify none

где в server node5 и server node6 указываем IP наших нод Vault.

Для наглядности заглянем в Web HAProxy (рис. 7).

Рисунок 7. Результат балансировки Vault в HAProxy

Видим, что у нас сейчас активна node6 — нода Vault в статусе Active. Теперь осталось вернуться в конфигурацию Zabbix — zabbix_server.conf (у нас две ноды Zabbix, поэтому настройки должны быть идентичны):

VaultToken=s.*****************************

VaultURL=https://10.125.140.90:8200

VaultDBPath=secret/zabbix/database

где VaultURL — VIP IP.

Ну и напоследок, для принятия конфигурации:

systemctl restart zabbix-server.service

На этом настройка HA Vault / HAProxy для нашего кластера Zabbix закончена. Теперь и Zabbix, и Vault доступны по IP 10.125.140.90, и общая схема имеет следующий вид, показанный на рис. 8.

Рисунок 8. Итоговая схема HA Zabbix/Patroni и HA Vault/Consul

Цель нашей работы достигнута — в нашем конфигурационном файле zabbix_server.conf не содержится пароля к БД в явном виде, мы получили в конфигурации Zabbix единую точку доступа в HA Vault кластер.

Автор: Иван Подстольный, инженер-проектировщик отдела систем мониторинга "Инфосистемы Джет"