NUT Server Documentation

Hi, I’m new here. I have had a heck of a time getting Network UPS Tools set up on my machine. The biggest problem I have faced is finding fedora specific documentation. I tried the NUT project site and when you’re just starting out, it was confusing and overwhelming. I found TechnoTim’s ultimate guide on youtube, but he’s using ubuntu/debian distro. I also found a centOS forum that helped me get CGI scripts running. I’m willing to share what I know and how I got NUT fully running on my system. I just wanted to double check with you vetran users of fedora discussion to see if any fedora specific documentation for setting up NUT was already available and where I could find it?

Thank You!

I’m setting up NUT on my Fedora 37 machine. I’ve been going through similar pages to you while not finding anything for Fedora. I would be interested if you could share your experiences to get it running.

I hear you. i have college classes going on right now. I’ll see what I can do here and reply shortly. Hang in there, I’ll be back shortly.

First, I would like to give some respect to TechnoTim on YouTube for the wonderful tutorial he put together. Thank You Techno Tim!!! Please check it out and give a like and subscribe if you’re feeling generous.

OK Fedora family, The following worked for me, but is still a work in progress and is not authoritative by any means. Here we go…

  1. The first step I took was installing the Nut server to my machine with the command

sudo dnf install nut nut-client nut-cgi -y

Note: the Fedora project is using /etc/ups instead of /etc/nut for the location of NUT configuration files.

The next steps are basically setting up configuration files. It’s not too bad - But you’ll need to be super patient because there are 8 files that we need to put together. I’ll show you examples and try my best to walk you through it. I used a lot of default values and your welcome to research them and change them to your liking later on.

  1. OK, we need to make sure the UPS unit(s) are ON and connected to the computer’s USB port(s).

Let’s make sure the UPS unit(s) can be seen by our computer. We’ll need the run the following command in a terminal window:

sudo nut-scanner -U

You should see a list of detected UPS units displayed on your screen. Note: i’m using APC branded UPS units and serial numbers need to be noted later on.

Here’s what your screen should kinda look like, only everything under the [nutdev#] will be tabbed to the right :

[nutdev1]
driver = “usbhid-ups”
port = “auto”
vendorid = “051D”
productid = “0002”
product = “Back-UPS ES 350 FW:823.B1a.D USB FW:B1a”
serial = “my unique serial number here - auto generated by nut-scanner”
vendor = “APC”
bus = “003”

[nutdev2]
driver = “usbhid-ups”
port = “auto”
vendorid = “051D”
productid = “0003”
product = “Smart-UPS_1000 FW:UPS 15.5 / ID=1015”
serial = “my unique serial number here - auto generated by nut-scanner”
vendor = “American Power Conversion”
bus = “003”

[nutdev3]
driver = “usbhid-ups”
port = “auto”
vendorid = “051D”
productid = “0003”
product = “Smart-UPS_1500 FW:UPS 15.5 / ID=1018”
serial = “my unique serial number here - auto generated by nut-scanner”
vendor = “American Power Conversion”
bus = “003”

  1. Next, we need to generate the first part of our ups.conf file with the nut-scanner command in a terminal window.

sudo nut-scanner -U > ups.conf

  1. Now we need to edit the file:

nano ups.conf

Note: Everything under [nutdev1,2,3] should be tabbed to the right on you screen and this is OK, don’t change the spacing. I can’t get this reply editor to respect the tab spaces.

We need to change the name of our UPS unit(s) from nutdev1 in the square brackets to a new name with no spaces in it (use underscore “_” in place of spaces).

Each unit needs its own unique name. We’ll use these same name(s) in our hosts.conf and upsmon.conf files later on. With APC units, make sure that the serial number matches up to the unit you’re naming/thinking about.

Now, we add the following lines to the top of the file:

pollinterval = 1
maxretry = 3

…and then save the file. (in nano press ctrl + o and then press enter).

The final product should look kinda like this:

Example of ups.conf:

pollinterval = 1
maxretry = 3

[new_ups_name1]
driver = “usbhid-ups”
port = “auto”
vendorid = “051D”
productid = “0002”
product = “Back-UPS ES 350 FW:823.B1a.D USB FW:B1a”
serial = “my unique serial number here - auto generated by nut-scanner”
vendor = “APC”
bus = “003”
[new_ups_name2]
driver = “usbhid-ups”
port = “auto”
vendorid = “051D”
productid = “0003”
product = “Smart-UPS_1000 FW:UPS 15.5 / ID=1015”
serial = “my unique serial number here - auto generated by nut-scanner”
vendor = “American Power Conversion”
bus = “003”
[new_ups_name3]
driver = “usbhid-ups”
port = “auto”
vendorid = “051D”
productid = “0003”
product = “Smart-UPS_1500 FW:UPS 15.5 / ID=1018”
serial = “my unique serial number here - auto generated by nut-scanner”
vendor = “American Power Conversion”
bus = “003”

  1. Now we need to copy ups.conf to it’s proper directory/folder:

sudo cp ups.conf /etc/ups/ups.conf

This is all we need to do to the ups.conf file. Not to bad. In my experience, If you change up the physical USB connections to your UPS units and computer, you may need to do this step over again AND it’s the only file you’ll have to redo.

  1. Now we need to set up the hosts.conf file:

sudo nano /etc/ups/hosts.conf

Each UPS unit gets its own “MONITOR” line (just copy and paste the MONITOR line below and fill it out with the name(s) you chose for each UPS unit and replace the Description inside the quote marks).

Example of hosts.conf file with 3 UPS Units:

MONITOR new_ups_name1@localhost “Description of UPS Unit 1”
MONITOR new_ups_name2@localhost “Description of UPS Unit 2”
MONITOR new_ups_name3@localhost “Description of UPS Unit 3”

Just to verify, If you only have one UPS unit, then you only need one MONITOR line.

Now save the file and were done with it. Easy peasy Japanesey!!! :smiley:

  1. Now make upsd.users file

sudo nano /etc/ups/upsd.users

Copy and paste the example below. Replace monusername in the square brackets with the user name you want(no spaces in the name, use “_” if you need spaces. ex. user_name) and replace your_password_here with the password you want, 8 characters in length.

Friendly Note: monusername is the user name you’ll log into the nut server with, along with the password you use when you replace your_password_here.

Example of upsd.users:

[monusername]
password = your_password_here
admin master

Save the file and were done with it. :slight_smile:

  1. Now we need to make a upsmon.conf file:

sudo nano /etc/ups/upsmon.conf

You can copy and paste the example below, but you’ll have to:

  • Replace “new_ups_name1” to the ups unit name that your nut server/computer is connected to.

  • Replace your_password_here with the password you used in the upsd.users file.

  • Optional: Research and Modify the other values in this file to your liking, I just used defaults for this example and you don’t have to change them if you don’t want to. The server will still work with them just as they are.

Example of upsmon.conf:

RUN_AS_USER root

MONITOR new_ups_name1@localhost 1 admin your_password_here slave

MINSUPPLIES 1
SHUTDOWNCMD “/sbin/shutdown -h”
NOTIFYCMD /usr/sbin/upssched
POLLFREQ 2
POLLFREQALERT 1
HOSTSYNC 15
DEADTIME 15
POWERDOWNFLAG /etc/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+WALL+EXEC
NOTIFYFLAG ONBATT SYSLOG+WALL+EXEC
NOTIFYFLAG LOWBATT SYSLOG+WALL
NOTIFYFLAG FSD SYSLOG+WALL+EXEC
NOTIFYFLAG COMMOK SYSLOG+WALL+EXEC
NOTIFYFLAG COMMBAD SYSLOG+WALL+EXEC
NOTIFYFLAG SHUTDOWN SYSLOG+WALL+EXEC
NOTIFYFLAG REPLBATT SYSLOG+WALL
NOTIFYFLAG NOCOMM SYSLOG+WALL+EXEC
NOTIFYFLAG NOPARENT SYSLOG+WALL

RBWARNTIME 43200

NOCOMMWARNTIME 600

FINALDELAY 5

Great News!!! You can copy + paste the rest of the files needed to make the server fully configured but not running yet. We’ll get to that part in just a moment. You’re almost there!!!

  1. We have to make nut.conf

sudo nano /etc/ups/nut.conf

You have to choose the mode of your server, I chose netserver.

Example of nut.conf:

MODE=netserver

  1. Now we make upsd.conf

sudo nano /etc/ups/upsd.conf

example of upsd.conf:

LISTEN 0.0.0.0 3493

  1. Now we make upsset.conf

sudo nano /etc/ups/upsset.conf

Example of upsset.conf:

I_HAVE_SECURED_MY_CGI_DIRECTORY

  1. The LAST file we make is ups-cgi.conf

sudo nano /etc/httpd/conf.modules.d/ups-cgi.conf

Example of ups-cgi.conf:

ScriptAlias /nut-cgi-bin/ “/var/www/nut-cgi-bin/”
<Directory “/var/www/nut-cgi-bin”>
AllowOverride None
Options None
Order allow,deny
Allow from all
“<”/Directory>

Note: take quotes " out of the last line of this example. because the reply editor is being a pain.

Save the file and we’re done with it. Thank God the worst part is over!!! We’re now completely done with configuration files!!! You may want to save a copy of all these files for future use.:slight_smile:

I need to give respect to a CentOS tutorial from howtoforge.com written by mspallacci. I acquired the data for the ups-cgi.conf file from the site below. Thank You mspallacci!!!

Now we have to:

  • Configure the firewall
  • Start/Enable the Nut Server, Nut Monitor, Nut Driver Enumerator and Web Server
  • Connect to the Nut Server through a web browser
  1. Configure the Firewall with the following commands:

sudo firewall-cmd --add-service=nut
sudo firewall-cmd --add-service=http
sudo firewall-cmd --runtime-to-permanent

  1. Start/Enable the Nut Server, Nut Monitor, Nut Driver Enumerator and Web Server with the following commands:

sudo systemctl enable --now nut-driver-enumerator.service
sudo systemctl enable --now nut-server.service
sudo systemctl enable --now nut-monitor.service
sudo systemctl enable --now httpd.service

  1. Connect to the server through a web browser

Start a web browser, I use Firefox. In the address/URL bar put the following address:

http://localhost/nut-cgi-bin/upsstats.cgi

For any other computer on your local network:

Replace Your_IP_Address_Here with the NUT Server’s IP Address to pull up the UPS Status page:

http://Your_IP_Address_Here/nut-cgi-bin/upsstats.cgi

…and that’s it. This is the basic configuration that I got to work.

I need to note that when I restart the computer, sometimes the server doesn’t connect right and I have to check my USB Connections and/or reload the server with the commands in step 13.

I sincerely hope this helps you get the NUT Server started and working on Fedora Linux! :smiley:

I have an Android phone and I downloaded an APP called APCUPSD Monitor by Nitramite. I am able to monitor My UPS units with it. Check it out!!!

When you add a unit in the app,

  1. Choose radio button next to NUT
  2. Server address: new_ups_name1@your_NUT_Server’s_IP_Address
  3. Server port: 3493
  4. Server username: is the user name you put in square brackets in the upsd.users file
  5. Server password: is the password you put in the upsd.users file
  6. UPS Enabled: Slide to right to turn ON
  7. Press Save

Enjoy!!! :smiley:

2 Likes

There is some basic UPS support in Gnome Upower. Fedora packages APC UPS software: apcupsd apcupsd-cgi (web interface) apcupsd-gui, while NUT supports legacy UPS’s with interfaces other than UPS (Network UPS Tools .org says: " at least 175 different manufacturers, and 1169 hardware device models are known as compatible"). NUT outstanding issue 2104 may affect APC users. Most users with APC hardware will be better off using Fedora packages.

You posted using the blockquote button. If you use the preformatted text option (the </> button) and mark the text before clicking the button, or add triple back quotes [ ``` ] to the lines preceding and following the pasted text then the formatting will be retained as seen on the screen. Note the change in appearance below when I made the change to the info you posted.

 [**nutdev1**]
 	driver = "usbhid-ups"
 	port = "auto"
 	vendorid = "051D"
 	productid = "0002"
 	product = "Back-UPS ES 350 FW:823.B1a.D USB FW:B1a"
 	serial = "my unique serial number here - auto generated by nut-scanner"
 	vendor = "APC"
 	bus = "003"
 
 [**nutdev2**]
 	driver = "usbhid-ups"
 	port = "auto"
 	vendorid = "051D"
 	productid = "0003"
 	product = "Smart-UPS_1000 FW:UPS 15.5 / ID=1015"
 	serial = "my unique serial number here - auto generated by nut-scanner"
 	vendor = "American Power Conversion"
 	bus = "003"
 
 [**nutdev3**]
 	driver = "usbhid-ups"
 	port = "auto"
 	vendorid = "051D"
 	productid = "0003"
 	product = "Smart-UPS_1500 FW:UPS 15.5 / ID=1018"
 	serial = "my unique serial number here - auto generated by nut-scanner"
 	vendor = "American Power Conversion"
 	bus = "003"

Thank You Jeff! I’m learning. I appreciate your help!

Thank You George! Yeah, I use dnf which pulls from fedora stable repositories, so not too much concern about packages there, but thanks for the heads up about 2104! Very interesting!

Do these services restart automatically on system reboot?

I know they should, but in my case that doesn’t happen. I have to restart the services manually on reboot.

This thread was very helpful for me to get things working with my UPS, but I ran into one issue for my use-case that might help others. I’d also like any feedback on alternate solutions.

I ran into issues with selinux on Fedora 38, and here is what I did to resolve it.

My physical UPS is connected to a QNAP NAS, and my Fedora 38 based desktop runs as a NUT client. I have a fairly large UPS, and I want to have my NAS and other network devices stay up for as long a possible in the event of a power loss. Thus, I want my power hungry desktop to shutdown within 2 minutes of the UPS going on battery.

I’m using the upssched facility, and a modified upssched-cmd script to start a shutdown timer when the UPS goes “on-batt”. Everything was working with stand-in “logger” command as a placeholder for the actual “shutdown” command. But when I tried a real test with the following command, it failed.

case $1 in
    shutdown_onbatt)
        logger -t upsmon[upssched] "Triggering shutdown after 2 minutes on battery"
        sudo /usr/sbin/shutdown -h now
        ;;

Since this script runs as the “nut” user (RUN_AS_USER nut) by default in the Fedora 38 installation, I created a sudoers file to allow the “nut” user to run “shutdown” without a password.

# /etc/sudoers.d/020_nut
# allows user nut to shutdown system without entering password
nut ALL=(ALL) NOPASSWD: /usr/sbin/shutdown

I could see from the journal, that selinux (running in enforcing mode) was preventing the execution of the “sudo” command (and subsequently the “shutdown” command").

Using “setenforce 0” to enable permissive mode, allowed everything to work as expected, but obviously not a final solution.

The selinux policy for Fedora 38 sets a special context of “nut_upsmon_exec_t” for the “upsmon” executable,

[root@localhost] ~ % ll -Z /usr/sbin/upsmon
-rwxr-xr-x. 1 root root system_u:object_r:nut_upsmon_exec_t:s0 54152 Feb 13  2023 /usr/sbin/upsmon

causing the the “upsmon” service to run in the “nut_upsmon_t” domain. This domain is not allowed to run the “sudo” or “shutdown” commands (or much of anything really).

I collected up all the selinux audit events output by “setroubleshoot” and created some new policy files to allow what was required. e.g. “my-sudo.pp” and “my-shutdown.pp”. I added this new policy to my system,

semodule -X 300 -i my-sudo.pp
semodule -X 300 -i my-shutdown.pp

but it was not sufficient, as “sudo” was still failing. I then learned about selinux “dontaudit” events, which will not be reported in the logs. I turned those off,

semodule -DB             (use "semodule -B" to re-hide dontaudit events)

and reran the shutdown test. This allowed me to see the additional policy changes that were required. After installing the updated policy files, the “sudo shutdown” was finally successful!

This took me a fair bit of time, and was surprising, as it seems natural that folks will want to do more or less what I did in the “/usr/bin/upssched-cmd” script.

I also learned that I could avoid all the targeted policy changes, by just allowing the “nut_upsmon_t” domain to run in permissive mode,

semanage permissive -a nut_upsmon_t

In this case, selinux still complains, but it works. A lot more simple, but kind of sidesteps the entire reason for running upsmon in a separate selinux domain.

I’m wondering if others have faced the same issues, and/or have any thoughts on the matter. For someone less versed in Linux and especially “selinux”, getting things working would be a significant hurdle. Did I miss something in documentation that would have avoided this?

1 Like

Just a follow up in case someone else stumbles across the prior post. I found that the expectation from the Fedora packagers was that the upssched-cmd script would call back to the running “upsmon” executable to trigger a shutdown (local only in the case of a secondary client).

https://bugzilla.redhat.com/show_bug.cgi?id=2228245

So I replaced my invocation of “sudo shutdown -h now”, with

/usr/sbin/upsmon -c fsd

Since /usr/sbin/upsmon is labled with the “nut_upsmon_exec_t” type, it is permitted to run without any complaints from selinux.

So a lot of work for nothing (except my own edification), but perhaps if someday I need to do something more complex, I now have the recipe for how to make selinux happy about it.

3 Likes

Is anyone else having an issue with the nut-server.service not starting after reboot? When I tried to enable, I receive this:

systemctl enable nut-server.service
The unit files have no installation config (WantedBy=, RequiredBy=, UpheldBy=,
Also=, or Alias= settings in the [Install] section, and DefaultInstance= for
template units). This means they are not meant to be enabled or disabled using systemctl.

Possible reasons for having this kind of units are:
• A unit may be statically enabled by being symlinked from another unit’s
.wants/, .requires/, or .upholds/ directory.
• A unit’s purpose may be to act as a helper for some other unit which has
a requirement dependency on it.
• A unit may be started when needed via activation (socket, path, timer,
D-Bus, udev, scripted systemctl call, …).
• In case of template units, the unit is meant to be enabled with some
instance name specified.

I’m sorry. i had that problem too. I had to manually restart the service after restart.

#Start and enable services
sudo systemctl enable --now nut-driver-enumerator.service
sudo systemctl enable --now nut-server.service
sudo systemctl enable --now nut-monitor.service
sudo systemctl enable --now httpd.service

I’m glad to help people get started, working out other issues may take some time or maybe the fedora team just hasn’t gotten around to it yet.