Category: linux

Monitoring UPS status with NUT(Network UPS Tools) on OpenWrt

I have a UPS (APC BK650) to supply power for my OpenWrt router, Network switch and Wireless AP. Since the UPS has no indicator screen, i can’t check its running status(Load, Battery runtime), that’s a little unacceptable for me.

Then i spent some time googling and deployed NUT (Network UPS Tools) on the OpenWrt router, which provides a simple web page showing status of connected UPS.

Web interface of nut web cgi

Here is my installation and configuration process:

1. Install NUT and dependences

opkg install nut nut-common nut-driver-usbhid-ups nut-server nut-upsc nut-web-cgi usbutils
  • nut nut-common nut-server basic packages
  • nut-driver-usbhid-ups nut driver compatible with APC BK650
  • nut-upsc provides upsc command
  • nut-web-cgi provides a web status page
  • usbutils provides lsusb command

2. Configure NUT server, edit /etc/config/nut_server

config driver 'apc'
# APC BK650 is compatible with the usbhid driver
  option driver usbhid-ups
# auto detect USB port
  option port auto

config listen_address
   option ::1

config upsd upsd

Reload nut server

/etc/init.d/nut-server reload

3. Configure the status web page, edit /etc/config/nut_cgi (Skip this step If you just want to check UPS status by upsc command)

# Local UPS configured at /etc/config/nut_server
config host
	option upsname apc
	option hostname localhost
	option displayname "Router"

# This is my another UPS connected with Synology NAS
# You can just ignore this section
config host
	option upsname ups
	option hostname
	option displayname "Synology"

config upsset
	option enable 0

Reload nut cgi

/etc/init.d/nut-cgi reload

5. Connect UPS and OpenWrt router with a USB cable

6. Check if the UPS has been detected

root@OpenWrt:~# lsusb
Bus 002 Device 001: ID 1d6b:0003 Linux Foundation 3.0 root hub
Bus 001 Device 002: ID 051d:0002 American Power Conversion Uninterruptible Power Supply
Bus 001 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub
root@OpenWrt:~# ps ax|grep usbhid
 2753 pts/1    S+     0:00 grep usbhid
 2865 ?        Sl   111:50 /lib/nut/usbhid-ups -D -a apc -u nut

The UPS device should appear in output of lsusb, and usbhid-ups process will also start automatically.

7. If everything goes well, you can get UPS status by command upsc, or visit status web page at http://your router ip/nut/ (if nut-cgi installed),

root@OpenWrt:~# upsc apc
battery.charge: 100
battery.charge.low: 10
battery.charge.warning: 50 not set 2018/10/05
battery.runtime: 2197
battery.runtime.low: 120
battery.type: PbAc
battery.voltage: 13.6
battery.voltage.nominal: 12.0
device.mfr: APC
device.model: Back-UPS 650
device.serial: 3B1840X68970
device.type: ups usbhid-ups
driver.parameter.pollfreq: 30
driver.parameter.pollinterval: 2
driver.parameter.port: auto
driver.parameter.synchronous: no
driver.version: 19.07.5-14-ge290024717 APC HID 0.96
driver.version.internal: 0.41
input.sensitivity: low
input.transfer.high: 266
input.transfer.low: 165
input.transfer.reason: input voltage out of range
input.voltage: 232.0
input.voltage.nominal: 220
ups.beeper.status: enabled
ups.delay.shutdown: 20
ups.firmware: 822.A3.I
ups.firmware.aux: A3
ups.load: 16
ups.mfr: APC 2018/10/05
ups.model: Back-UPS 650
ups.productid: 0002
ups.serial: 3B1840X68970
ups.status: OL
ups.timer.reboot: 0
ups.timer.shutdown: -1
ups.vendorid: 051d

How to limit ingress bandwith with tc command in Linux

tc (Traffic Control) is a builtin command in linux, can be used to configure traffic control rules in linux kernel. is a bash script that I use to simulate a low-speed network during software testing. it sets ingress bandwith limit with the tc command.

# Modify speed variable according to your needs
# Find the default network device in route table
DEVICE=$(route | grep '^default' | grep -o '[^ ]*$')

# Linux does not support shaping on ingress
# but we can redirect ingress taffic to ifb device, then do
# taffic shaping on egress queue of ifb device.

if test -z "$(lsmod | grep ifb)"; then
    modprobe ifb

if test -z "$(ip link | grep ifb0)"; then
    ip link add name ifb0 type ifb
    ip link set dev ifb0 up

tc qdisc add dev ifb0 root handle 1: htb r2q 1
tc class add dev ifb0 parent 1: classid 1:1 htb rate $SPEED
tc filter add dev ifb0 parent 1: matchall flowid 1:1

tc qdisc add dev $DEVICE ingress
tc filter add dev $DEVICE ingress matchall action mirred egress redirect dev ifb0 is used to clean bandwith limit rules

DEVICE=$(route | grep '^default' | grep -o '[^ ]*$')
tc qdisc del dev $DEVICE ingress
tc qdisc del dev ifb0 root

Test results on CentOS 7.8

# wget
--2021-09-24 10:44:43--
Resolving ( 2600:3c01::f03c:91ff:feae:68d,
Connecting to (|2600:3c01::f03c:91ff:feae:68d|:80... connected.
HTTP request sent, awaiting response... 200 OK
Length: 104857600 (100M) [application/octet-stream]
Saving to: ‘100MB-fremont.bin’

30% [=========================>                                                               ] 31,633,828  15.0MB/s             ^C
# wget
--2021-09-24 10:45:12--
Resolving ( 2600:3c01::f03c:91ff:feae:68d,
Connecting to (|2600:3c01::f03c:91ff:feae:68d|:80... connected.
HTTP request sent, awaiting response... 200 OK
Length: 104857600 (100M) [application/octet-stream]
Saving to: ‘100MB-fremont.bin’

 0% [                                                                                         ] 171,104     27.4KB/s  eta 60m 25s^C

Basic iptables rules for linux web server

# Reset rules
iptables -F
iptables -X
iptables -t nat -F
iptables -t nat -X
iptables -t mangle -F
iptables -t mangle -X
iptables -P INPUT ACCEPT
iptables -A INPUT -s -d -j ACCEPT
iptables -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT
iptables -A OUTPUT -j ACCEPT
# Allow ssh remote login
iptables -A INPUT -p tcp --dport 22 -j ACCEPT
# Allow https
iptables -A INPUT -p tcp --dport 443 -j ACCEPT
# Allow http
iptables -A INPUT -p tcp --dport 80 -j ACCEPT
# Allow ping
iptables -A INPUT -p icmp -j ACCEPT
iptables -A INPUT -j REJECT
iptables -A FORWARD -j REJECT

Add User to Group in Linux

Add an Existing User to a Group

sudo usermod -a -G newgroupname username

Add an Existing User to Multiple Groups in One Command

sudo usermod -a -G newgroup1,newgroup2 username

Remove a User From a Group

sudo gpasswd -d username groupname

Create a Group

sudo groupadd groupname

Delete a Group

sudo groupdel groupname

Display User Groups

id username