Настройка NUT для управления ИБП с нескольких серверов

NUT — это Network UPS Tools или набор программных компонентов, предназначенных для мониторинга силовых устройств, таких как источники бесперебойного питания (ИБП), блоки распределения питания, солнечные контроллеры и блоки питания серверов.

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

Как настроить NUT на Linux и Windows серверах ? Читаем ниже.

Исходные данные:
1. В локальной сети организации есть 2 сервера под управлением Debian 8.9 (jessie) и 1 сервер под управлением Windows Server 2012 R2;
2. Есть ИБП компании APC, модель Smart-UPS 1000. ИБП подключен по USB к одному из серверов Debian 8.9 (jessie);

Задача:
На сервере Debian 8.9 к которому подключен ИБП установить серверную часть NUT и настроить клиентскую часть NUT на этом сервере и других серверах. В случае перехода питания серверов на ИБП и истощения заряда батарей ИБП нужно произвести корректное завершение работы всех серверов.

Распределение IP адресов во внутренней сети компании между серверами:
192.168.100.1 (srv1.mycompany.ru) — Сервер Debian 8.9 (jessie) к которому подключен APC Smart-UPS 1000 по USB — на нем будет серверная часть NUT и клиентская;
192.168.100.2 (srv2.mycompany.ru) — Сервер Debian 8.9 (jessie) — на нем будет клиентская часть NUT;
192.168.100.3 (srv3.mycompany.ru) — Сервер Windows 2012 R2 — на нем будет клиентская часть NUT;

Настройка серверной части NUT.

1. Проверим факт обнаружения нашего ИБП ядром Linux с помощью утилиты lsusb:

Для ИБП марки APC Smart-UPS значения idVendor и idProduct будут 051d и 0002 соответственно.

# lsusb -vd 051d:0002

Bus 004 Device 003: ID 051d:0002 American Power Conversion Uninterruptible Power Supply
Device Descriptor:
  bLength                18
  bDescriptorType         1
  bcdUSB               1.10
  bDeviceClass            0 (Defined at Interface level)
  bDeviceSubClass         0
  bDeviceProtocol         0
  bMaxPacketSize0         8
  idVendor           0x051d American Power Conversion
  idProduct          0x0002 Uninterruptible Power Supply
  bcdDevice            0.06
  iManufacturer           3 American Power Conversion
  iProduct                1 Smart-UPS 1000 FW:652.18.I USB FW:7.3
  iSerial                 2 AS0811123791
  bNumConfigurations      1
  Configuration Descriptor:
    bLength                 9
    bDescriptorType         2
    wTotalLength           34
    bNumInterfaces          1
    bConfigurationValue     1
    iConfiguration         11 1
    bmAttributes         0xe0
      Self Powered
      Remote Wakeup
    MaxPower               30mA
    Interface Descriptor:
      bLength                 9
      bDescriptorType         4
      bInterfaceNumber        0
      bAlternateSetting       0
      bNumEndpoints           1
      bInterfaceClass         3 Human Interface Device
      bInterfaceSubClass      0 No Subclass
      bInterfaceProtocol      0 None
      iInterface              0
        HID Device Descriptor:
          bLength                 9
          bDescriptorType        33
          bcdHID               1.10
          bCountryCode           33 US
          bNumDescriptors         1
          bDescriptorType        34 Report
          wDescriptorLength    1064
         Report Descriptors:
           ** UNAVAILABLE **
      Endpoint Descriptor:
        bLength                 7
        bDescriptorType         5
        bEndpointAddress     0x81  EP 1 IN
        bmAttributes            3
          Transfer Type            Interrupt
          Synch Type               None
          Usage Type               Data
        wMaxPacketSize     0x0006  1x 6 bytes
        bInterval             100
Device Status:     0x0001
  Self Powered

2. Установка NUT (серверной части на хосте 192.168.100.1):

apt-get install nut

Далее отредактируем файл /etc/nut/ups.conf и приведем его к виду:

[apc]
    driver = usbhid-ups
    port = auto

Этой минимальной конфигурации хватит для нашего ИБП.

Как Вы уже догадались в файле /etc/nut/ups.conf описываются все наши ИБП, а так же драйвер и их параметры для работы с NUT.

Нашему ИБП мы присвоили имя apc и будем использовать драйвер usbhid-ups.
Драйвер usbhid-ups гарантировано работает с ИБП Smart-UPS компании APC.
Более детально со списком драйверов и списком ИБП каких фирм может работать NUT описано на этой странице. Список параметров драйвера usbhid-ups можно посмотреть на этой странице.

3. Настройка драйвера NUT для работы с нашим ИБП.

Далее нам нужно установить права на наше USB устройство чтобы драйвер NUT смог работать с ним.

Для этого создадим правило /etc/udev/rules.d/90-nut-ups.rules для udev со следующим содержимым:

ACTION=="add", SUBSYSTEM=="usb", ATTR{idVendor}=="051d", ATTR{idProduct}=="0002", MODE="0660", GROUP="nut"

Далее нужно перечитать все правила, для этого выполним:

udevadm control --reload-rules
udevadm trigger

Для тех кто хочет понять в чем тут дело, объясняю:

При выводе информации по нашему ИБП с помощью lsusb мы можем увидеть строку «Bus 004 Device 003»:

# lsusb -vd 051d:0002
Bus 004 Device 003: ID 051d:0002 American Power Conversion Uninterruptible Power Supply
Device Descriptor:
...

Она говорит, что ядро Linux при подключении нашего ИБП по USB присвоило ему номер шины обмена данными 4 и id устройства 3, само наше устройство соответственно будет находится по такому пути /dev/bus/usb/004/003 а владельцем будут пользователь root и группа root с правами 664 (crw-rw-r—), но для работы драйвера NUT этого не достаточно, драйвер в таком случае не сможет управлять устройством.

С помощью файла /etc/udev/rules.d/90-nut-ups.rules и утилиты udevadm мы задали правило для сервиса udev который управляет периферией, получая от Linux ядра разного рода уведомления. По этому правилу для нового устройства с определенным idVendor и idProduct владельцем будет назначаться группа nut.

Если интересно, то запросить информацию у udev по нашему устройству можно так:

udevadm info -a -p  $(udevadm info -q path -n /dev/bus/usb/004/003)

4. Теперь запустим все драйвера NUT описанные в /etc/nut/ups.conf с помощью команды:

upsdrvctl start

Если в файле /etc/nut/ups.conf у Вас описаны несколько ИБП, то остановить конкретный драйвер или запустить его можно так:

Остановить драйвер для ИБП с именем apc
# upsdrvctl stop apc
Или запустить драйвер для ИБП с именем apc
# upsdrvctl stop apc

5. Теперь опишем права доступа к нашему серверу NUT для доступа клиентских ОС по сети, за это отвечает файл /etc/nut/upsd.conf

LISTEN 192.168.100.1 3493
LISTEN 127.0.0.1 3493

Директива LISTEN задает адрес и порт на котором будет принимать соединения демон upsd (Сервер NUT).

ВНИМАНИЕ! Директивы ACL, ACCEPT, REJECT в файле /etc/nut/upsd.conf больше не используется и является устаревшей.

6. Теперь опишем пользователей и пароли для подключения клиентских устройств к серверу NUT, за это отвечает файл /etc/nut/upsd.users:

[admin]
    password = MASTERPASSWORD
    actions = SET
    instcmds = ALL

[local_mon]
    password = xxx_local_passwd
    upsmon master

[srv2_mon]
    password = xxx_srv1_passwd
    upsmon slave

[srv3_mon]
    password = xxx_srv2_passwd
    upsmon slave

В секции [admin] мы описали пользователя для управления NUT через утилиту upscmd, а так же разрешили менять все параметры самого ИБП (строка actions = SET и instcmds = ALL).
Если нужно разрешить пользователю admin менять только определенные параметры, то их нужно описать в опции instcmds, например так:

[admin]
    password = MASTERPASSWORD
    actions = SET
    instcmds  = test.battery.start
    instcmds  = test.battery.stop

Секции [local_mon] [srv2_mon] и [srv3_mon] описывают пользователей для клиентских ОС, на них будет стоять клиентская часть NUT.
В этих секциях мы указали индивидуальные пароли (опция password) и статус этих пользователей (опция upsmon).

Для пользователя local_mon мы указали в опции upsmon значение master, это сделано не спроста, дело в том что на том же ПК, где у нас будет работать сервер NUT мы настроим и клиентскую часть NUT и когда сервер NUT отправит всем клиентам сигнал о критическом состоянии батарей ИБП, то master должен выключиться самым последним из серверов, дождавшись выключения всех slave серверов.

ВНИМАНИЕ! Директива allowfrom в файле /etc/nut/upsd.users больше не используется и является устаревшей.

7. Настроим режим работы NUT на сервере 192.168.100.1 (работа в режиме сервера), для этого в файле /etc/nut/nut.conf напишем:

MODE=netserver

8. Запустим сервер NUT:

/etc/init.d/nut-server restart

И проверим его статус:

# /etc/init.d/nut-server status
● nut-server.service - Network UPS Tools - power devices information server
   Loaded: loaded (/lib/systemd/system/nut-server.service; enabled)
   Active: active (running) since Sun 2017-12-24 23:26:32 +05; 1s ago
  Process: 21736 ExecStart=/sbin/upsd (code=exited, status=0/SUCCESS)
 Main PID: 21737 (upsd)
   CGroup: /system.slice/nut-server.service
           └─21737 /lib/nut/upsd

Dec 24 23:26:32 srv1.mycompany.ru systemd[1]: Starting Network UPS Tools - power devices information server...
Dec 24 23:26:32 srv1.mycompany.ru upsd[21736]: listening on 127.0.0.1 port 3493
Dec 24 23:26:32 srv1.mycompany.ru upsd[21736]: listening on 192.168.100.1 port 3493
Dec 24 23:26:32 srv1.mycompany.ru upsd[21736]: Connected to UPS [apc]: usbhid-ups-apc
Dec 24 23:26:32 srv1.mycompany.ru upsd[21737]: Startup successful

Проверим открытые порты:

# netstat -ltun | grep 3493
tcp        0      0 192.168.100.1:3493      0.0.0.0:*               LISTEN
tcp        0      0 127.0.0.1:3493          0.0.0.0:*               LISTEN

Настройка клиентской части NUT на серверах.

1. Настроим клиент мониторинга (upsmon), который будет заниматься слежением за состоянием ИБП и правильным завершением работы сервера при отсутствии электричества и полном разряде батарей. (Первый клиент у нас будет на том же хосте, что и сервер NUT, то есть на 192.168.100.1):

Для этого отредактируем файл /etc/nut/upsmon.conf и приведем его к виду:

MONITOR apc@localhost 1 local_mon xxx_local_passwd master
POWERDOWNFLAG /etc/killpower
SHUTDOWNCMD "/sbin/shutdown -h +0"
NOTIFYFLAG ONLINE  SYSLOG+EXEC
NOTIFYFLAG ONBATT  SYSLOG+EXEC
NOTIFYFLAG LOWBATT SYSLOG+EXEC

Самое интересное здесь — это директива
MONITOR apc@localhost 1 local_mon xxx_local_passwd master

В ней описывается подключение к нашему серверу NUT, формат здесь простой:
MONITOR <имя_ИБП>@<адрес_сервера_NUT> <количество_ИБП_в_системе> <логин> <пароль>

<имя_ИБП> — берется с сервера NUT из файла /etc/nut/ups.conf, в нашем случае apc;
<адрес_сервера_NUT> — думаю тут все понятно, для локального клиента это localhost;
<количество_ИБП_в_системе> — как правило это 1, если Вам нужно контролировать переход на питание от ИБП, но выключать этот сервер по сигналу NUT Вы не хотите, то установите этот параметр в 0;
<логин> и <пароль> — думаю тут тоже все понятно, данные берутся с сервера NUT из файла /etc/nut/upsd.users;
— если указана опция master, то данный сервер будет выключаться после выключения всех slave серверов;

Так же нужно остановиться на директиве POWERDOWNFLAG и разъяснить как происходит отключение системы в случае когда заряд батарей ИБП истощается.
Итак, в режиме работы от батарей, перед самым их истощением, ИБП генерирует сообщение «battery low». Демон upsmon получает это сообщение от сервера NUT (от upsd) и обрабатывает этот сигнал, вызывая команду описанную в опции SHUTDOWNCMD для корректной остановки системы. Более детально данный процесс можно описать следующей последовательностью:
1. ИБП генерирует событие «battery low»;
2. upsmon получает данный сигнал от сервера NUT и инициирует выключение ПК;
3. Создается специальный файл POWERDOWNFLAG, являющийся признаком того, что система находится в режиме отключения в связи с истощением батарей ИБП;
4. Выполняется команда SHUTDOWNCMD;
5. RC-сценарий использует проверку флага POWERDOWNFLAG для предотвращения так называемой «энергетической гонки» (power race);

«Энергетической гонкой» называется ситуация, когда ИБП переходит в режим работы от сети вскоре после генерации сигнала «battery low», в процессе останова системы. В этом случае компьютер, настроенный на автоматическое включение после сбоя электропитания окажется заложником собственной «осторожности», ведь фактически никакого сбоя не произойдет. Многие современные ИБП имеют механизмы разрешения такой ситуации и дополнительного анализа POWERDOWNFLAG флага на стороне ОС как правило не нужно, но знать про это необходимо.

Теперь перезапустим клиента NUT командой

/etc/init.d/nut-client restart

И проверим его статус:

#  /etc/init.d/nut-client status
● nut-monitor.service - Network UPS Tools - power device monitor and shutdown controller
   Loaded: loaded (/lib/systemd/system/nut-monitor.service; enabled)
   Active: active (running) since Sun 2017-12-24 23:56:49 +05; 9s ago
  Process: 30612 ExecStart=/sbin/upsmon (code=exited, status=0/SUCCESS)
 Main PID: 30615 (upsmon)
   CGroup: /system.slice/nut-monitor.service
           ├─30614 /lib/nut/upsmon
           └─30615 /lib/nut/upsmon

Dec 24 23:56:49 srv1.mycompany.ru upsmon[30612]: UPS: apc@localhost (master) (power value 1)
Dec 24 23:56:49 srv1.mycompany.ru upsmon[30612]: Using power down flag file /etc/killpower
Dec 24 23:56:49 srv1.mycompany.ru upsmon[30614]: Startup successful
Dec 24 23:56:49 srv1.mycompany.ru upsmon[30615]: Init SSL without certificate database
Dec 24 23:56:49 srv1.mycompany.ru systemd[1]: nut-monitor.service: Supervising process 30615 which is no...its.
Dec 24 23:56:49 srv1.mycompany.ru systemd[1]: Started Network UPS Tools - power device monitor and shutd...ler.
Hint: Some lines were ellipsized, use -l to show in full.

Проверить подключение к серверу и вывести все параметры ИБП можно командой:

upsc apc@localhost

Посмотреть значение какого-то конкретного параметра можно указав дополнительно его имя:

upsc apc@localhost ups.beeper.status

Кроме того, как я писал выше есть более сложный клиент (upscmd), который позволяет не только просматривать настройки, но и выполнять команды.
Список доступных команд можно увидеть вот так:

upscmd -l -u admin -p MASTERPASSWORD apc

2. Теперь настроим клиент мониторинга NUT (upsmon) на сервере под управлением Debian Linux (хост 192.168.100.2):

apt-get install nut-client -y

Отредактируем файл /etc/nut/upsmon.conf и приведем его к виду:

MONITOR apc@192.168.100.1 1 srv2_mon xxx_srv1_passwd slave
POWERDOWNFLAG /etc/killpower
SHUTDOWNCMD "/sbin/shutdown -h +0"
NOTIFYFLAG ONLINE  SYSLOG+EXEC
NOTIFYFLAG ONBATT  SYSLOG+EXEC
NOTIFYFLAG LOWBATT SYSLOG+EXEC

Отредактируем файл /etc/nut/nut.conf и приведем его к виду:

MODE=netclient

Теперь перезапустим клиента NUT командой

/etc/init.d/nut-client restart

И проверим подключение к серверу NUT путем вывода всех параметров ИБП командой:

upsc apc@192.168.100.1

3. Теперь настроим клиента мониторинга NUT (upsmon) на серверe под управлением Windows Server 2012 R2 (хост 192.168.100.3):

Скачиваем инсталлятор под Windows с официального сайта.

Переименовываем файл «C:\Program Files (x86)\NUT\etc\nut.conf.sample» в «C:\Program Files (x86)\NUT\etc\nut.conf» и пишем в конце файла:

MODE=netclient

Далее переименовываем файл «C:\Program Files (x86)\NUT\etc\upsmon.conf.sample» в «C:\Program Files (x86)\NUT\etc\upsmon.conf» и приводим его к виду:

MONITOR apc@192.168.100.1 1 srv3_mon xxx_srv2_passwd slave
SHUTDOWNCMD "shutdown /s /t 00"
POWERDOWNFLAG "C:\\killpower"

Открываем консоль cmd с правами Администратор и рестартуем службу:

net stop "Network UPS Tools"
net start "Network UPS Tools"

И наконец там же из cmd проверяем подключение к серверу NUT путем вывода всех параметров ИБП командой:

"C:\Program Files (x86)\NUT\bin\upsc.exe" apc@192.168.100.1

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