87. NUT + Proxmox + Home Assistant



 Уверен что у многих, после того как увидели в заголовке первых два слагаемых, засвербело и начало нестерпимо жечь в некоторых местах. Чтож, легитимно, и именно потому что каждый имеет право на своё мнение. И именно поэтому выходит эта статья, а комментарии к ней остаются открытыми. В статье №59 уже было лёгкое знакомство с этой темой. На этот раз рассмотрим альтернативный вариант тестируемый автором уже больше года на момент написания статьи, и давший 0 сбоев и поломок.Для начала краткий экскурс для несведущих, чем и как может кому-то мешать заголовок.

Основные причины против использования NUT с Proxmox.

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

Ну и для честности, конечно стоит рассмотреть положительные стороны.

Решение NUT предлагает исключительную гибкость с поддержкой более 1500 моделей ИБП и обеспечивает эффективное управление питанием в распределенных системах, включая кластеры Proxmox с архитектурой master-slave для координированного выключения. Как открытый, легковесный инструмент, встроенный в Linux, он органично интегрируется с Debian-средой Proxmox, предоставляя широкие возможности настройки через скрипты для уведомлений, приоритетного выключения виртуальных машин и интеграции систем мониторинга, одновременно предлагая экономичную альтернативу проприетарным решениям управления ИБП.Домашние пользователи используют один или несколько хостов Proxmox, каждый из которых запускает несколько виртуальных машин и контейнеров (клиентов).
Каждый хост может выключить всех своих клиентов во время обычного выключения питания. Именно поэтому каждый хост должен знать о состоянии ИБП. Большинство ИБП имеют один порт для подключения к компьютерам или серверам для управления. На бюджетных устройствах будет USB или последовательный разъем. Более дорогие устройства часто имеют порт Ethernet. Поскольку есть только один порт (USB), это означает, что только один компьютер или сервер может напрямую взаимодействовать с ИБП.

Сервер NUT устанавливается на системе, к которой физически подключен UPS. Он позволяет ретранслировать информацию дальше по локальной сети.
Клиент NUT устанавливается на устройствах, которым необходимо получать данные о состоянии UPS от сервера, для выполнения задач.

Это приводит нас к следующим топологиям:
«Простая»: Один ИБП, один компьютер или сервер.
В этом случае (рис. А), в системе устанавливается Сервер NUT, для работы которого нужны компоненты:
  • driver - драйвер устройства ИБП, чтобы "общаться" с ним для получения данных.
  • upsd - сервис самого сервера, передающий данные об устройстве в сеть.
  • upsmon - сервис мониторинга, подключающийся к службе upsd. Из него система может получать данные на понятном ей языке и в формате, с которым уже можно что-то делать.

простой конфиг А




«Расширенная»: Один ИБП, несколько компьютеров или серверов.
Сервер NUT устанавливается только на машине, которая отвечает следующим характеристикам:
  • по роду своей деятельности доложна быть всегда включена.
  • ИБП к ней подключен напрямую.
  • эта машина подключена к локальной сети.
Клиент NUT, по сути являет собой сервис upsmon, устанавливаемый на системы, которым нужно получать данные о состоянии ИБП.

расширенный конфиг Б


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


Настройка NUT.

Перейдём от теории к практике.
Из условий и требований выше становится понятно что в большинстве случаев роль NUT сервера с успехом может выполнять сам Proxmox.
На него-то и будем ставить софт.

Для начала обновимся или убедимся в отсутствии обновлений:
apt update -y

NUT поставим с помощью команды:
apt install nut -y


В дальнейшем необходимо будет отредактировать несколько файлов. Вот их имена и назначение:

Этот файл сообщает установленному Network UPS Tools, в каком режиме он должен работать. В зависимости от этой настройки затем запускаются требуемые модули.
расположение: /etc/nut/nut.conf

Этот файл считывается контроллером драйвера. Он сообщает Network UPS Tools, с каким типом устройства ИБП ему приходится работать. Некоторые настройки для управления связью с устройством. Также некоторые параметры устройства ИБП могут быть переопределены.
расположение: /etc/nut/ups.conf

С его помощью происходит управление доступом к серверу и определение некоторые других значений конфигурации.
расположение: /etc/nut/upsd.conf

Административные команды, такие как настройка переменных и прочие, могут быть опасны, поэтому доступ к ним должен быть ограничен.
Этот файл определяет, кто может получить к ним доступ и что доступно.
Каждый пользователь получает свой собственный раздел. Поля в этом разделе устанавливают параметры, связанные с привилегиями этого пользователя.
Раздел начинается с имени пользователя в скобках и продолжается до следующего имени пользователя в скобках или конца файла. Эти пользователи независимы от пользователей прописанных в системе.
расположение: /etc/nut/upsd.users

Основная задача этого файла — определить устройства, которые необходимо отслеживать, и сообщить серверу, как при необходимости завершить работу системы.
Также, в этом файле можно задать другие необязательные параметры.
расположение: /etc/nut/upsmon.conf

Этот файл контролирует деятельность планировщика, вспомогательной программы-таймера для службы мониторинга.
расположение: /etc/nut/upssched.conf

Этот скрипт используется для вызова команд при срабатывании таймеров.
расположение: /etc/nut/upssched-cmd

Итак, поехали.
Первым делом найдём в системе подключенный (с большой долей вероятности по USB кабелю) UPS.
Для этого выпоним команду:

lsusb

Она отобразит устройства подключенные таким образом. Обращаем внимание на номер шины и номер устройства на ней.


В данном примере на шине номер 2 устройство номер 2 опознаётся как UPS.
Чтобы прочитать информацию нужного устройства с юсб порта, выполним следующую команду: lsusb -v -s [шина]:[устройство]
Т.е. в данном случае: lsusb -v -s 2:2


Отлично, устройство передаёт о себе данные и "разговаривает" с системой. Можно приступать к настройке сервера. Для начала запустим сканирование, чтобы узнать как именно сервер "видит" наш ИБП. Выполняем команду:

nut-scanner -U


и сохраняем полученные результаты в любой текстовый файл в сторону. Эти данные понадобятся в дальнейшем.

Начинаем работать с файлами.

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

nut.conf

Бэкапим: cp /etc/nut/nut.conf /etc/nut/nut.example.conf
Редактиируем оригинал: nano /etc/nut/nut.conf
Удаляем содержимое и вставляем строку:
MODE=netserver


ups.conf

Бэкапим: cp /etc/nut/ups.conf /etc/nut/ups.example.conf
Редактиируем оригинал: nano /etc/nut/ups.conf
Удаляем содержимое и вставляем строки:


pollinterval = 15
maxretry = 3

offdelay = 120
ondelay = 240

Далее в этом же файле создаём конфиг для нашего ЮПС.
В первой строке в квадратных скобках указываем имя с которым он будет отображаться на сервере, и которое будет выдаваться в сеть для клиентов. Использовать можно только латинские буквы и цифры, без пробелов и спецсимволов.
В остальные строки подставлем значения полученные на предыдущем шаге, когда выполняли команду "nut-scanner -U" и сохранили в сторону результат её выполнения.

[apc]
        driver = usbhid-ups
        port = auto
        desc = "APC Back-UPS BX1400U-FR"
        vendorid = 051D
        productid = 0002
        serial = xxxxxxxxxxxx

upsd.conf

Бэкапим: cp /etc/nut/upsd.conf /etc/nut/upsd.example.conf
Редактиируем оригинал: nano /etc/nut/upsd.conf
Удаляем содержимое и вставляем строки:

LISTEN 0.0.0.0 3493
LISTEN :: 3493

Указывая адрес 0.0.0.0 мы "говорим" серверу "слушать" входящие соединения на всех сетевых интерфейсах по указанному номеру порта. (вспоминаем статью про SDN в Proxmox)

upsd.users

Бэкапим: cp /etc/nut/upsd.users /etc/nut/upsd.example.users
Редактиируем оригинал: nano /etc/nut/upsd.users
Удаляем содержимое и вставляем строки:

[upsadmin]
# Administrative user
password = ********
# Allow changing values of certain variables in the UPS.
actions = SET
# Allow setting the "Forced Shutdown" flag in the UPS.
actions = FSD
# Allow all instant commands
instcmds = ALL
upsmon master

[upsuser]
# Normal user
password = ********
upsmon slave

Здесь в квадратных скобках указывается имя пользователя, с которым клиенты смогут подключаться к сереверу для управления и получения данных. В первом блоке создаётся администратор, с максимальными правами доступа и управления устройством. Так же указывается режим работы сервиса upsmon - ведущий.
Во втором блоке создаётся ведомый пользователь, именно его будут использовать клиенты для подключения.
Не забываем сменить ******* на свои пароли по усмотрению.

Логика проста.
Есть всего 2 пользователя.
Административный - может как получать данные так и отправлять команды на устройство.
Обычный - находится в режиме только для чтения относительно устройства.

upsmon.conf

Бэкапим: cp /etc/nut/upsmon.conf /etc/nut/upsmon.example.conf
Редактиируем оригинал: nano /etc/nut/upsmon.conf
Удаляем содержимое и вставляем строки: 

RUN_AS_USER root
MONITOR apc@localhost 1 upsadmin ******* master

MINSUPPLIES 1
SHUTDOWNCMD "/sbin/shutdown -h"
NOTIFYCMD /usr/sbin/upssched
POLLFREQ 4
POLLFREQALERT 2
HOSTSYNC 15
DEADTIME 24
MAXAGE 24
POWERDOWNFLAG /etc/killpower

NOTIFYMSG ONLINE "UPS %s on line power"
NOTIFYMSG ONBATT "UPS %s on battery"
NOTIFYMSG LOWBATT "UPS %s battery is low"
NOTIFYMSG FSD "UPS %s: forced shutdown in progress"
NOTIFYMSG COMMOK "Communications with UPS %s established"
NOTIFYMSG COMMBAD "Communications with UPS %s lost"
NOTIFYMSG SHUTDOWN "Auto logout and shutdown proceeding"
NOTIFYMSG REPLBATT "UPS %s battery needs to be replaced"
NOTIFYMSG NOCOMM "UPS %s is unavailable"
NOTIFYMSG NOPARENT "upsmon parent process died - shutdown impossible"

NOTIFYFLAG ONLINE   SYSLOG+WALL+EXEC
NOTIFYFLAG ONBATT   SYSLOG+WALL+EXEC
NOTIFYFLAG LOWBATT  SYSLOG+WALL+EXEC
NOTIFYFLAG FSD      SYSLOG+WALL+EXEC
NOTIFYFLAG COMMOK   SYSLOG+WALL+EXEC
NOTIFYFLAG COMMBAD  SYSLOG+WALL+EXEC
NOTIFYFLAG SHUTDOWN SYSLOG+WALL+EXEC
NOTIFYFLAG REPLBATT SYSLOG+WALL
NOTIFYFLAG NOCOMM   SYSLOG+WALL+EXEC
NOTIFYFLAG NOPARENT SYSLOG+WALL

RBWARNTIME 43200
NOCOMMWARNTIME 600

FINALDELAY 5

Обращаем внимание что в первой строке указываем то имя ЮПС, которое ранее указали в файле ups.conf.
И имя пользователья администратора и его пароль указанные в файле upsd.users.

upssched.conf

Бэкапим: cp /etc/nut/upssched.conf /etc/nut/upssched.example.conf
Редактиируем оригинал: nano /etc/nut/upssched.conf
Удаляем содержимое и вставляем строки:

CMDSCRIPT /etc/nut/upssched-cmd
PIPEFN /etc/nut/upssched.pipe
LOCKFN /etc/nut/upssched.lock

AT ONBATT * START-TIMER onbatt 30
AT ONLINE * CANCEL-TIMER onbatt online
AT LOWBATT * EXECUTE onbatt
AT COMMBAD * START-TIMER commbad 30
AT COMMOK * CANCEL-TIMER commbad commok
AT NOCOMM * EXECUTE commbad
AT SHUTDOWN * EXECUTE powerdown
AT SHUTDOWN * EXECUTE powerdown

upssched-cmd

Бэкапим: cp /etc/nut/upssched-cmd /etc/nut/upssched-cmd.example
Редактиируем оригинал: nano /etc/nut/upssched-cmd
Удаляем содержимое и вставляем строки:

#!/bin/sh
 case $1 in
       onbatt)
          logger -t upssched-cmd "UPS running on battery"
          ;;
       shutdowncritical)
          logger -t upssched-cmd "UPS on battery critical, forced shutdown"
          /usr/sbin/upsmon -c fsd
          ;;
       upsgone)
          logger -t upssched-cmd "UPS has been gone too long, can't reach"
          ;;
       *)
          logger -t upssched-cmd "Unrecognized command: $1"
          ;;
 esac

Сохраняем файл и выходим из него. Теперь сделаем этот скрипт запускаемым:

chmod +x /etc/nut/upssched-cmd

Выдыхаем, первый и самый сложный этап настройки позади. Осталось перезапустить сервисы и проверить всё ли корректно работает.

Перезагрузка.

Чтобы применить изменения необходимо сделать полный перезапуск всему хосту Proxmox, либо вручную перезапустить только необходимые сервисы:
service nut-server restart
service nut-client restart
systemctl restart nut-monitor
upsdrvctl stop
upsdrvctl start

после чего проверить соединение командой:
upsc [имя_юпс_из_файла_ups.conf]@localhost
т.е. в случае примера из данных выше, это будет upsc apc@localhost
Если все настройки были совершены точно и без ошибок, то увидим ответ от нашего ИБП



Безопасность.

Демон upsd (ядро nut-server) работает от пользователя nut.
Это видно по выводу команды: systemctl status nut-server
Если проверить одноимённую группу пользователей nut, то пользователь запускающий сервер в ней может не находиться.
getent group nut
Поэтому будем исправлять ситуацию добавив этого пользователя в его группу
usermod -aG nut nut

Теперь настроим права доступа на всю директорию сервера и его файлы
Сменим владельца всех файлов и папок в /etc/nut на root, а группу на nut.
chown -R root:nut /etc/nut

Ограничим доступ к каталогу только для владельца и группы.
chmod 0770 /etc/nut

Ограничим доступ к файлам: только чтение/запись для владельца, только чтение для группы, ничего для остальных.
chmod 0640 /etc/nut/*

Только root может редактировать конфиги.
Служба (благодаря членству в группе nut) может читать конфиги и выполнять скрипты.

Перезапустим службу, чтобы применились права:
systemctl restart nut-server

Работа с UPS.

Прежде всего стоит проверить какие функции предоставляет само устройство через всю настроенную только что связку.
Делается это командой upscmd -l [имя_юпс_из_файла_ups.conf]@localhost
Ну или в нашем случае: upscmd -l apc@localhost
Эта команда выведет список всех доступных мгновенных команд (instant commands).


Здесь можно увидеть одну команду, которой наверняка захотят воспользоваться многие.
Ранее, выполнив команду upsc [имя_юпс_из_файла_ups.conf]@localhost можно было увидеть параметр ups.beeper.status: enabled
Это значит что встроенная в устройство пищалка находится во включенном состоянии, и при отключении электричества устройство будет подавать звуковой сигнал.
Чтобы отключить этот сигнал воспользуемся командой
upscmd [имя_юпс_из_файла_ups.conf]@localhost beeper.toggle и система запросит указать имя пользователя, от имени которого будет выполнено действие. Укажем административного пользователя из файла upsd.users, после чего система запросит его пароль, и команда сработает.
После повторного запуска  upsc [имя_юпс_из_файла_ups.conf]@localhost увидим что параметр ups.beeper.status: изменился на disabled.
Так же можно сделать это действие одной командой, указав в ней данные пользователя:
upscmd -u <user> -p <password> [имя_юпс_из_файла_ups.conf]@localhost beeper.disable
Где <user> и <password> — учётные данные из файла /etc/nut/upsd.users

Настройка Home Assistant.

После всех выполненных работ делается максимально легко и просто.
Единственное с чем стоит заранее определиться, это каким именно образом ХА будет взаимодействовать с NUT сервером, т.к. по сути у нас есть 2 варианта:
- через обычную сеть (свой домашний LAN)
- через сеть SDN.

В чём разница?

ХА установлен на хосте с проксмоксом.

Если общение между ними происходит по обычной сети, то в случае сбоев электричества, может оказаться что свич или раутер в который подключен хост не работает. Мало ли по каким причинам, просто решил сгореть или может нерадивый админ не подключил его к ИБП, или же по какой-то причине выскочил сетевой кабель, в общем не суть важно. При наличии проблем с физической локальной сетью, получаем что виртуальная система работающая на железке не может общаться с этой же железкой.

В случае с SDN, наличие или отсутствие физической локальной сети никак не влияет, т.к. используется внутренняя сеть на уровне самой железки. В качестве бонуса, лишний трафик не бегает по домашней сети.

В итоге, если виртуальная машина с ХА не подключена к SDN, то делаем настройку через обычную сеть и указываем обычный адрес проксмокса.
Если  виртуальная машина с ХА подключена к SDN, то используем его и указываем адрес проксмокса в сети SDN.

Где указывать?
В одноимённой интеграции или же просто нажав на кнопку


После чего заполняем поля и сохраняемся


Ну а дальше уже смотрим какое устройство с какими сущностями появилось в системе и на основе их показаний делаем желаемые автоматизации.

нескончаемый респект авторам оригинальных статей:

Комментарии