Network UPS Tools (NUT) – это клиент-серверная система мониторинга и управления источниками бесперебойного питания (ИБП). networkupstools.org

На этой странице представлена настройка NUT для отправки уведомления при пропадании электропитания от сети и отключения ИБП с помощью скриптов и расписания.

Настройка основана на первоначальной инструкции с этой страницы, в которой представлена установка и настройка до этапа использования скриптов.

При стандартной настройке NUT (без дополнительных скриптов) система делает только самое необходимое: следит за состоянием ИБП и может выключить сервер при критическом разряде батареи.

 

Требования от NUT в представляемом сценарии:

-отправить оповещение о пропадании электропитания от сети 220В;

-отправить оповещение о низком уровне заряда батареи ИБП;

-завершить работу сервера (гипервизора) с виртуальными машинами Proxmox при разряде батареи ИБП;

Завершение работы сервера при разряде АКБ ИБП может выполнятся по следующим критериям: событие LOWBATT (LB), оставшееся время работы (battery.runtime, если поддерживается) или таймер после перехода на батарейное питание.

Отключение сервера по уровню заряда аккумулятора (например, 15%) возможно только в том случае, если ИБП передает в NUT значение battery.charge. В представленном ИБП этот параметр не передается.

Поскольку процент заряда недоступен, а используется протокол Megatec, наиболее предсказуемым вариантом будет настроить расписание с таймером. Такой сценарий не зависит от того, умеет ли ИБП корректно сообщать процент заряда батареи, и обычно оказывается более надежным. Недостаток в том, что время работы от ИБП может уменьшатся по мере износа батареи и за этим нужно следить.

 

Используемые средства.

upssched – это планировщик событий NUT. Он запускает таймеры при наступлении событий (например, переход на батарею) и выполняет заданные действия по истечении таймера или при отмене.

upssched-cmd – это скрипт-обработчик, который вызывается upssched для выполнения конкретных действий (выключение сервера, отправка уведомлений и т.п.). Содержит логику, что именно делать при срабатывании таймера.

Схема взаимодействия планировщика и скрипта.

 

Скрипт.

Далее представлен проверочный скрипт, который срабатывает через 5мин. после пропадания электропитания. Т.е. настраиваем этот скрипт, вытаскиваем провод ИБП из розетки 220В и ждем 5мин. Скрипт должен сработать и завершить работу Proxmox. 5мин используется для быстрой проверки скриптов. В реальной рабочей обстановке время рассчитывается исходя из мощности нагрузки, емкости и качества батареи.

Правильный подход – рассчитать время, в течение которого ИБП может держать нагрузку, и задать таймер с запасом. Например, ИБП держит нагрузку 20 минут, выставляем таймер на 15 минут. Тогда у сервера будет 15 минут на работу от батареи, и еще 5 минут в запасе на случай, непредвиденных ситуаций. Это гарантирует корректное завершение работы сервера до полного разряда батареи.

 

Создаем файл скрипта.

 

Содержание.

Скрипт безопасно выключает сервер только в том случае, если питание отсутствует более заданного времени (5 минут в тестовом режиме). При восстановлении питания выключение отменяется. Выполняется логирование всех действий.

 

Разрешаем пользователю nut выключать систему.

В NUT 2.8.1 пользовательский скрипт (CMDSCRIPT) выполняется от имени пользователя nut, а не root. Если скрипт вызывает команды, требующие административных привилегий (например, shutdown или systemctl poweroff), пользователю nut необходимо предоставить соответствующие права (например, через sudo или другой механизм делегирования привилегий). Если это не сделать, выполнение скрипта завершается сообщением Call to PowerOff failed: Access denied.

 

Убеждаемся, что установлен sudo.

 

Если команда ничего не выводит устанавливаем.

 

Создаем правило.

 

Содержимое:

Сохраняем, выходим.

 

Права доступа.

 

В результате, это правило разрешает пользователю nut выполнять команду выключения сервера (shutdown) от имени root без ввода пароля.

 

Если нужно несколько разных скриптов.

upssched позволяет указать только один скрипт в upssched.conf через директиву CMDSCRIPT. Но внутри этого скрипта можно вызывать другие скрипты. А сами скрипты положить в отдельную папку, например, /etc/nut/scripts/.

Один скрипт – для простых сценариев (до 5-7 действий). Легче править и видеть всё сразу.

Несколько скриптов – когда логика становится сложной, много повторяющихся действий.

Имя файла не обязательно upssched-cmd. По умолчанию в примерах используется /etc/nut/upssched-cmd, но это просто традиция.

 

Делаем скрипт исполняемым.

+x – добавляет флаг «исполняемый» (execute) для всех пользователей.

 

Планировщик.

Планировщик добавляет скрипту возможность отложенного выполнения и гибкого управления событиями, потому что представленный скрипт умеет только сделать что-то один раз в момент запуска.

Реализовать отложенное выключение с отменой можно и с помощью самодельного скрипта, но это потребует сложной логики с фоновыми процессами, ручным управлением таймерами и проверками статуса. upssched берёт всю эту сложность на себя, делая настройку надёжной, прозрачной и простой в поддержке.

Настраиваем планировщик NUT.

 

Содержание.

Конструкции EXECUTE, START-TIMER, CANCEL-TIMER и тп, это встроенные команды (директивы) конфигурационного файла upssched.conf существующие специально для описания логики отложенных действий в NUT. Они представляют собой специализированный синтаксис для описания правил, который понимает планировщик upssched.

 

Настройка upsmon.conf.

Нужно убедится, что upsmon умеет вызывать upssched.

 

Раскомментируем (или добавим, если нет) эти строки.

SYSLOG+WALL+EXEC – это флаги уведомлений, которые указывают upsmon, как именно обрабатывать событие. Они объединяются знаком + и могут использоваться в любой комбинации.

SYSLOG – записывает сообщение о событии в системный лог.

WALL – отправляет сообщение всем пользователям, которые сейчас залогинены в системе.

EXEC – выполняет программу, указанную в NOTIFYCMD (в данном случае – upssched).

 

Перезапускаем службы NUT

 

Проверка.

Выключаем питание ИБП из розетки. Сервер переходит на батарею. NUT фиксирует событие ONBATT и запускает таймер на 5 минут.

Через 5 минут (если не подсоединить провод обратно) срабатывает скрипт.

В логе (/var/log/upssched.log) появляется запись о том, что скрипт сработал.

Сервер начнет процедуру выключения: сначала мягко завершатся работа всех ВМ, затем выключится сам Proxmox.

Если подсоединить провод обратно в течение 5 минут, NUT фиксирует событие ONLINE (питание вернулось). Таймер отменяется. Выключение не произойдет.

Для мониторинга процесса в реальном времени после того, как вытащили провод из розетки, лучше всего использовать команду для просмотра логов в реальном времени. Вот какие команды подойдут.

 

Основная команда для просмотра лога NUT в реальном времени

-u nutmonitor.service – показывает логи службы мониторинга (upsmon), которая фиксирует события ONBATT и ONLINE.

-u nutserver.service – показывает логи сервера (upsd), который получает данные от драйвера.

-f – режим «follow», то есть видны новые строки лога в реальном времени.

 

Альтернативный вариант: смотреть логи скрипта (если настроено как предлагалось выше).

 

Файл лога может затребовать права на доступ, поэтому его нужно предварительно создать вручную и задать права.

Создание лог-файла.

 

Даем права владельца для nut.

 

Можно проверить выполнение скрипта вручную. Proxmox завершит работу.

 

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

Далее идет усложнение того, что уже настроено.

 

Оповещение о событии по email.

NUT не позволяет автоматически отправлять уведомления о событиях ИБП своими встроенными возможностями. Для этого используется скрипт, выполняющийся при наступлении выбранных событий. Скрипт может отправлять уведомления по электронной почте или каким-то другими способами. В данном случае рассматривается email.

 

mail – консольная утилита для формирования и передачи сообщений локальному почтовому агенту (Mail Transfer Agent, MTA).

Проверка почтовой системы.

Вывод означает, что файл принадлежит пакету Postfix. Значит, в данном случае MTA – Postfix.

Postfix – это почтовый сервер. mail передает письмо сервису Postfix, который выполняет фактическую отправку через внешний SMTP-сервер. Задача Postfix принять письмо от программы mail (или подобных), определить, куда его доставить, установить SMTP-соединение с сервером получателя и отправить письмо.

Альтернатива Postfix – это msmtp. Он проще и легче, но так как Postfix уже присутствует в Proxmox используем его.

Настраиваем Postfix как SMTP-клиент (relay). При такой настройке Postfix не работает как почтовый сервер в Интернете, а лишь пересылает всю исходящую почту через SMTP заданного сервиса, например Яндекса.

Схема выглядит так.

 

Подготавливаем email.

Для Яндекса нельзя использовать обычный пароль учетной записи. Нужно создать пароль приложения в настройках безопасности аккаунта.

 

Настройка Postfix.

main.cf – основной конфигурационный файл Postfix. В нем задаются параметры работы: имя сервера, SMTP-сервер для отправки почты, способы аутентификации, использование TLS/SSL и другие настройки.

Редактируем main.cf.

 

Минимально необходимая конфигурация.

myhostname = pve-orthanc.pc360.local – имя текущего сервера, используемое Postfix в заголовках и идентификации при отправке почты.

mydestination = localhost – список доменов, для которых Postfix считает почту локальной доставкой.

inet_interfaces = loopback-only –  postfix принимает соединения только с локального интерфейса (не является почтовым сервером для сети).

mynetworks = 127.0.0.0/8 – разрешенные доверенные сети, которым разрешена отправка через Postfix без дополнительной проверки.

inet_protocols = ipv4 – использование только IPv4 (отключение попыток отправки через IPv6).

relayhost = [smtp.yandex.ru]:465 – внешний SMTP-сервер, через который Postfix отправляет почту.

smtp_tls_wrappermode = yes – использование прямого TLS-соединения (SMTPS) при подключении к порту 465.

smtp_tls_security_level = encrypt – требование обязательного шифрования TLS при отправке.

smtp_tls_CAfile = /etc/ssl/certs/ca-certificates.crt – файл доверенных сертификатов для проверки TLS-сервера.

smtp_sasl_auth_enable = yes – включение авторизации на внешнем SMTP-сервере.

smtp_sasl_password_maps = hash:/etc/postfix/sasl_passwd – файл с логином и паролем для SMTP-авторизации.

smtp_sasl_security_options = noanonymous – запрет анонимной SMTP-аутентификации.

smtp_sasl_tls_security_options = noanonymous – запрет анонимной аутентификации при использовании TLS.

smtp_generic_maps = hash:/etc/postfix/generic – замена локальных адресов отправителя на корректный внешний email-адрес.

compatibility_level = 3.6 – уровень совместимости Postfix с настройками и поведением версии 3.6+.

Данная конфигурация превращает Postfix в локальный почтовый агент только для исходящей отправки уведомлений через внешний SMTP-сервер Яндекс. Входящая почта и прием сообщений из сети не используются.

 

Создаем файл с учетными данными.

 

Содержимое:

 

Защита пароля.

 

Создаем хэш.

Это нужно делать при каждой смене пароля или изменении в файле sasl_passwd.

 

После этого появится файл

 

Просмотр наличия файла.

Postfix не умеет читать обычный текстовый файл. Он читает специальную базу данных Berkeley DB. Команда postmap создает нужный формат файла.

 

Устанавливаем пакет для выполнения SMTP-авторизации из postfix.

 

Перезапускаем Postfix

 

Проверяем статус.

 

Преобразования адресов отправителя.

Настройка используется для замены локальных адресов (например, root@pve.local) на действительный внешний почтовый адрес перед отправкой через SMTP.

Если этого не сделать, отправка завершается ошибкой 553 5.7.1 Sender address rejected: user not found. Потому что Postfix будет пытаться отправлять письма от имени root@pve.local или nut@pve.local, а таких почтовых ящиков на Яндексе не существует.

 

Создаем файл.

 

Содержимое.

 

Создаем базу.

Эта команда компилирует текстовый файл /etc/postfix/generic в служебную базу данных generic.db, используемую Postfix.

Т.е. мы редактируем обычный текстовый файл generic, команда postmap создает рядом файл generic.db. Именно этот файл .db читает Postfix во время работы.

После каждого изменения файла generic необходимо снова выполнять postmap.

 

В main.cf добавляем строку (уже добавлена выше).

 

Перезапускаем Postfix.

 

В результате, не важно кто отправляет письмо: Mail, скрипт NUT или другие системные службы, все письма автоматически будут отправляться от адреса Яндекса, который авторизован на SMTP.

 

Выполняем тестовую отправку.

 

На email приходит сообщение.

Если не приходит, смотрим логи и очередь, выявляем причины и устраняем.

 

Проверка очереди.

 

Очистка очереди.

(если понадобится убрать не отправленные сообщения)

 

Просмотр логов.

 

Отправка сообщений из скрипта.

Последовательность выполнения.

upsmon первым узнает обо всех событиях ИБП.  Его конфигурация настроена выше.

Строки NOTIFYFLAG в конфиге указывают, что делать, когда произошло конкретное событие.

Например, NOTIFYFLAG ONBATT SYSLOG+WALL+EXEC означает – при переходе на батарею выполнить три действия:

-записать сообщение в системный журнал (SYSLOG);

-показать сообщение всем пользователям (WALL);

-выполнить внешнюю программу (EXEC).

 

Внешняя программа указана здесь:

Поэтому запускается именно upssched.

 

Далее работает upssched.conf где написано:

 

Последовательность получается такая.

Так как уже есть готовый upssched-cmd, и он выполняется только там, где действительно нужно, чтоб не плодил дополнительные скрипты, можно добавить отправку email внутри этого скрипта.

Логика скрипта получится такой.

Всё находится в одном файле. Это удобно сопровождать.

Такая схема принята в работу.

 

Настраиваем скрипт upssched-cmd.

 

Содержание.

 

Делаем файл исполняемым, чтобы NUT мог запускать его при возникновении событий.

 

Скрипт с отключением по статусу LB.

Для большинства случаев отключение по статусу LB (Low Battery) логичнее. Механизм NUT сам отслеживает состояние ИБП и инициирует выключение, когда ИБП сообщает, что заряд достиг критического уровня. Не нужно рассчитывать время работы или корректировать его после старения аккумуляторов.

В таком варианте скрипт остается таким же, в нем меняется только описание события. Вот его содержание (на всякий случай).

 

Вся логика действий изменяется в файле планировщика. Нужно изменить upssched.conf так, чтобы shutdown_proxmox вызывался не по таймеру, а по событию LOWBATT.

 

Редактируем конфигурацию планировщика.

 

Вставляем такое содержание.

 

По сравнению с первоначальной конфигурацией, представленной в начале страницы, из нее удалены только две строки.

 

Вместо них добавлена одна.

 

Проверка.

Отключаем электропитание. Весь настроенный механизм отрабатывает и на email приходит оповещение.

Что и требовалось.

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