--- categories: ['OpenBSD','Système','Utilitaire'] date: 2021-07-18T15:34:24+02:00 description: "Gérer un onduleur avec le projet NUT sur OpenBSD" draft: false tags: ['OpenBSD','NUT','UPS'] title: "OpenBSD : Gérer un onduleur avec NUT" translationKey: 'openbsd-nut' --- ## Description Ayant un onduleur Eaton Ellipse ECO, j'utilise le projet NUT pour le gérer sous OpenBSD. ⇒ Environnement : * OpenBSD : 6.9 ⇒ 7.4 ⇒ Matériel UPS : **Eaton Ellipse ECO 650 VA USB FR** ## Installation {{< inside2 l="sys/openbsd/pkg" t="Installez" a="installer" >}} **nut** ## Configuration Le binaire **nut-scanner** permet de détecter tout matériel UPS connecté, que ce soit par USB, ou réseau. Avec des droits admins : ```sh $ doas nut-scanner SNMP library not found. SNMP search disabled. Neon library not found. XML search disabled. AVAHI client library not found. AVAHI search disabled. Scanning USB bus. No start IP, skipping NUT bus (old connect method) [nutdev1] driver = "usbhid-ups" port = "auto" vendorid = "0463" productid = "FFFF" product = "Ellipse ECO" serial = "000000000" vendor = "EATON" bus = "005" ``` Ensuite, plusieurs fichiers de configurations sont à modifier. Tout changement dans un des fichiers de configuration nécessite le redémarre des services ad hoc. ### ups.conf Il faut remplir le fichier de configuration `/etc/nut/ups.conf` avec les informations retournées par le logiciel. ```cfg (…) [eaton] desc = "Eaton Ellipse ECO 650 VA USB FR" driver = "usbhid-ups" port = "auto" vendorid = "0463" productid = "FFFF" product = "Ellipse ECO" serial = "000000000" vendor = "EATON" bus = "005" ``` ### upsd.conf Ce fichier de configuration permet de paramètrer le contrôle de l'accès aux données gérées par le serveur upsd. Par défaut, le service est seulement accessible sur localhost, en IPv4 et IPv6, sur le port 3493. C'est ce fichier de configuration qu'il faudra modifier pour utiliser l'encapsulation TLS, si besoin. {{< note info >}} Depuis la version 2.4.0 du projet NUT, les directives **ACL** et **allowfrom** ont été remplacés par la directive **LISTEN** et le mécanisme tcp-wrappers. *(cf la [note de changements](https://networkupstools.org/docs/user-manual.chunked/apis12.html)…)* Ne cherchez plus à utiliser les directives ACL ; beaucoup de vieux tutoriels y font de fait références. Tenez en compte ! {{}} {{< note warning >}} Si la directive LISTEN est modifiée/configurée pour permettre l'écoute sur une adresse IPv4, IPv6, il sera nécessaire de configurer le parefeu PF pour autoriser la connexion sur le port adéquat, et filtrer ainsi les requêtes. {{}} ### upsd.users Ce fichier de configuration permet de configurer des utilisateurs qui auront les droits d'interagir avec le serveur upsd. {{< note warning >}} Il est IMPératif que ce fichier ait des droits systèmes les plus minimalistes ! *Par défaut, sous OpenBSD, seul l'utilisateur dédié y a accès en lecture-écriture.* ```sh $ doas chmod 0400 /etc/nut/upsd.users ``` {{}} Profitons en pour configurer un utilisateur qui aura le droit de communiquer entre les services upsd et upsmon. ```cfg [upsmon] password = *** upsmon master ``` Ainsi nous créons : - un utilisateur nommé **upsmon** - *vous pouvez très bien choisir tout autre caractère ; à vous de le réutiliser correctement ensuite*… - qui a des droits maître sur le service upsmon. * *(la connotation n'a rien à voire avec de l'esclavage, elle définit le rôle qui selon sa dominance arrêtera en premier ou dernier le système, dans le cas de gestion des plusieurs OS connectés ; dans le contexte d'un seul OS géré, la valeur **master** s'impose d'elle-même)*. - ensuite, modifier la valeur de la directive **password** par celle de votre choix. Puis modifions le fichier **upsmon.conf**. ### upsmon.conf Ce fichier de configuration paramètre le service moniteur. {{< note warning >}} Attention ce fichier renferme des informations sensibles, il est donc impératif de veiller aux permissions et droits utilisateur. {{}} Suite à la modification du fichier **upsd.users** pour configurer un utilisateur **upsmon**, il nous faut ajouter une directive **MONITOR**, telle que : ```cfg MONITOR eaton@localhost 1 upsmon *** master ``` *(Les '\*\*\*' doivent correspondre au mot de passe configuré dans le fichier **upsd.users** pour l'utilisateur **upsmon**)*. Ensuite, il faut modifier à minima, les directives **NOTIFYMSG**, **NOTIFYFLAG** ; je vous renvoie à la documentation officielle, ainsi que pour connaître le rôle des autres directives. Concernant les directives **NOTIFYFLAG**, il importe d'ajouter le drapeau **EXEC** pour l'exécution des commandes liées. Sans, celles-ci ne seront pas exécutées. Finissons par parler de la directive **NOTIFYCMD** qui n'est pas paramétrée correctement : - dans un premier temps, décommentons-la, puis - changeons le chemin vers le binaire **upssched** Tel que : `NOTIFYCMD /usr/local/sbin/upssched` Ainsi le service **upsmon** passera le relais au binaire **upssched**, qui lira alors la configuration du fichier **upssched.conf**. {{< note info >}} Pourquoi faire cela ? C'est simplement recommandé par la doc officielle, dans la sous section **[Suppressing notify storms](https://networkupstools.org/docs/user-manual.chunked/ar01s07.html)** où il est clairement écrit d'utiliser **upssched** en tant que notificateur de commande, afin d'éviter une "tornade de notifications", qui pourrait avoir lieu dans certains contextes, si la directive **NOTIFYCMD** n'était pas configurée. {{}} ### upssched.conf Ce fichier de configuration permet de configurer des actions à planifier. Il faut décommenter les directives **PIPEFN**, **LOCKFN**, et enfin les directives **AT**. Concernant les deux directives **LOCKFN** et **PIPEFN**, le chemin absolu renseigné par défaut n'existe pas ; il faut le créer et lui donner les droits de l'utilisateur **_ups** : ```sh # mkdir -p /var/db/nut/upssched # chown _ups /var/db/nut/upssched ``` Ensuite créer les directives **AT** nécessaires ; voici ce que j'ai configuré : ```cfg (…) AT ONBATT * START-TIMER onbatt 15 AT ONBATT * START-TIMER onbattwarn 30 (…) AT ONLINE * CANCEL-TIMER onbatt AT ONLINE * CANCEL-TIMER onbattwarn (…) AT ONLINE * EXECUTE ups-back-on-line ``` Sans parler qu'il est possible de modifier le script `/usr/local/bin/upssched-cmd`, pour interagir avec le système selon l'événement appelé. Veuillez lire plus profondément la doc officielle. ### upsset.conf Ce fichier de configuration permet l'usage de scripts CGI, fournit dans le paquet **nut-cgi** et n'a qu'un rôle : celui d'attester que la configuration pour utiliser les scripts CGI en question est bel et bien (soit-disant ?) sécurisée. Il ne sert **que** dans ce contexte. ### Permissions {{< note info >}} À chaque migration de version d'OpenBSD, il sera nécessaire de changer à nouveau les permissions, car elles sont réinitialisées par défaut. {{}} Sous OpenBSD, lors de l'installation du binaire, sont configurés : * un utilisateur : **_ups** * le groupe : **_ups** Il est nécessaire de configurer les permissions utilisateurs afin d'avoir accès au nœud de dispositif adéquat. ⇒ Pour les dispositifs USB, il faut identifier le contrôleur USB sur lequel est connecté le périphérique UPS, voire le(s) nœud(s) de dispositifs **ugen**. Utilisons la commande **usbdevs** : ```sh $ doas usbdevs (…) Controller /dev/usb5: addr 01: 1002:0000 ATI, OHCI root hub addr 02: 0463:ffff EATON, Ellipse ECO (…) ``` *Dans mon cas, le périphérique UPS est connecté sur le contrôleur **usb5**, sans nœud de dispositifs précisé*. Ensuite, il suffit de changer les droits utilisateurs sur le dispositif adéquat ; dans mon cas : ```sh $ doas chown :_ups /dev/usb5 # ou, chgrp _ups /dev/usb5 $ doas chmod g+w /dev/usb5 ``` Ainsi le groupe **_ups** a accès au contrôleur ! Pour finir, assurons-nous d'avoir les droits utilisateurs sur les fichiers du répertoire de configuration '/etc/nut' : ```sh $ doas chown _ups:_ups /etc/nut/ups* ``` Normalement, cela suffit pour démarrer les services adéquats. --- {{< note warning >}} Certains onduleurs de type APC USB ont des soucis, veuillez vous réferer au fichier pkg-readme fourni ! {{}} --- ⇒ Si l'onduleur est connecté par le port RS232, il faut soit : - ajouter l'utilisateur **_ups** au groupe **dialer**, - modifier les droits utilisateur sur le dispositif `/dev/tty` adéquat pour que l'utilisateur **_ups** puisse le gérer. *Ce n'est pas le cas de mon onduleur !* ;-) ### Services Côté service, il faut donc activer puis démarrer les démons suivants : - **upsd** : le service qui gère le serveur réseau - **upsmon** : le service qui gère le moniteur Le service **upsd** doit être démarré avant le service **upsmon**. ```sh $ doas rcctl enable upsd upsmon $ doas rcctl set upsd flags -u _ups $ doas rcctl start upsd upsmon ``` Normallement, le log **daemon** doit notifier ainsi les services : ```sh (…) Jul 17 13:25:34 sh1 usbhid-ups[47317]: Startup successful Jul 17 13:25:34 sh1 upsd[83153]: listening on ::1 port 3493 Jul 17 13:25:34 sh1 upsd[83153]: listening on 127.0.0.1 port 3493 Jul 17 13:25:34 sh1 upsd[83153]: Connected to UPS [eaton]: usbhid-ups-eaton Jul 17 13:25:34 sh1 upsd[90348]: Startup successful Jul 17 13:25:34 sh1 upsmon[19005]: Startup successful (…) ``` ## Vérification ### État Le binaire **upsc** permet de vérifier l'état de l'onduleur, tel que : `$ upsc eaton` est la même chose que faire `$ upsc eaton@localhost` ⇒ Connaître l'état de la batterie : ```sh $ upsc eaton ups.status OL ``` * La réponse **OL** signifie que la batterie fonctionne bien et que l'UPS est bien en ligne électrique ; **OL** : **On Line** - **OB** : **On Battery** signifie que l'onduleur ne fonctionne plus que sur la batterie - **LB** : **Low Battery** signifie que la batterie est à son niveau de charge le plus bas Les indicateurs **OB** et **LB** doivent déclencher des actions selon ce qui est paramétré dans les fichiers de configuration **upsmon.conf**, voire **upssched.conf**. ### Processus et fichiers ouverts Il est possible de vérifier quels processus sont gérés par l'utilisateur **_ups**, voire quels sont les fichiers ouverts par lui, par exemple avec les commandes `ps` et `fstat`, tels que : ```sh $ ps aux -U _ups USER PID %CPU %MEM VSZ RSS TT STAT STARTED TIME COMMAND _ups 31655 0.0 0.0 836 1668 ?? S 5:07PM 0:00.70 /usr/local/bin/usbhid-ups -a eaton _ups 4840 0.0 0.0 764 1308 ?? S 5:07PM 0:00.12 /usr/local/sbin/upsd -u _ups _ups 65469 0.0 0.0 780 3084 ?? S 5:07PM 0:00.09 /usr/local/sbin/upsmon $ fstat -u _ups -n USER CMD PID FD DEV INUM MODE R/W SZ|DV _ups upsmon 65469 wd 4,0 103712 40700 r 512 _ups upsmon 65469 0 4,0 27162 20666 rw 2,2 _ups upsmon 65469 1 4,0 27162 20666 rw 2,2 _ups upsmon 65469 2 4,0 27162 20666 rw 2,2 _ups upsmon 65469 3* internet stream tcp 0x0 127.0.0.1:26706 --> 127.0.0.1:3493 _ups upsmon 65469 4 pipe 0x0 state: _ups upsd 4840 wd 4,4 26111 40700 r 512 _ups upsd 4840 0 4,0 27162 20666 rw 2,2 _ups upsd 4840 1 4,0 27162 20666 rw 2,2 _ups upsd 4840 2 4,0 27162 20666 rw 2,2 _ups upsd 4840 3* internet6 stream tcp 0x0 [::1]:3493 _ups upsd 4840 4* internet stream tcp 0x0 127.0.0.1:3493 _ups upsd 4840 5* unix stream 0x0 _ups upsd 4840 6* internet stream tcp 0x0 127.0.0.1:3493 <-- 127.0.0.1:26706 _ups usbhid-ups 31655 wd 4,4 26111 40700 r 512 _ups usbhid-ups 31655 0 4,0 27162 20666 rw 2,2 _ups usbhid-ups 31655 1 4,0 27162 20666 rw 2,2 _ups usbhid-ups 31655 2 4,0 27162 20666 rw 2,2 _ups usbhid-ups 31655 3 pipe 0x0 state: _ups usbhid-ups 31655 4 pipe 0x0 state: _ups usbhid-ups 31655 5* unix stream 0x0 /var/db/nut/usbhid-ups-eaton _ups usbhid-ups 31655 6* unix stream 0x0 /var/db/nut/usbhid-ups-eaton ``` Ainsi, on remarque que : - les services upsd et upsmon fonctionnent, bien gérés par l'utilisateur **_ups** - des flux TCP sont bien créés, utilisés sur localhost - que le binaire **usbhid-ups** correspondant à celui qui prend en charge l'UPS fonctionne bien sur le profil **eaton** créé ## Dépannage ### Connection refused Voici, la série de messages : ```sh (…) upsd[55984]: Can't connect to UPS [eaton] (usbhid-ups-eaton): Connection refused upsmon[20574]: Poll UPS [eaton@localhost] failed - Driver not connected upsmon[20574]: Communications with UPS eaton@localhost lost (…) upsmon[44238]: UPS eaton@localhost is unavailable upsmon[44238]: UPS [eaton@localhost]: connect failed: Connection failure: Connection refused (…) ``` Au minimum, deux raisons possibles : - **vérifiez la connexion physique USB** de l'onduleur. Il peut être utile de changer de câble USB, et/ou de débrancher pour rebrancher le câble. De même les ports USB de votre carte-mère, ou de votre hub USB commencent peut-être à être défectueux. - **lors d'une migration d'OpenBSD** : il faut refaire les {{< anchor permissions permissions >}} nécessaires ! ### Login failed ```sh upsmon[39287]: Login on UPS [eaton@localhost] failed - got [ERR ACCESS-DENIED] ``` Vérifier qu'un utilisateur a été configuré dans les fichiers **upsd.users**, qu'il corresponde bien à celui paramétré dans **upsmon.conf**. ### Permission denied ```sh upsd[87303]: Can't open /etc/nut/upsd.conf: Permission denied ``` Vérifier les droits utilisateurs sur le fichier en question, il doit appartenir à l'utilisateur **_ups** --- ## nut-cgi Le binaire **nut-cgi** fournit des scripts CGI pour interagir/visionner au-travers d'un service web le fonctionnement de l'onduleur. Dans les faits, cela ne fonctionne officiellement qu'avec le serveur Apache, et nécessite l'écriture d'un fichier de configuration **hosts.conf**, non créé par défaut. --- Pour la petite histoire, j'ai essayé de paramétrer et utiliser les services natifs que sont **httpd** et **slowcgi** puis à modifier le fichier de configuration **upsset.conf**, mais le service refuse de fonctionner en informant qu'il s'arrête par défaut de sécurité. Résultat : **nut-cgi** semble ne pas fonctionner avec **httpd**… Voici ci-dessous la configuration testée : ### httpd Ici la configuration minimaliste du serveur httpd utilisée : ```cfg types { include "/usr/share/misc/mime.types" } server "default" { listen on 127.0.0.1 port 80 log { access "httpd-default-access.log", error "httpd-default-error.log" } location "/cgi-bin/nut/upsset.cgi" { fastcgi socket "/run/slowcgi.sock" root "/" } } ``` ### bin sh Pour que les scripts CGI, il semble nécessaire d'installer le binaire **sh** dans le chroot web : ```sh $ doas install -o root -g bin -m 0555 /bin/sh /var/www/bin/ ``` ### utilisateur www Il faut aussi donner les droits de l'utilsateur **www** sur le scrit CGI, tel que : ```sh $ doas chown www:bin /var/www/cgi-bin/nut/upsset.cgi ``` Il est de même possible de faire de même pour les deux autres scripts CGI ; à ne faire que si vraiment le besoin est réel. ### nut-cgi et hosts.conf Le fichier de configuration **hosts.conf** n'existe pas par défaut, sous OpenBSD. Il faut le créer et lui donner les droits de l'utilisateur **_ups**. Dans mon cas : ```sh $ doas echo "MONITOR eaton@localhost \"Eaton Ellipse ECO 650 VA USB FR\"" > /etc/nut/hosts.conf $ doas chown _ups:_ups /etc/nut/hosts.conf ``` ### nut-cgi et upsset.conf Il est nécessaire de décommenter l'écriture **I_HAVE_SECURED_MY_CGI_DIRECTORY** dans le fichier de configuration **upsset.conf** ---- ## Documentations - Projet NUT : https://networkupstools.org/ - pkg-readme : `/usr/local/share/doc/pkg-readmes/nut` ---