sysutils/nut: fix upsstatus diagnostics and netclient model definition#5469
sysutils/nut: fix upsstatus diagnostics and netclient model definition#5469Drinker09 wants to merge 2 commits into
Conversation
| $response = $backend->configdpRun('nut upsstatus', array("{$upsname}@{$host}")); | ||
|
|
||
| $response = ''; | ||
| $socket = @fsockopen($host, $port, $errno, $errstr, 5); |
There was a problem hiding this comment.
given that the GUI will eventually be privilege separated and the backend call is removed this is not a dependable way forward.
I'm also trying to understand the issue that nut has with something that worked at least up to 2.8.3 and if there isn't a better way to deal with this (if upstream is even aware this is a regression).
There was a problem hiding this comment.
Thank you for the feedback @fichtner!
Regarding the privilege separation concern — that's a completely valid point and we appreciate the heads up about the direction OPNsense is heading. We agree that fsockopen() is not an ideal long-term solution for that reason.
However, the root cause of this issue is a regression in NUT 2.8.5 itself rather than in the plugin. We filed a bug report with the NUT project which has been confirmed by core NUT developer @jimklimov:
NUT issue #3454: networkupstools/nut#3454
The short version is that upsc segfaults (SIGSEGV, exit code 11) on FreeBSD 14.x with NUT 2.8.5 when querying a remote upsd server. The crash occurs during SSL cleanup on exit — SSL is half-initialized after a failed STARTTLS attempt, and upscli_cleanup() crashes dereferencing a null pointer when trying to free the SSL context. jimklimov has confirmed this is a regression introduced late in the 2.8.5 release cycle as part of SSL modernization work, and noted that 2.8.6 is being worked on.
The original configdpRun approach also has a separate issue — configd sanitizes the @ symbol in parameters, making it impossible to pass upsname@host correctly regardless of the upsc segfault.
We're happy to revisit this PR once NUT 2.8.6 is released and the upstream bug is fixed. At that point the original configdpRun approach may work correctly again, or a cleaner solution may be possible that fits the future privilege separation model.
In the meantime, our fsockopen() workaround does restore full functionality for OPNsense 26.1 users running NUT 2.8.5 in netclient mode. We leave it to your judgment whether to merge it as a temporary fix or wait for the upstream resolution.
Important notices
Before you submit a pull request, we ask you kindly to acknowledge the following:
If AI was used, please disclose:
This PR covers issue #5470
Description
This PR fixes two issues with the NUT plugin that prevent the diagnostics page, dashboard widget, and API endpoint from returning UPS status data when running in netclient mode.
Problem 1: upsc binary segfaults on FreeBSD 14.x with NUT 2.8.5
The DiagnosticsController::upsstatusAction() method called /usr/local/bin/upsc via configd to retrieve UPS status. This approach fails for two reasons:
1.) configd sanitizes the @ symbol in parameters, making it impossible to pass upsname@host as an argument via configdpRun().
2.) On FreeBSD 14.x with NUT 2.8.5, upsc segfaults (SIGSEGV, exit code 11) when querying a remote upsd server, producing no output before crashing.
This bug has been reported to the NUT project: networkupstools/nut#3454
Fix: Replace the upsc call with a direct TCP socket connection to the remote upsd server using the NUT protocol. This is more reliable, faster, and bypasses both issues entirely.
Problem 2: Bare HostnameField definition in netclient model
The netclient->address field in Nut.xml was defined as a bare address type="HostnameField" with no configuration, which is inconsistent with how other fields in the model are defined.
Fix: Add explicit Required and IpWithPrefix attributes to properly define the field.
Files changed
sysutils/nut/src/opnsense/mvc/app/controllers/OPNsense/Nut/Api/DiagnosticsController.php — replaced upsc call with direct NUT protocol socket connection
sysutils/nut/src/opnsense/mvc/app/models/OPNsense/Nut/Nut.xml — properly defined netclient address HostnameField
Testing
Tested on OPNsense 26.1 (FreeBSD 14.3-RELEASE-p12) with NUT 2.8.5 in netclient mode, monitoring a CyberPower CP1500PFCLCDa connected to a Raspberry Pi NUT server. After this fix:
Services > NUT > Diagnostics > UPS Status displays full UPS data
Dashboard NUT widget displays UPS status, battery level, and runtime
/api/nut/diagnostics/upsstatus API endpoint returns correct data