===== Настройка Network UPS Tools (NUT) для контролируемого выключения сервера с ОС Debian GNU/Linux, подключенного к двум ИБП APC Smart-UPS с платами управления Инматикс ПСУ Спутник =====
{{:unix-linux:debian:bullseye:pasted:20250507-114445.png }} В этой заметке мы рассмотрим пример настройки свободного программного обеспечения **Network UPS Tools** (**NUT**) для контролируемого выключения сервера на базе ОС **Debian GNU**/**Linux**. В рассматриваемом примере NUT будет использоваться в связке с двумя ИБП **APC Smart-UPS SURT6000XLI**, в которые установлены ранее рассмотренные платы **Инматикс ПСУ Спутник А21**. То есть в нашем случае к двум блокам питания сервера подключены два разных ИБП, а ПО NUT, установленное на сервер, по протоколу **SNMP** будет контролировать состояние обоих ИБП и, в случае проблем с электропитанием на ИБП, инициировать команду штатного выключения хостовой ОС.
\\
==== Установка NUT ====
Все необходимые пакеты можно установить из официальных репозиториев Debian Linux
# apt install nut snmp nut-snmp
Так как конфигурация NUT критична в плане безопасности, мы должны проверить права доступа к конфигурационным файлам.
Доступ должен быть разрешён только для **root** (на редактирование) и группе **nut** (на чтение).
# ls -la /etc/nut
total 64
drwxr-xr-x 2 root nut 4096 Apr 25 16:50 .
drwxr-xr-x 84 root root 4096 Apr 25 16:50 ..
-rw-r----- 1 root nut 1911 Jan 25 2023 nut.conf
-rw-r----- 1 root nut 9047 Jan 25 2023 ups.conf
-rw-r----- 1 root nut 7363 Jan 25 2023 upsd.conf
-rw-r----- 1 root nut 2319 Jan 25 2023 upsd.users
-rw-r----- 1 root nut 19786 Jan 25 2023 upsmon.conf
-rw-r----- 1 root nut 4201 Jan 25 2023 upssched.conf
Если необходимо (если ситуация с правами отличается от выше указанного примера), можем скорректировать права доступа:
# chown root:nut /etc/nut/*
# chmod 640 /etc/nut/*
Прежде чем перейти к конфигурированию NUT, стоит проверить связь сервера с платами управления обоих ИБП по протоколу SNMP. В нашем примере используется протокол **SNMPv3**:
# snmpwalk -v 3 -u nut-user -l authPriv -a SHA -A 'zN3s8fU!sO1sbPMsF' -x DES -X 'H5iXoLe5x4ZY52w-d' KOM-UP001
# snmpwalk -v 3 -u nut-user -l authPriv -a SHA -A 'fR!sO1sbPMsFzN3s8' -x DES -X 'Le5x4ZYv2w-dH5iXo' KOM-UP002
После каждой команды для ИБП должен отобразиться список параметров и их текущие значения, считанные с плат управления по протоколу SNMP.
\\
==== Конфигурация NUT ====
В рамках данной заметки мы не будем рассматривать архитектуру NUT и возможные варианты настройки конфигурационных файлов NUT, так как ранее эта информация была тезисно изложена в статье [[https://blog.it-kb.ru/2024/04/20/configuring-network-ups-tools-nut-for-shutdown-of-hyper-v-vms-and-virtualization-host-connected-to-two-apc-smart-ups-upss-with-nmc-inmatics-psu-sputnik/|о настройке NUT на Windows Server]]. Далее мы приведём примеры настроенных параметров в конфигурационных файлах NUT без учёта комментариев в этих файлах, обозначив некоторые важные моменты.
В первую очередь отредактируем файл **nut.conf**, указав режим работы NUT. Справку по возможным режимам работы можно получить в закомментированных строках nut.conf, либо найти в [[https://networkupstools.org/docs/man/nut.conf.html|man nut.conf]].
# nano /etc/nut/nut.conf
MODE=standalone
----
Настроим конфигурацию драйверов NUT. Для этого отредактируем файл **ups.conf**. Справку по этому конфигурационному файлу можно получить в закомментированных строках файла, либо найти в [[https://networkupstools.org/docs/man/ups.conf.html|man ups.conf]].
Есть разные варианты настройки драйвера и они зависят от типа подключения компьютера с NUT к ИБП и от модели ИБП. Перечень совместимых моделей ИБП и рекомендуемые параметры конфигурации для них можно найти в [[https://networkupstools.org/stable-hcl.html|Hardware compatibility list]].
В нашем случае NUT будет подключаться к ИБП не напрямую через USB, а по сети по протоколу SNMP. Поэтому нам потребуется настроить драйвер **snmp-ups**. В нашем случае к компьютеру с NUT подключены 2 ИБП, доступ к которым мы сконфигурируем по протоколу SNMPv3.
# nano /etc/nut/ups.conf
maxretry = 3
[KOM-UP001]
driver = snmp-ups
mibs = ietf
port = kom-up001.holding.com
snmp_version = v3
secLevel = authPriv
secName = nut-user
authProtocol = SHA
authPassword = zN3s8fU!sO1sbPMsF
privProtocol = DES
privPassword = H5iXoLe5x4ZY52w-d
pollfreq = 10
desc = "APC Smart-UPS SURT6000XLI with NMC Sputnik A21"
[KOM-UP002]
driver = snmp-ups
mibs = ietf
port = kom-up02.holding.com
snmp_version = v3
secLevel = authPriv
secName = nut-user
authProtocol = SHA
authPassword = fR!sO1sbPMsFzN3s8
privProtocol = DES
privPassword = Le5x4ZYv2w-dH5iXo
pollfreq = 10
desc = "APC Smart-UPS SURT6000XLI with NMC Sputnik A21"
----
Следующим шагом настроим серверную компоненту **upsd** таким образом, чтобы upsd не был доступен по сети и прослушивал только локальный порт 3493, отредактировав файл **upsd.conf**:
# nano /etc/nut/upsd.conf
LISTEN 127.0.0.1 3493
----
Далее настроим конфигурационный файл **upsd.users** с пользователями, которые будут иметь доступ к серверу **upsd** (не путать с пользователями Linux. Подробнее в [[https://networkupstools.org/docs/man/upsd.users.html|man upsd.users]]). Внесём в файл секцию с описанием пользователя, например, с именем ''upsmon-user'', указав ему произвольный пароль:
# nano /etc/nut/upsd.users
[upsmon-user]
password = sImplePZsw0rd
upsmon primary
----
Затем настроим конфигурационный файл компоненты мониторинга **upsmon**. Для этого редактируем файл **upsmon.conf** (приведены только добавленные/раскомментированные/отредактированные строки):
# nano /etc/nut/upsmon.conf
MONITOR KOM-UP001@localhost 1 upsmon-user sImplePZsw0rd primary
MONITOR KOM-UP002@localhost 1 upsmon-user sImplePZsw0rd primary
MINSUPPLIES 1
SHUTDOWNCMD "/sbin/shutdown -h +0"
NOTIFYCMD /sbin/upssched
POLLFREQ 5
POLLFREQALERT 5
HOSTSYNC 15
DEADTIME 15
POWERDOWNFLAG /etc/nut/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+EXEC
NOTIFYFLAG ONBATT SYSLOG+EXEC
NOTIFYFLAG LOWBATT SYSLOG+EXEC
NOTIFYFLAG FSD SYSLOG
NOTIFYFLAG COMMOK SYSLOG
NOTIFYFLAG COMMBAD SYSLOG
NOTIFYFLAG SHUTDOWN SYSLOG
NOTIFYFLAG REPLBATT SYSLOG
NOTIFYFLAG NOCOMM SYSLOG
NOTIFYFLAG NOPARENT SYSLOG
RBWARNTIME 43200
NOCOMMWARNTIME 600
FINALDELAY 5
Первые две строки определяют подключение компоненты мониторинга к драйверам, описанным нами в ups.conf с учётной записью, описанной нами в upsd.users. Третья строка с параметром MINSUPPLIES определяет минимально допустимое количество источников питания в состоянии ONLINE. На сервере с двумя блоками питания, подключенным к двум разным ИБП, логично определить значение этого параметра в 1. На сервере с 4 блоками питания, подключенными к разным источникам питания, это значение может быть, например, 2 или 3. Важным здесь также являются параметры NOTIFYFLAG. Обратите внимание на то, что для большинства разных состояний источников питания у нас определено лишь логирование (SYSLOG). И только для трёх состояний (ONLINE, ONBATT, LOWBATT) мы включаем логирование и запуск команды (SYSLOG+EXEC). Под командой здесь подразумевается исполняемый файл планировщика upssched, ссылка на который описана в параметре NOTIFYCMD.
Чтобы лучше понять все описанные параметры, рекомендуется ознакомиться со справкой по этому конфигурационному файлу, которую можно получить в закомментированных строках файла, либо найти в [[https://networkupstools.org/docs/man/upsmon.conf.html|man upsmon.conf]].
----
Настроим конфигурационный файл **upssched.conf** вспомогательного планировщика **upssched**, который вызывается в NOTIFYCMD конфигурации компоненты upsmon:
# nano /etc/nut/upssched.conf
CMDSCRIPT /usr/bin/upssched-script.sh
PIPEFN /run/nut/upssched.pipe
LOCKFN /run/nut/upssched.lock
AT LOWBATT * EXECUTE ups-on-battery
AT ONBATT * START-TIMER ups-on-battery 3600
AT ONLINE * CANCEL-TIMER ups-on-battery
Данная конфигурация предполагает то, что после того, как любой из ИБП переходит в состояние работы от батарей (ONBATT) запускается таймер, ожидающий 1 час (3600 секунд). Это время может корректироваться в зависимости от возможностей ваших ИБП по времени автономной работы от батарей при пропадании входного напряжения. Если в течение указанного периода времени входное напряжение на ИБП вернётся и он перейдёт с батарей на питание от сети (возврат в статус ONLINE), то обратный отсчёт времени таймера будет прерван. Если обратный отсчёт времени таймера доработает до конца, то произойдёт вызов скрипта завершения работы (CMDSCRIPT) с передачей ему параметра "ups-on-battery". При этом, в любой из ситуаций, если с любого из ИБП будет получен статус об исчерпании заряда батарей (LOWBATT), то будет выполнен вызов скрипта завершения работы (CMDSCRIPT) с передачей ему параметра "ups-on-battery".
----
Создаем файл скрипта **upssched-script.sh**:
# nano /usr/bin/upssched-script.sh
#!/bin/bash
###############################################################################
# NUT UPS Monitoring Script with Advanced Communication Loss Protection
# Version: 2.1
#
# Features:
# - Prevents shutdown on communication loss with all UPS units
# - Respects MINSUPPLIES parameter from upsmon.conf
# - Differentiates between power loss and communication issues
# - Comprehensive logging and status tracking
# - Supports calibration mode (CAL) as safe state
###############################################################################
### Configuration Section - Adjust these parameters as needed ###
UPSMON_CONF="/etc/nut/upsmon.conf" # Path to NUT main configuration
LOG_IDENT="NUT-UPS-Monitor" # Syslog identification tag
SAFE_UPS_STATES="OL CAL" # States considered operational (space-separated)
COMM_RETRY_INTERVAL=30 # Seconds between communication retries
MAX_COMM_FAILURES=3 # Allowed consecutive communication failures
### Initialization Section ###
# Read MINSUPPLIES from config with fallback to default value 1
MINSUPPLIES=$(grep -oP '^MINSUPPLIES\s+\K\d+' "$UPSMON_CONF" 2>/dev/null || echo 1)
# Get list of all configured UPS devices (filtering out SSL messages)
UPS_LIST=$(upsc -l 2>/dev/null | grep -v '^Init SSL')
TOTAL_UPS=$(echo "$UPS_LIST" | wc -w)
### Status Tracking Variables ###
SAFE_UPS_COUNT=0 # Count of UPS in safe states
COMM_FAILURE_COUNT=0 # Count of consecutive communication failures
declare -a UPS_STATUSES # Array to store detailed UPS states
###############################################################################
# Function: check_ups_status
# Description: Checks and logs the status of a specific UPS unit
# Arguments:
# $1 - UPS identifier
###############################################################################
check_ups_status() {
local ups_id=$1
local status
# Get UPS status with error handling
status=$(upsc "$ups_id" 2>/dev/null | grep -oP 'ups.status:\s*\K\w+')
# Handle communication failures
if [ -z "$status" ]; then
status="NOCOMM"
((COMM_FAILURE_COUNT++))
logger -t "$LOG_IDENT" -p warn "Communication failed with UPS $ups_id (Attempt $COMM_FAILURE_COUNT/$MAX_COMM_FAILURES)"
else
# Reset communication failure counter on successful contact
COMM_FAILURE_COUNT=0
fi
# Check against safe states
for safe_state in $SAFE_UPS_STATES; do
if [[ "$status" == "$safe_state" ]]; then
((SAFE_UPS_COUNT++))
logger -t "$LOG_IDENT" "UPS $ups_id operational (Status: $status)"
break
fi
done
# Store detailed status for reporting
UPS_STATUSES+=("$ups_id:$status")
}
###############################################################################
# Main Event Handler
# Processes ups-on-battery events and makes shutdown decisions
###############################################################################
case $1 in
ups-on-battery)
### Check all UPS units
for ups in $UPS_LIST; do
check_ups_status "$ups"
done
### Communication Failure Protection ###
if [ $COMM_FAILURE_COUNT -ge $MAX_COMM_FAILURES ]; then
logger -t "$LOG_IDENT" -p err \
"CRITICAL: Persistent communication failures with $COMM_FAILURE_COUNT UPS units"
logger -t "$LOG_IDENT" -p err \
"Possible network/SNMP issue. NOT initiating shutdown."
exit 2
fi
### Power State Evaluation ###
if [ "$SAFE_UPS_COUNT" -lt "$MINSUPPLIES" ]; then
# Genuine power failure condition
logger -t "$LOG_IDENT" -p crit \
"POWER FAILURE: Only $SAFE_UPS_COUNT/$TOTAL_UPS UPS operational (Required: $MINSUPPLIES)"
logger -t "$LOG_IDENT" -p crit \
"Detailed status: ${UPS_STATUSES[*]}"
logger -t "$LOG_IDENT" "Initiating controlled shutdown..."
# Create powerdown flag file
touch /etc/nut/killpower 2>/dev/null
# Execute shutdown command
/usr/sbin/upsmon -c fsd
else
# Adequate power protection available
logger -t "$LOG_IDENT" \
"Power stable: $SAFE_UPS_COUNT/$TOTAL_UPS UPS operational (Required: $MINSUPPLIES)"
fi
;;
*)
# Unknown event type handler
logger -t "$LOG_IDENT" -p warn "Received unconfigured event: $1"
exit 1
;;
esac
exit 0
Разрешим исполнение скрипта:
# chmod +x /usr/bin/upssched-script.sh
----
Перезапускаем службы NUT и убеждаемся в том, что службы запустились без ошибок:
# systemctl restart nut-server nut-monitor
# systemctl status nut-server nut-monitor
Убедиться в правильности настройки связи NUT с платами управления ИБП можно введя команды:
# upsc KOM-UP001
# upsc KOM-UP002
Проверку работы скрипта завершения работы можно выполнить в любое время, вызвав его с параметром "ups-on-battery" (при нормальном состоянии ИБП скрипт не должен вызывать выключение ОС, а лишь фиксировать в системном логе информацию о текущем состоянии обоих подключенных ИБП):
# /usr/bin/upssched-script.sh ups-on-battery
Результат работы скрипта можем увидеть в системном журнале:
# journalctl -n 50 | grep NUT-UPS
\\
----
Дополнительные источники информации:
* [[https://blog.it-kb.ru/2024/04/20/configuring-network-ups-tools-nut-for-shutdown-of-hyper-v-vms-and-virtualization-host-connected-to-two-apc-smart-ups-upss-with-nmc-inmatics-psu-sputnik/|Настройка Network UPS Tools (NUT) для контролируемого выключения хоста Hyper-V, подключенного к двум ИБП APC Smart-UPS с платами управления Инматикс ПСУ Спутник]]
----
Проверено на следующих конфигурациях:
^ Версия ОС ^ Версия NUT ^
| Debian GNU/Linux 11 (Bullseye) | 2.7.4-13 |
| Debian GNU/Linux 12 (Bookworm) | 2.8.0-7 |
----
{{:user:blogroot.png?50&nolink |}} Автор первичной редакции:\\ [[user:blogroot|Алексей Максимов]] \\ Время публикации: 07.05.2025 12:16
{{tag>APC "Network UPS Tools" Linux Debian NMC NUT Bash Script Shutdown "Smart-UPS" SNMP UPS Инматикс "ПСУ Спутник"}}
~~DISCUSSION~~
~~NOTOC~~