Skip to content

Instantly share code, notes, and snippets.

@Wahllow
Last active January 9, 2026 11:18
Show Gist options
  • Select an option

  • Save Wahllow/223dfe714f5d7485bc47bd4bfb8d4bbb to your computer and use it in GitHub Desktop.

Select an option

Save Wahllow/223dfe714f5d7485bc47bd4bfb8d4bbb to your computer and use it in GitHub Desktop.
How to set up NUT on openSUSE MicroOS with SELinux enforced.

Guide for Reddit: https://www.reddit.com/r/openSUSE/comments/1q2j2ox/comment/nykqps6/

1. Install NUT and SELinux tools

su

hostnamectl set-hostname srv-ups-observer # or what hostname you want
transactional-update pkg install nano nut policycoreutils-python-utils

reboot

2. Configure NUT

Use 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
reboot

3. Create udev rules for USB permissions

Use lsusb to find the vendor and product IDs:

# Example 0764:0501
Bus 001 Device 009: ID 0764:0501 Cyber Power System, Inc. CP1500 AVR UPS

USB 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

4. Enable NUT services

# 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
reboot

5. SELinux policies

su
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
reboot

After reboot, restore contexts:

sudo restorecon -R -v /var/lib/ups

6. Verify everything works

su

# 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
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment