Guide for Reddit: https://www.reddit.com/r/openSUSE/comments/1q2j2ox/comment/nykqps6/
su
hostnamectl set-hostname srv-ups-observer # or what hostname you want
transactional-update pkg install nano nut policycoreutils-python-utils
rebootUse nut-scanner -U to find your "UPS configuration".
su
transactional-update shell
# Backup original config files
cd /etc/ups/
mkdir backup
cp *.{conf,users} backup
ADMIN_PASSWORD=`openssl rand -hex 20`
# UPS configuration
cat > /etc/ups/ups.conf << EOF
[cyberpower]
# Use your own options here
driver = "usbhid-ups"
port = "auto"
vendorid = "0764"
productid = "0501"
vendor = "CPS"
# Important options below
pollonly = "enabled"
pollinterval = 15
pollfreq = 15
maxretry = 3
EOF
# Server configuration
cat > /etc/ups/upsd.conf << EOF
MAXAGE 15
LISTEN 0.0.0.0 3493
EOF
# Server users
cat > /etc/ups/upsd.users << EOF
[admin]
password = $ADMIN_PASSWORD
actions = SET
instcmds = ALL
upsmon master
EOF
# Monitor configuration
cat > /etc/ups/upsmon.conf << EOF
MONITOR cyberpower@localhost 1 admin $ADMIN_PASSWORD master
RUN_AS_USER upsd
MINSUPPLIES 1
SHUTDOWNCMD "/sbin/shutdown -h +0"
POWERDOWNFLAG "/etc/killpower"
POLLFREQ 5
POLLFREQALERT 5
HOSTSYNC 15
DEADTIME 15
NOTIFYCMD /usr/sbin/upssched
NOTIFYFLAG ONLINE SYSLOG
NOTIFYFLAG COMMOK SYSLOG
NOTIFYFLAG SHUTDOWN SYSLOG
NOTIFYFLAG ONBATT SYSLOG+WALL
NOTIFYFLAG LOWBATT SYSLOG+WALL
NOTIFYFLAG FSD SYSLOG+WALL
NOTIFYFLAG NOCOMM SYSLOG+WALL
NOTIFYFLAG COMMBAD SYSLOG+WALL
OFFDURATION 30
OVERDURATION -1
RBWARNTIME 43200
NOCOMMWARNTIME 300
FINALDELAY 5
ALARMCRITICAL 1
EOF
# NUT mode
cat > /etc/ups/nut.conf << EOF
MODE=standalone
EOF
# Remove account expiration and add groups
chage -E -1 upsd
usermod -aG input upsd
exit
rebootUse lsusb to find the vendor and product IDs:
# Example 0764:0501
Bus 001 Device 009: ID 0764:0501 Cyber Power System, Inc. CP1500 AVR UPSUSB permissions:
su
transactional-update shell
# Create udev rule, replace the idVendor and idProduct with yours
cat > /etc/udev/rules.d/99-nut-usbups-override.rules << EOF
# CyberPower UPS
SUBSYSTEM=="usb", ATTR{idVendor}=="0764", ATTR{idProduct}=="0501", MODE="0666", GROUP="input"
SUBSYSTEM=="usb", ATTRS{idVendor}=="0764", ATTRS{idProduct}=="0501", MODE="0666", GROUP="input"
SUBSYSTEM=="usb", ENV{PRODUCT}=="764/501/*", MODE="0666", GROUP="input"
# Trigger driver start on USB add
ACTION=="add", SUBSYSTEM=="usb", ATTR{idVendor}=="0764", ATTR{idProduct}=="0501", RUN+="/usr/bin/systemctl --no-block start nut-driver@cyberpower.service"
# Set hidraw and hiddev
SUBSYSTEM=="hidraw", ATTRS{idVendor}=="0764", ATTRS{idProduct}=="0501", MODE="0666"
KERNEL=="hiddev*", ATTRS{idVendor}=="0764", ATTRS{idProduct}=="0501", MODE="0666"
EOF# Still in transactional-update shell
# Enable all NUT services via nut.target
systemctl enable nut.target
systemctl enable nut-driver.target
systemctl enable nut-driver@cyberpower.service
systemctl enable nut-server.service
systemctl enable nut-monitor.service
exit
rebootsu
cd /etc/ups
# Generate SELinux policy from denials
ausearch -m avc -ts recent | audit2allow -M nut-policies
transactional-update shell
# Set correct SELinux context for /var/lib/ups
semanage fcontext -a -t nut_var_run_t "/var/lib/ups(/.*)?"
# Install the custom policy module
semodule -i /etc/ups/nut-policies.pp
# Verify installed
semodule -l | grep nut
exit
rebootAfter reboot, restore contexts:
sudo restorecon -R -v /var/lib/upssu
# Check all services are active
systemctl is-active nut.target nut-driver@cyberpower.service nut-server.service nut-monitor.service
# Test UPS communication
upsc cyberpower@localhost | head -5
# Check for SELinux denials
ausearch -m avc -ts recent
# Check USB is stable (no disconnect loop)
dmesg | grep "usb" | tail -20