Connecting Proxmox to a Synology NAS UPS with NUT
Using the NUT server built into DSM to shut down virtual machines and the Proxmox host cleanly after a power cut.
My UPS is connected over USB to the Synology NAS. The same cable cannot be shared with the Proxmox host running on an Aoostar WTR PRO, so DSM acts as a gateway: it reads the UPS state, then publishes it on the network with NUT. Proxmox can therefore detect an outage and cleanly shut down its virtual machines, its containers and finally the host.
Before you start
- Give the NAS and Proxmox fixed IP addresses, or DHCP reservations.
- Plug the NAS, the Proxmox host and the switch that connects them into the battery-backed outlets of the UPS. With no network during the outage, the NUT alert will never reach Proxmox.
- Check that the UPS is recognised by DSM and that it offers enough runtime to finish the shutdown.
- In Proxmox, configure the shutdown order and delays for the guests. For VMs, install and enable the QEMU Guest Agent whenever the guest system allows it.
- Run the commands below from a
rootshell on the Proxmox host.
1. Enabling the UPS server in DSM
Open Control Panel → Hardware & Power → UPS. Enable UPS support, then Enable network UPS server. Under Permitted Synology NAS devices, add the Proxmox IP address — 192.168.68.24 in this example — and apply the changes.
The NUT server of DSM must only be reachable from the trusted local network. If a firewall separates the NAS from Proxmox, allow only TCP port 3493 from the Proxmox host address. Never expose that port to the internet.
2. Installing NUT on Proxmox
Install the NUT client from the Debian repositories used by Proxmox:
apt update && apt install nut -y
In /etc/nut/nut.conf, state that this machine is only a client of a remote NUT server:
MODE=netclient
3. Declaring the remote UPS
Open /etc/nut/upsmon.conf and add or adapt the following lines:
MONITOR ups@192.168.68.10 1 monuser secret secondary
MINSUPPLIES 1
SHUTDOWNCMD "/sbin/shutdown -h now"
POLLFREQ 5
POLLFREQALERT 5
HOSTSYNC 15
DEADTIME 15
NOTIFYCMD /usr/sbin/upssched
NOTIFYFLAG ONBATT SYSLOG+WALL+EXEC
NOTIFYFLAG ONLINE SYSLOG+EXEC
ups, monuser and secret match the values usually exposed by the NUT server of DSM. They do not replace the restriction by IP address. Modern NUT versions use the secondary role; if an older package rejects that word, use its former alias slave.
4. Triggering the shutdown after 60 seconds
Create /etc/nut/upssched.conf:
CMDSCRIPT /etc/nut/upssched-cmd
PIPEFN /run/nut/upssched.pipe
LOCKFN /run/nut/upssched.lock
AT ONBATT * START-TIMER shutdown-now 60
AT ONLINE * CANCEL-TIMER shutdown-now online
The /run/nut directory is normally prepared by the package. If it does not exist, create it with restricted permissions:
install -d -o nut -g nut -m 0750 /run/nut
Then create the handler /etc/nut/upssched-cmd:
#!/bin/sh
case "$1" in
shutdown-now)
logger -t upssched-cmd "UPS on battery for 60 seconds - initiating shutdown"
/usr/sbin/upsmon -c fsd
;;
online)
logger -t upssched-cmd "UPS back online - canceling shutdown"
;;
*)
logger -t upssched-cmd "Unknown command: $1"
;;
esac
Make the script executable. The configuration files must stay writable by the administrator only:
chown root:nut /etc/nut/upsmon.conf /etc/nut/upssched.conf /etc/nut/upssched-cmd
chmod 750 /etc/nut/upssched-cmd
chmod 640 /etc/nut/upsmon.conf /etc/nut/upssched.conf
The value 60 follows the configuration tested in the original article. Increase it if your guests need more time, while keeping enough margin before the battery runs out.
5. Starting the monitor and checking the connection
systemctl enable nut-monitor
systemctl restart nut-monitor
systemctl status nut-monitor
Then query the UPS published by DSM directly:
upsc ups@192.168.68.10
To keep only the state and the estimated runtime:
upsc ups@192.168.68.10 2>&1 | grep -E '^(ups.status|battery.runtime)'
OLmeans On Line: mains power is present.OBmeans On Battery: the UPS is running on battery.LBmeans Low Battery: the battery is low.
What happens during an outage
- DSM detects the loss of mains power and publishes the
OBstate. upsmonreceives theONBATTevent and asksupsschedto start a 60-second timer.- If power returns before the deadline, the
ONLINEevent cancels the timer. - If the outage continues, the script calls
upsmon -c fsd. Proxmox then shuts down the guests, then the host, following the configured delays.
Testing without nasty surprises
Start by following the log in a second terminal:
journalctl -u nut-monitor -f
Then unplug the mains supply of the UPS, never the equipment on its battery-backed outlets. Check that the state switches to OB. Recent NUT versions also let you list the pending timer with:
/usr/sbin/upssched -l
For a first attempt, plug the mains back in before 60 seconds and confirm the cancellation in the log. Then schedule a real simulation during a maintenance window, to check the complete shutdown of the VMs, the containers and the host. The upsmon -c fsd command really does trigger the shutdown sequence: do not run it on a production server outside a planned window.
Quick troubleshooting
- Connection refused or timeout: check the NAS address, the network UPS server in DSM, TCP port 3493 and the firewall.
- Access denied: check that the Proxmox address really is among the permitted devices and that the
MONITORline uses the values expected by DSM. - The timer does not start: check the two
NOTIFYFLAGlines withEXEC, thePIPEFN/LOCKFNpaths and the permissions of/run/nut. - The host shuts down but not the VMs: review the shutdown order, the Proxmox delays and the QEMU Guest Agent in each guest concerned.
Conclusion
This setup avoids buying a second UPS or physically sharing the USB cable. The NAS stays the NUT server, Proxmox becomes a network client, and a short outage interrupts nothing thanks to the 60-second delay. The essential part remains the real test: the network must stay powered and every guest must shut down before the battery is empty.
Discussion
Comments
No comment yet. Feel free to open the discussion with a question or your own experience.
Signing in keeps the discussion free of spam and avoids publishing your e-mail address.
Sign in to comment →