Недавно на одном из проектов для телекоммуникационной компании нам пришлось дополнительно (не без помощи коллег из ИБ) проработать вопрос безопасного использования паролей для подключения к базе данных 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
Рисунок 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 кластер
Рисунок 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
Рисунок 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
Рисунок 4. HA Vault
Рисунок 5. Основной состав кластера Consul
Рисунок 5. Основной состав кластера Consul

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

Рисунок 6. Схема HA Zabbix/Patroni – Vault/Consul
Рисунок 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
Рисунок 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
Рисунок 8. Итоговая схема HA Zabbix/Patroni и HA Vault/Consul

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

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

Комментарии (9)


  1. Abyss777
    23.05.2023 09:19

    В чем принципиальное отличие пароля в явном виде в конфиге zabbix от токена в явном виде в этом же конфиге, с которым можно получить этот пароль?

    Одним дополнительным curl можно превратить одно в другое...


    1. JetHabr Автор
      23.05.2023 09:19

      Бесспорно, так и есть, но тут скорее было требования по явному виду пароля в конфигурации


      1. Ign0r
        23.05.2023 09:19

        Объясните, пожалуйста, почему в качестве хранилища выбран Consul? Встроенный функционал Service Discovery и его интеграцию с HAProxy вы не используете, объем хранимых данных - ничтожен. Не проще ли ограничиться внутренним хранилищем Vault?


        1. JetHabr Автор
          23.05.2023 09:19

          Да, Consul уже используется активно в решении у заказчика, поэтому было принято решение задействовать его, об этом упомянули в статье. Спасибо за вопрос!


          1. Ign0r
            23.05.2023 09:19

            И ещё - Vault не балансируется. Все запросы перенаправляются на активный узел и выполняются там. А результат реплицируется. Так что - ваше решение немного надуманное.


            1. Ign0r
              23.05.2023 09:19

              Пардон. Вы используете HA. Я пропустил что у вас данные статичны.


    1. JetHabr Автор
      23.05.2023 09:19

      Добавлю, что нет стопроцентно безопасных решений. В данной заметке мы использовали решение из документации по настройке секретов в Zabbix (ссылка в тексте есть), или вот тут еще раз: https://www.zabbix.com/documentation/6.0/en/manual/config/secrets [Configuration parameters] На наш взгляд это вполне рабочее решение в данном конкретном случае.


      1. Abyss777
        23.05.2023 09:19

        Дак мы тоже его используем. Но оно не помогает скрывать пароль от БД zabbix. Оно для других вещей:

        Один источник правды о паролях, сменили пароль на базу - занесли его в Vault (вручную или автоматически) все инстансы zabbix его будут знать, не нужно обходить и править конфиг. Я думаю когда придумывали HA zabbix, тогда и задались вопросом, как нескольким инстансам его безопасно сообщить.

        Ну и самое главное, пароли из Vault можно использовать как значения макросов. Вот в этом случае это позволяет их скрыть от пользователей Zabbix. Инженер настраивающий хост должен знать только его путь в Vault.

        Ну или когда одна автоматизация создала пользователя например в базе для мониторинга, а другая автоматизация настроила хост в zabbix. Пароль в открытом виде нигде не передаётся, и пользователи его не увидят.

        Но если узнают токен, то это эквивалентно знанию всех паролей.


        1. JetHabr Автор
          23.05.2023 09:19

          Мы говорим о явном прописывании паролей в конфигурации. Написали об этом в начале.