快轉到主要內容
  1. 全部文章/

在 Linux 上安裝 NUT 管理 UPS 不斷電系統

·3030 字·7 分鐘
目錄

前言
#

我在〈Home Lab 私人伺服器架設日誌|Pt.1 硬體選購 〉中有提到 ,當初在挑選 UPS 時,就是以支援 NUT 為前提挑選,最後決定購買 CyberPower CP1500PFCLCDa

我目前的 homelab 架構是:

  1. 主要的 ProxmoxVE 自組伺服器
  2. 備用的 Synology NAS

ProxmoxVE 中的 NUT 設定為 netserver 模式,提供 UPS 狀態給 Synology NAS 或後續增添的新設備查詢,並在 Synology NAS 上設定 NUT 為 netclient 模式,從 ProxmoxVE 取得 UPS 狀態。

本篇文章主要分享我如何在 ProxmoxVE 上安裝 NUT 並設定為 netserver 模式,並監控電源達成斷電時自動關機以保護硬體。

NUT 是什麼?
#

NUT (Network UPS Tools) 是一套開源自由的工具,用來監控和管理不同品牌的不斷電系統(UPS),只要該品牌的 UPS 有支援,NUT 就能透過驅動程式與硬體溝通,提供網路協議讓遠端電腦查詢狀態,並在斷電時自動觸發關機程序。

它的架構包含:

  1. nut-driver:驅動程式,負責與對應的 UPS 硬體通訊。
  2. nut-server:NUT 資料伺服器 (upsd),讀取驅動程式提供的 UPS 資訊,將狀態透過網路提供給客戶端。
  3. nut-client:監控狀態並執行如關機等動作,包含 upsmonupsupscmd 等元件。

安裝 NUT
#

apt update
apt install nut -y

接上 UPS,找 USB ID
#

執行:

lsusb | grep -i ups
# 或是
lsusb

會看到類似以下的結果:

Bus XXX Device XXX: ID xxxx(vendorid):xxxx(productid) 裝置名稱

找到對應的裝置名稱,以我的 UPS 為例是 Cyber Power System, Inc. PR1500LCDRT2U UPS,記住對應的 ID,接下來在設定 UPS 連線裝置 時會用到。


設定 NUT 模式 nut.conf
#

  1. 編輯設定檔:
nano /etc/nut/nut.conf
  1. 更改 MODE,這邊以 netserver為例:
MODE=netserver

MODE 可選擇:

  1. standalone:獨立模式,最常見,upsdupsmon 在同一台機器運行,直接連接到本地 UPS,保護單一主機。
  2. netserver:網路伺服器模式,類似 standalone,但額外提供 UPS 資料給其他遠端客戶端,需注意 upsd.conf 的網路安全設定。
  3. netclient:網路客戶端模式,只運行 upsmon,從遠端 NUT 伺服器取得 UPS 狀態,不直接連 UPS 硬體。

設定 UPS 連線裝置 ups.conf
#

  1. 編輯設定檔案:
nano /etc/nut/ups.conf

2.貼上:

[cyberpower] # 這裡可以自訂 UPS 設備名稱
  # 要使用的驅動,大部分都是 usbhid-ups
  driver = usbhid-ups
  port = auto
  # `vendorid` 和 `productid` 是從執行 `lsusb` 得到的對應 ID
  vendorid = xxxx
  productid = xxxx
  # 下行裝置描述可以自訂
  desc = "CyberPower CP1500PFCLCDa"

driver 的部分會因 UPS 品牌而異,通常各品牌對應的 driver 如下:

  • APCusbhid-upsapcsmart
  • CyberPowerTripp LiteMinutemanusbhid-ups
  • Eatonusbhid-upssnmp-ups

可透過以下命令查看是否已安裝對應驅動。

ls /lib/nut/

設定 upsd 使用者 upsd.users
#

  1. 編輯設定檔
nano /etc/nut/upsd.users
  1. 在文件最末行貼上:
[admin]
	password = 自訂密碼
	actions = set
	actions = fsd
	instcmds = all
[upswired]
	password = 自訂密碼
	upsmon primary
[observer]
	password = 自訂密碼
	upsmon secondary
  1. 設定權限
chmod 640 /etc/nut/upsd.users
chown root:nut /etc/nut/upsd.users

設定 upsd 監聽 upsd.conf
#

  1. 編輯設定檔
nano /etc/nut/upsd.conf
  1. 貼上:
LISTEN 0.0.0.0 3493

如果你是用 standalone 模式,可以寫:

LISTEN 127.0.0.1 3493

設定監控與系統關機策略 upsmon.conf
#

  1. 編輯 upsmon 設定檔:
nano /etc/nut/upsmon.conf
  1. UPS 監控設定

文件中分為多個區塊,首先找到負責監控設定的 MONITOR 區塊,新增:

MONITOR system powervalue username password ("primary" | "secondary")

其中:

  • system:為 UPS 識別碼,格式為 UPS 設備名稱@主機名[:端口],以本文為例,使用 cyberpower@localhost
  • powervalue:供電權重,通常設 1。
  • username / passwordupsd.users 中的帳號密碼,以本文為例,使用 upswired 自訂密碼
  • primary / secondary:主要設備(與 UPS 直接有線連接的設備)或是從屬設備,在本文中使用 primary
  1. 依序在底下區塊確認是否有以下設定:
MINSUPPLIES 1
# 它代表這台伺服器需要至少幾個正常運作的電源供應器,通常是 1 個。
SHUTDOWNCMD "/usr/sbin/shutdown -h +0"
# 這是電池電量危急時執行的關機指令
POLLFREQ 5
# 它代表 `upsmon` 每幾秒查詢一次 UPS 狀態,通常設定為 `5` 秒
POLLFREQALERT 5
# 它代表 UPS 切換到電池供電時 `upsmon` 每幾秒查詢一次 UPS 狀態,通常跟 `POLLFREQ` 一樣設定為 `5` 秒,也可以設定為更小。
HOSTSYNC 15
# 裝置間關機協調等待秒數
DEADTIME 15
# 代表 UPS 通訊中斷多久後,判定它已經掛掉。
POWERDOWNFLAG /etc/killpower
# 找到 `POWERDOWNFLAG` 關機旗標檔案 - 告訴 UPS 「系統已安全關機,可以切斷電源」
RBWARNTIME 43200
# 當 UPS 偵測到「電池老化該換了」時,upsmon 會每幾小時跳一次警告。
FINALDELAY 5
# 關機前的最後緩衝時間,預設 `5` 秒,之後執行 `SHUTDOWNCMD`
  1. NOTIFYCMD 區塊中加入:
NOTIFYCMD /usr/sbin/upssched

這是事件發生時執行的通知指令,當 UPS 發生事件(斷電、低電量等)時,自動執行 upssched 程式(事件排程器)。

  1. 顯示訊息與通知

NOTIFYMSG 區塊可以設定顯示訊息,NOTIFYFLAG 區塊可以設定訊息通知方式,文件中有列出預設的顯示訊息及通知方式,你可以取消註解並更改。

  1. 設定權限
chmod 640 /etc/nut/upsmon.conf
chown root:nut /etc/nut/upsmon.conf

設定進階事件排程 upssched
#

upssched 能夠設定讓 upsmon 監控的事件發生的一段時間後執行指定程式。例如在電池供電一段固定時間後關機。

  1. 編輯設定檔:
nano /etc/nut/upssched.conf
  1. CMDSCRIPT 區塊中的:
CMDSCRIPT /bin/upssched-cmd

改為:

CMDSCRIPT /etc/nut/upssched-cmd

它代表 upssched 去哪找執行動作的指令,我們會在後續創建並編輯執行腳本。

  1. 找到下面這兩行,並取消註解
PIPEFN /run/nut/upssched.pipe    # 事件佇列
LOCKFN /run/nut/upssched.lock    # 避免重複執行
  1. 在文件下方新增核心規則
AT ONBATT * START-TIMER onbatt 30     # 斷電 → 30秒後執行「onbatt」
AT ONLINE * CANCEL-TIMER onbatt       # 市電恢復 → 取消計時器
AT LOWBATT * EXECUTE lowbatt          # 低電量 → 立即執行「lowbatt」
  1. 編輯動作執行腳本:
sudo tee /etc/nut/upssched-cmd << 'EOF'
#!/bin/bash
# upssched 指令處理腳本

case "$1" in
    onbatt)
        # 斷電30秒後執行 - 發送警報
        logger "UPS: 已斷電,正在使用電池"
        # 在這裡加入你的通知方式 (email、webhook 等)
        ;;
    lowbatt)
        # 電池電量危急 - 開始關機
        logger "UPS: 電池電量低,開始關機程序"
        /sbin/upsmon -c fsd
        ;;
    *)
        logger "upssched-cmd: 未知事件: $1"
        ;;
esac
EOF
  1. 設定腳本執行權限:
sudo chmod +x /etc/nut/upssched-cmd

啟動服務
#

# 啟動 UPS 驅動
upsdrvctl start
# 啟動 upsd 及 upsmon
systemctl start nut-server nut-client 
# 開機時自動啟動
systemctl enable nut-server.service nut-client.service
# 確認狀態
systemctl status nut-server nut-client

查詢 UPS 狀態 upsc
#

  1. 列出所有可用裝置
upsc -l
  1. 顯示所有 UPS 參數:
upsc cyberpower@localhost

以我的 UPS 為例,顯示的資訊如下:

Init SSL without certificate database
battery.charge: 100
battery.charge.low: 10
battery.charge.warning: 20
battery.mfr.date: CPS
battery.runtime: 3675
battery.runtime.low: 300
battery.type: PbAcid
battery.voltage: 27.2
battery.voltage.nominal: 24
device.mfr: CPS
device.model: CP1500PFCLCDa TW
device.serial: CYCQU2000151
device.type: ups
driver.name: usbhid-ups
driver.parameter.pollfreq: 30
driver.parameter.pollinterval: 2
driver.parameter.port: auto
driver.parameter.productid: xxxx
driver.parameter.synchronous: auto
driver.parameter.vendorid: xxxx
driver.version: 2.8.0
driver.version.data: CyberPower HID 0.6
driver.version.internal: 0.47
driver.version.usb: libusb-1.0.26 (API: 0x1000109)
input.voltage: 115.0
input.voltage.nominal: 120
output.voltage: 115.0
ups.beeper.status: enabled
ups.delay.shutdown: 20
ups.delay.start: 30
ups.load: 12
ups.mfr: CPS
ups.model: CP1500PFCLCDa TW
ups.productid: 0601
ups.realpower.nominal: 1000
ups.serial: CYCQU2000151
ups.status: OL
ups.test.result: No test initiated
ups.timer.shutdown: -60
ups.timer.start: -60
ups.vendorid: xxxx
  • 常見 ups.status 解說:

    • OL:On Line power(線上供電)──UPS 使用市電正常供電
    • OB:On Battery(電池供電)──UPS 偵測停電,切換到電池模式
    • LB:Low Battery(電池電量低)──電池即將耗盡的警告狀態
    • CHRG:Charging(充電中)──UPS 電池正在從市電充電
    • DISCHRG:Discharging(放電中)──電池正在向設備供電
  1. 也可以顯示指定參數,例如:
upsc 設備名稱@localhost ups.status

控制 UPS 的即時命令 upscmd
#

upscmd 透過伺服器 upsd 將命令傳送給驅動程式,由驅動程式管理硬體,例如啟動/停止電池測試及蜂鳴器開關等等。 並不是每款 UPS 都支援所有的即時命令,可以使用下面的命令查詢你那款 UPS 有支援哪些:

upscmd -l 設備名稱

接著使用下面的命令執行:

upscmd -u 用戶 -p 自訂密碼 -w -t 秒數 設備名稱 即時命令
  • -u 用戶-p 自訂密碼:指定要連線到伺服器 upsd 的用戶,也可以不加,這樣的話執行命令後會跳出互動式提示要你輸入用戶及密碼。要使用的用戶必須在 upsd.users 中設定權限──instcmds = all,所以這裡使用 admin。
  • -w:如果不使用 -w 的話,命令成功發送到 NUT 伺服器 upsd 就會回傳 OK。加上 -w 會在發送命令後進入等待狀態,讓命令不僅是被發送到 NUT伺服器,還要成功傳遞給了 UPS 硬體,並由 UPS 硬體執行完畢且回傳確認訊號。但 -w 需要 upsd 和驅動程式都支援「TRACKING」功能才能使用。
  • -t 秒數: 與 -w 搭配使用,不設定秒數的話,預設會等待 10 秒。超過指定時間仍未收到硬體回傳的確認訊號,程式就會判斷為超時並停止等待,回傳超時錯誤訊息。

以下提供一個範例:

upscmd -u admin -p 自訂密碼 -w -t 30 cyberpower beeper.enable
  • 用戶指定為 admin
  • 使用 -w 搭配等待時間 30
  • 設備為 cyberpower
  • 執行「開啟蜂鳴器」的即時命令:beeper.enable

測試斷電
#

拔掉 UPS 電源,執行:

upsc 設備名稱@localhost ups.status

應該要顯示 OB,也就是 On Battery(電池供電),接著觀察關機策略是否正常運作。

或是執行下面命令,直接測試一次關機流程是否正常。

upsmon -c fsd
透過郵件回覆
YoZ 柚子
作者
YoZ 柚子
韓國實用音樂系留學生/FOSS Nerd/ISTJ/襯衫、墨鏡愛好者

相關文章