Network UPS Tools (NUT) на CentOS и Windows с отправкой смс через smstools+playsms

в 10:15, , рубрики: ippon, nut, ups, ИБП, костыли, Настройка Linux, Серверное администрирование

В условиях ограниченного бюджета небольшой компании, скромный терминальный сервер 2003 получал бесперебойное электричество от Ippon Smart Winner 1500, который управлялся стандартной утилитой. Не могу чего-то сильно плохого сказать про этот ИБП и его монструозную утилиту управления с анимацией тока. Гудит вполне на свои деньги.

Со временем, windows пришлось обременить парой виртуальных машин Vmware, а парк пополнился парой небольших линуксовых серверов с АТС, Jabber и прочими офисными радостями. Соответственно, возникло желание тоже управлять их питанием от Ippon, ибо заявлена поддержка *nix.

Однако, хотя производитель «по взрослому» предусмотрел множество расширенных возможностей управления, включая клиенты под *nix и mac, смс и email оповещение и т.д., попытки практического применения всего этого болезненны, а результат непредсказуем.

Как все дороги ведут в Рим, так и проблемы с Ippon ведут к NUT. В сети масса информации об этой чудесной утилите, в т.ч. и на Хабре есть примеры настройки
Под *nix работать с NUT одно удовольствие. Просто, понятно, логично.

В сервер c CentOS, непосредственно соединенный с ИБП по USB, я воткнул GSM-модем Teleofis-RX104 и подружил его с smstools3 и playsms, чтобы получился импровизированный sms-шлюз с поддержкой webservices api. В результате, получился удобный универсальный инструмент для разного рода оповещений, в т.ч. и офисной работы

Далее, установил готовый NUT из EPEL-репозитория, прописав в конфигах:

/etc/nut/nut.conf

MODE=netserver

/etc/nut/ups.conf

[winner1500]
driver = blazer_usb
port = /dev/usb/hiddev0
bus = "003"
port = "002"
vendorid = 06da
productid = 0003
desc = "Ippon Smart Winner 1500"
default.battery.voltage.high = 55
default.battery.voltage.low = 47
default.battery.voltage.nominal = 48

Информация о портах и vendor/product из вывода lsusb, вольтаж подобран экспериментально, чтобы всем хватило времени на корректное выключение, т.к. алгоритм завершения работы включается при остаточном напряжении батареи ниже, чем default.battery.voltage.low

В NUT есть и переменная battery.charge, в которую записывается предположительный математический остаток батареи в %. Он наглядный, но для управления не очень удобен

/etc/nut/upsd.users

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

[upsmon_local]
	password  = pass
	upsmon master

[upsmon_remote]
        password  = pass
        upsmon slave

Пользователи, которые могут подключаться и смотреть/управлять/управляться ИБП. admin — для управления ИБП, upsmon_local — для мониторинга состояния ИБП на локальном сервере, upsmon_remote — для управляемых клиентов. Пароли по вкусу

/etc/nut/upsmon.conf

RUN_AS_USER nut
MONITOR winner1500@127.0.0.1 1 upsmon_local pass master
MINSUPPLIES 1
SHUTDOWNCMD "/sbin/shutdown -h +0"
NOTIFYCMD /usr/local/ups/notifyme
POLLFREQ 5
POLLFREQALERT 5
HOSTSYNC 45
DEADTIME 15
POWERDOWNFLAG /etc/killpower
NOTIFYFLAG ONLINE	SYSLOG+EXEC
NOTIFYFLAG ONBATT	SYSLOG+EXEC
NOTIFYFLAG LOWBATT	SYSLOG+EXEC
NOTIFYFLAG FSD	SYSLOG+EXEC
NOTIFYFLAG COMMOK	SYSLOG+EXEC
NOTIFYFLAG COMMBAD	SYSLOG+EXEC
NOTIFYFLAG SHUTDOWN	SYSLOG+EXEC
NOTIFYFLAG REPLBATT	SYSLOG+EXEC
NOTIFYFLAG NOCOMM	SYSLOG+EXEC
RBWARNTIME 43200
NOCOMMWARNTIME 300
FINALDELAY 5

Это самый интересный конфиг, в котором описывается поведение NUT при разных состояниях ИБП. MONITOR указывает, что мы подключаемся к локальной службе NUT и будем мастером, т.е., в случае чего — будем выключать ведомых, а сами умрем последними. Строка NOTIFYCMD указывает какая команда будет выполняться для уведомления. У меня — это вызов /usr/local/ups/notifyme следующего содержания:

#! /bin/bash
smssend 7903******* "servername:$*"

В команду передаются те аргументы NOTIFYFLAG, где есть флаг EXEC. Все переданные аргументы помещаются в строке после «servername:» (чтобы было понятно кто пишет) и отправляются на 7903*******. То есть, при отключении тока придет смс «servername: UPS winner1500 on battery» Текст уведомлений можно менять.

Второй Centos-сервер настраивается еще проще. Фактически, нам нужен только монитор состояния мастер-сервера и ожидание вестей от него. Но раз уж у нас есть playsms, то можно и от него получать смс, например, о том есть ли связь с мастером (не умерла ли на нем служба NUT)

/etc/nut/nut.conf

MODE=netсlient

/etc/nut/upsmon.conf

RUN_AS_USER nut
MONITOR winner1500@10.10.0.4 1 upsmon_remote pass slave
MINSUPPLIES 1
SHUTDOWNCMD "/sbin/shutdown -h +0"
NOTIFYCMD /usr/local/ups/notifyme
POLLFREQ 5
POLLFREQALERT 5
HOSTSYNC 45
DEADTIME 15
POWERDOWNFLAG /etc/killpower
NOTIFYFLAG ONLINE	SYSLOG
NOTIFYFLAG ONBATT	SYSLOG
NOTIFYFLAG LOWBATT	SYSLOG
NOTIFYFLAG FSD	SYSLOG+EXEC
NOTIFYFLAG COMMOK	SYSLOG+EXEC
NOTIFYFLAG COMMBAD	SYSLOG+EXEC
NOTIFYFLAG SHUTDOWN	SYSLOG+EXEC
NOTIFYFLAG REPLBATT	SYSLOG
NOTIFYFLAG NOCOMM	SYSLOG+EXEC
RBWARNTIME 43200
NOCOMMWARNTIME 300
FINALDELAY 5

То есть, ставим EXEC там, где нас интересуют проблемы со связью и прошла ли команда отключения питания от мастера.
Для отправки смс, я задействовал playsms, которому curl передает текст в виде GET-url. Для этого изначально нужно в настройках пользователя playsms включить webservices и сгенерировать webservices token. После этого, в /usr/local/ups/notifyme второго сервера указываем:

#! /bin/bash
msg="$(echo "$*" | tr ' ' '+')"
curl -v "http://10.10.0.4/smsd/index.php?app=webservices&h=f3fd0e7c758b5d529dea17c256f94b23&u=admin&ta=pv&to=7903*******&msg=servername:$msg"

То есть, все то же самое, что и в первом варианте, только заменить пробелы на + и отправить через GET-запрос.

В windows все немного обросло костылями. На сервер был установлен пакет NUT-Installer-2.6.5-3.msi Который по дефолту установился в C:Program FilesNUT и чудесно запустился службой без особых проблем. И curl для отправки уведомлений через playsms.

Настройка NUT аналогична второму серверу-слэйву, т.е. MODE-netclient, основное в upsmon.conf и костылях.

C:Program FilesNUTetcupsmon.conf

MONITOR winner1500@10.10.0.4 1 upsmon_remote pass slave
MINSUPPLIES 1
SHUTDOWNCMD "C:/Common/curl/powerdown.cmd"
NOTIFYCMD "C:/Common/curl/notify.cmd"
POLLFREQ 5
POLLFREQALERT 5
HOSTSYNC 45
DEADTIME 15
POWERDOWNFLAG "C:/killpower"
# NOTIFYFLAG ONLINE	SYSLOG+WALL
NOTIFYFLAG ONBATT	SYSLOG+WALL
# NOTIFYFLAG LOWBATT	SYSLOG+WALL
NOTIFYFLAG FSD		SYSLOG+EXEC
NOTIFYFLAG COMMOK	SYSLOG
NOTIFYFLAG COMMBAD	SYSLOG
NOTIFYFLAG SHUTDOWN	SYSLOG+EXEC+WALL
# NOTIFYFLAG REPLBATT	SYSLOG+WALL
NOTIFYFLAG NOCOMM	SYSLOG+EXEC
# NOTIFYFLAG NOPARENT	SYSLOG+WALL
RBWARNTIME 43200
NOCOMMWARNTIME 300
FINALDELAY 5

Здесь файл уведомления notify.cmd следующего содержания (смысл от которого не меняется):

@echo off
SET "url=http://10.10.0.4/smsd/index.php?app=webservices&h=f3fd0e7c758b5d529dea17c256f94b23&u=admin&ta=pv&to=7903*******&msg="
SET "msg=%*"
SET "msg=%msg: =+%"
C:Commoncurlcurl.exe "%url%servername:+%msg%"

Вот собственно и весь сказ. Если нужно что-то уточнить-дополнить буду рад

Кстати:

msg=%* в notify.cmd делает батник относительно универсальным для разных задач. То есть, добавив в автозагрузку «notify.cmd started» получим уведомление «servername:started» на смс.

Я не преминул это использовать для мониторинга жесткой перезагрузки с BSOD 0x9, которую мне устраивал symantec. Убирать не стал. Мониторинг hard reset полезен:

eventtriggers /create /eid 6008 /l system /tr "hardreset" /tk "C:Commoncurlnotify.cmd 6008 hard reset occured"

Вместо powerdown.cmd можно прямо указать команду, например C:/WINDOWS/system32/shutdown.exe -s -t 0 -c «Forced by NUT master».

Путь к батнику появился потому, что мне было желательно перед выключением сервера корректно выключить виртуальную машину с помощью vmrun из комплекта VMware VIX.

Так как машина была запущена в виде службы утилитой AlwaysUp, то команду корректного останова машины «C:Program FilesVMwareVMware VIXvmrun.exe» stop S:vmachine.vmx я прописал в AlwaysUp, а в батнике уже лишь контролировал службу и писал лог, чтобы если что — таймауты прибавить. Получилось:

@echo off
set "service=autocatalog (managed by AlwaysUpService)"
set "log=C:Commoncurlfsd.log"
echo FSD command received %DATE% %TIME% >> %log%
sc query "%service%" | find "RUNNING" >nul 2>&1 && set running=true
if not "%running%"=="true" goto stopnow
echo VM machine is runnung. Let's stop it >> %log%
sc stop "%service%"
if ERRORLEVEL 1 goto stopnow
sleep 35
sc query "%service%" | find "STOPPED" >nul 2>&1 && echo VM machine soft off in 35 sec >> %log%
:stopnow
echo system shutdown initiated >> %log%
echo ------------------------- >> %log%
C:WINDOWSsystem32shutdown.exe -s -t 0 -c "Forced by NUT master"

То есть, когда батарейка тикает — негоже ждать выключения виртуалки дольше определенного лимита, если она повисла или вообще не запущена

Автор: Louie

Источник

* - обязательные к заполнению поля


https://ajax.googleapis.com/ajax/libs/jquery/3.4.1/jquery.min.js