Informations :
Dates
- Publish : : Friday 17 december 2010
- Modification : Thursday 01 september 2011
- 861 views
Share :
Par Olivier Van Hoof (ovh) html (Mes autres articles) html
1. Considérations générales sur les UPS
1.1. Définition et rôles
- batterie de secours en cas de panne de courant : attention les batteries ne permettent que quelques dizaines de minutes d'autonomie (dépend de la charge à fournir). Un UPS a donc pour principal but de pouvoir éteindre proprement les machines qui lui sont connectées dès qu'une panne de courant survient, et d'éviter ainsi toute perte de données dûe à un crash disque provoqué par une interruption brutale d'alimentation.
- régulateur de tension : un bon UPS fournit un signal parfaitement sinusoïdal (stabilité de l'alimentation) et protège contre tous types de parasites, variations de tension et surcharges dûes à la foudre, par exemple.
1.2. Types d'UPS
Il en existe 3 :
- UPS offline : l'entrée de gamme, n'offre quasiment aucune régulation de tension, a pour seul but d'offrir une batterie de secours. Transmet intégralement toute perturbation électrique aux machines... A éviter autant que faire se peut, surtout pour des serveurs !
- UPS "line interactive" : milieu de gamme, offre une relative protection contre les surcharges avec un certain nombres de filtres électroniques. Si la foudre frappe violemment, la protection risque de ne pas être suffisante. Cependant dans la majeure partie des cas ce type d'UPS est satisfaisant.
- UPS online : le sommet de la technologie :) Regénère entièrement le signal (transformation alternatif -→ continu -→ alternatif), protection totale contre les surtensions. En cas de foudre c'est l'UPS qui encaissera (au point qu'il peut se détruire lui-même), mais les machines n'auront rien : la protection aura donc parfaitement rempli son devoir.
1.3. Comment choisir un UPS ?
Calcul de puissance html
2. Application pratique
L'UPS ayant des entrées tripôles type "PC", il est impossible d'y raccorder une fiche électrique européenne normale. Dès lors, pour y connecter le switch le mieux est de se servir d'un multi-prise spécial tel que le MGE Pulsar CL5 html qui présente l'avantage d'avoir un connecteur d'alimentation tripôle sous la forme "PC" standard. Il suffit dès lors de le relier à l'UPS par un câble d'alimentation mâle-femelle qu'on trouve dans tous les magasins d'informatique.
Voici le schéma de l'installation :

3. Installation sous linux
3.1. Préparation du système
Script avec 1 ligne
001<span class="other_code">usbcore: registered new driver hiddev<br />hiddev96: USB HID v1.10 Device [American Power Conversion Back-UPS BR 800 FW:9.o2 .I USB FW:o2] on usb-0000:00:10.0-1<br />usbcore: registered new driver usbhid<br />drivers/usb/input/hid-core.c: v2.0:USB HID core driver</span>
|
Script avec 1 ligne
001<span class="other_code">mknod /dev/usb/hiddev0 c 180 96</span>
|
3.2. Installation de NUT
C'est un logiciel libre largement soutenu par le célèbre fabricant d'UPS français Merlin-Gerin html (MGE) qui y contribue beaucoup, dont les 2 atouts principaux sont :
- universalité : fonctionne avec la plupart des UPS du marché (liste ici html), quelque soit leur connectique (liaison série, USB... ).
- client/serveur : un serveur tourne sur la machine à laquelle est branché l'UPS, ce qui permet à tout le réseau de connaître à tout moment l'état du système, et éventuellement d'envisager les actions nécessaires le cas échéant (batterie faible >> extinction propre).
Script avec 1 ligne
001<span class="other_code">apt-get install nut nut-usb</span>
|
L'installation se déroule sans problème, mais l'aspect configuration est plus délicat : aucun fichier de configuration dans /etc/nut, aucun assistant ou même message d'information : il est impératif de lire la documentation dans /usr/share/doc/nut, ou de chercher sur le net... Heureusement ce tutoriel est là pour vous simplifier la tâche ;-)
3.3. Configuration de NUT sur le serveur maître
Script avec 1 ligne
001<span class="other_code"># start upsd<br />START_UPSD=yes<br /><br /># start upsmon<br />START_UPSMON=yes</span>
|
Script avec 1 ligne
001<span class="other_code"># define the ups driver and the port where it's connected<br />[myups]<br />driver=hidups<br />port=/dev/usb/hiddev0</span>
|
On précise ensuite le pilote qui est "hidups" pour les UPS USB (n'importe quel modèle et marque supportés) et le périphérique auquel il est connecté : /dev/usb/hiddev0 créé précédemment.
A noter que si on veut utiliser un UPS série, il suffit de changer le port /dev/ttyS0 par exemple) et choisir le driver correspondant au modèle de l'onduleur (voir man ups.conf et man nutupsdrv).
Script avec 1 ligne
001<span class="other_code"># access-lists:<br />ACL all 0.0.0.0/0<br />ACL localhost 127.0.0.1/32<br />ACL lan 192.168.1.0/24<br /><br /># rights:<br />ACCEPT localhost lan<br />REJECT all</span>
|
Script avec 1 ligne
001<span class="other_code"># rights:<br />ACCESS grant monitor localhost<br />ACCESS grant monitor lan<br />ACCESS deny all all</span>
|
Script avec 1 ligne
001<span class="other_code"># define the user rights according to the ACL in upsd.conf<br />[user]<br />password = mypassword<br />allowfrom = localhost lan<br />upsmon master</span>
|
Script avec 1 ligne
001<span class="other_code"># define the ups to monitor and the permissions<br />MONITOR myups@localhost 1 user mypassword master<br /><br /># define the shutdown comand<br />SHUTDOWNCMD "/sbin/shutdown -h now"</span>
|
Et voilà ! L'UPS est ainsi configuré et fonctionnel. Pour s'en assurer, un coup d'oeil dans /var/log/daemon.log (car le programme n'est pas fort bavard à l'écran) :
Script avec 1 ligne
001<span class="other_code">Sep 23 18:47:52 srvtest hidups[712]: Startup successful<br />Sep 23 18:47:52 srvtest upsd[713]: Connected to UPS [myups]: hidups-hiddev0<br />Sep 23 18:47:52 srvtest upsd[714]: Startup successful<br />Sep 23 18:47:52 srvtest upsmon[716]: Startup successful<br />Sep 23 18:47:52 srvtest upsd[714]: Connection from 127.0.0.1<br />Sep 23 18:47:52 srvtest upsd[714]: Client user@127.0.0.1 logged into UPS [myups]</span>
|
Script avec 1 ligne
001<span class="other_code">dmesg | grep hid</span>
|
Script avec 1 ligne
001<span class="other_code">usbcore: registered new driver hiddev<br />hiddev96: USB HID v1.10 Device [American Power Conversion Back-UPS BR 800 FW:9.o2 .I USB FW:o2] on usb-0000:00:10.0-1<br />usbcore: registered new driver usbhid<br />drivers/usb/input/hid-core.c: v2.0:USB HID core driver</span>
|
Script avec 1 ligne
001<span class="other_code">battery.charge: 100<br />battery.chemistry: PbAc<br />battery.runtime: 1290<br />battery.voltage: 27.8<br />driver.name: hidups<br />driver.parameter.port: /dev/usb/hiddev0<br />driver.version: 2.0.1<br />ups.delay.shutdown: -1<br />ups.delay.start: 0<br />ups.load: 380<br />ups.mfr: American Power Conversion<br />ups.model: Back-UPS BR 800 FW:9.o2 .I USB FW:o2<br />ups.serial: QB0406247589<br />ups.status: OL</span>
|
Il se peut que la machine mette 5 secondes maximum avant de s'éteindre, ceci est dû à l'intervalle avec lequel le démon surveille l'état de l'UPS, qui est fixé à 5 secondes par défaut.
Script avec 1 ligne
001<span class="other_code">upsmon -c fsd</span>
|
3.4. Configuration de NUT sur le serveur esclave
Dans /etc/default/nut :
Script avec 1 ligne
001<span class="other_code"># start upsd<br />START_UPSD=no<br /><br /># start upsmon<br />START_UPSMON=yes</span>
|
Script avec 1 ligne
001<span class="other_code"># define the ups to monitor and the permissions<br />MONITOR myups@192.168.1.5 1 user mypassword slave<br /><br /># define the shutdown comand<br />SHUTDOWNCMD "/sbin/shutdown -h now"</span>
|
Et si on simule une panne de courant les 2 ordinateurs s'éteindront maintenant automatiquement, le serveur ayant donné le signal à tous les esclaves qui lui sont connectés.
4. Installation sous Windows
Nous installons donc WinNUT html, ce qui ne pose aucun problème.

- cocher "install as service"
- cocher "automatic setup", ces 2 options assurant que WinNUT sera exécuté automatiquement à chaque démarrage de Windows, en tant que service système
- vérifier que "use timed shutdown" est décoché
- shutdown method : forced
Le fichier est très complet, toutes les options sont déjà réglées à leur valeur par défaut et le fichier est bien commenté ! Ici seule l'option "MONITOR" devra être réglée :
Script avec 1 ligne
001<span class="other_code">MONITOR myups@192.168.1.5 1 user mypassword slave</span>
|
Script avec 1 ligne
001<span class="other_code">upsmon -c fsd</span>
|
5. Configuration avancée
5.1. Evénements et actions personnalisées
Pour cela, nous devons reprendre le fichier /etc/nut/upsmon.conf et le compléter par quelques options :
Script avec 1 ligne
001<span class="other_code"># define the ups to monitor and the permissions<br />MONITOR myups@localhost 1 user mypassword master<br /><br /># define the shutdown comand<br />SHUTDOWNCMD "/sbin/shutdown -h now"<br /><br /># specify the script to execute on event<br />NOTIFYCMD /root/upsalert<br />NOTIFYFLAG ONBATT SYSLOG+WALL+EXEC</span>
|
Script avec 1 ligne
001<span class="other_code">#!/bin/sh<br /><br /># send mail to admin<br />echo "Power is lost, UPS is shutting down servers." | mail -s "UPS ALERT" admin@myserver.com<br /><br /># write to a specific log file<br />date=$(date +"%F %T")<br />echo "$date >> UPS ALERT, shutting down in a few seconds..." >> /var/log/ups.log<br /><br /># actually send the shutdown signal to master (will broadcast to all slaves)<br />/sbin/upsmon -c fsd</span>
|
A noter que si on veut gérer plusieurs événements, un seul script est autorisé, et il faudra donc un moyen pour détecter le type d'événement à traiter. Pour cela NUT définit un paramètre qui est envoyé au script ($*). Pour plus de détails, je vous renvoie à la documentation officielle, n'ayant pas jugé utile d'employer cette option dans mon cas de figure.
5.2. Actions différées
Nous devons encore une fois reprendre le fichier de configuration /etc/nut/upsmon.conf :
Script avec 1 ligne
001<span class="other_code"># define the ups to monitor and the permissions<br />MONITOR myups@localhost 1 user mypassword master<br /><br /># define the shutdown comand<br />SHUTDOWNCMD "/sbin/shutdown -h now"<br /><br /># launch the upssched program to execute script with delay<br />NOTIFYCMD /sbin/upssched<br />NOTIFYFLAG ONBATT SYSLOG+WALL+EXEC<br />NOTIFYFLAG ONLINE SYSLOG+WALL+EXEC</span>
|
Pour paramétrer le timing, il faut ajouter un fichier de configuration spécifique /etc/nut/upssched.conf :
Script avec 1 ligne
001<span class="other_code"># the script to be executed<br />CMDSCRIPT /root/upsalert<br /><br /># mandatory fields that must be set before AT commands<br />PIPEFN /var/run/upssched/upssched.pipe<br />LOCKFN /var/run/upssched/upssched.lock<br /><br /># the timers, here 30 sec after the ONBATT (ups on battery) event<br />AT ONBATT * START-TIMER onbatt 30<br /><br /># cancel the countdown is power is back<br />AT ONLINE * CANCEL-TIMER onbatt</span>
|
Les 2 paramètres suivants sont extrêmement importants, sans quoi ça ne marchera jamais. Durant son exécution, upssched a absolument besoin d'écrire temporairement quelques données sur fichier, mais il faut lui spécifier où il peut le faire et régler les permissions appropriées. Suivant les conseils de la documentation, on va lui créer un répertoire dédié /var/run/upssched qu'on devra léguer au groupe "nut" (chown nut.nut pour l'utilisateur et le groupe, pour être sûr) et lui donner l'accès en écriture (chmod 775). Lors de l'installation de NUT, Debian a créé un utilisateur "nut" membre du groupe "nut" : c'est sous cette idendité que sera exécuté upssched.
On indique ensuite le timing sur l'événement ONBATT, * désigne tous les UPS géré par NUT, START-TIMER pour dire que le compte à rebours commence, "onbatt" désigne ici le nom du timer (car il peut y avoir plusieurs événéments à des timings différents, donc il faut un nom pour les différencier), et enfin le chiffre 30 est le timeout en secondes, c'est-à-dire le délai au bout duquel le script sera exécuté.
Mais une exécution différée amène un autre problème : que faire s'il y a un changement d'état pendant le délai ? C'est l'objet de la dernière ligne de configuration qui dit d'annuler le compte à rebours (CANCEL-TIMER onbatt) si l'événement ONLINE survient, c'est-à-dire si le courant est revenu entretemps.
Preuve dans les logs système qui nous indique clairement et à la seconde près le suivi des opérations :
Script avec 1 ligne
001<span class="other_code">Sep 23 18:20:28 srvtest upsmon[1270]: UPS myups@localhost on battery<br />Sep 23 18:20:28 srvtest upssched[1276]: Timer daemon started<br />Sep 23 18:20:29 srvtest upssched[1276]: New timer: onbatt (30 seconds)<br />Sep 23 18:20:59 srvtest upssched[1276]: Event: onbatt<br />Sep 23 18:20:59 srvtest upsmon[1270]: Signal 10: User requested FSD<br />Sep 23 18:20:59 srvtest upsd[1267]: Setting FSD on UPS [myups]<br />Sep 23 18:21:08 srvtest upsd[1267]: Host 192.168.1.4 disconnected (read failure)<br />Sep 23 18:21:08 srvtest upsmon[1270]: Executing automatic power-fail shutdown<br />Sep 23 18:21:08 srvtest upsmon[1270]: Auto logout and shutdown proceeding<br />Sep 23 18:21:14 srvtest upssched[1276]: Timer queue empty, exiting<br />Sep 23 18:21:14 srvtest upsd[1267]: Host 127.0.0.1 disconnected (read failure)<br />Sep 23 18:21:20 srvtest upsd[1267]: Signal 15: exiting<br />Sep 23 18:21:20 srvtest hidups[1265]: Signal 15: exiting</span>
|
5.3. Hacking
Script avec 1 ligne
001<span class="other_code">USERNAME myuser<br />PASSWORD mypassword<br />FSD myups<br />LOGOUT</span>
|
Script avec 1 ligne
001<span class="other_code">cat ups.cmd | nc 192.168.1.5 3493</span>
|
Script avec 1 ligne
001<span class="other_code">USERNAME myuser<br />PASSWORD mypassword<br />LIST VAR myups<br />LOGOUT</span>
|
Script avec 1 ligne
001<span class="other_code">ovh@server:~$ cat ups.cmd | nc localhost 3493<br />OK<br />OK<br />BEGIN LIST VAR myups<br />VAR myups battery.charge "100"<br />VAR myups battery.chemistry "PbAc"<br />VAR myups battery.runtime "1290"<br />VAR myups battery.voltage "27.8"<br />VAR myups driver.name "hidups"<br />VAR myups driver.parameter.port "/dev/usb/hiddev0"<br />VAR myups driver.version "2.0.1"<br />VAR myups ups.delay.shutdown "-1"<br />VAR myups ups.delay.start "0"<br />VAR myups ups.load "380"<br />VAR myups ups.mfr "American Power Conversion"<br />VAR myups ups.model "Back-UPS BR 800 FW:9.o2 .I USB FW:o2 "<br />VAR myups ups.serial "QB0406247589 "<br />VAR myups ups.status "OL"<br />END LIST VAR myups<br />OK Goodbye</span>
|
6. Affichage de l'état de l'UPS sur un site web en PHP
Script avec 1 ligne
001<span class="php_code"><strong>Charge UPS:</strong> <a class="php_fonc_lien" href="http://fr.php.net/manual/fr/function.system.php">system</a></span>(<span class="php_ch">'upsc myups@192.168.1.2 | grep "ups.load" | cut -d" " -f2'</span>); ?>VA - <br /><strong>Batterie UPS</strong>: <a class="php_fonc_lien" href="http://fr.php.net/manual/fr/function.system.php">system</a>(<span class="php_ch">'upsc myups@192.168.1.2 | grep "battery.charge" | cut -d" " -f2'</span>); ?>% - <br /><strong>Etat UPS</strong>: <br /> <span class="php_var">$ups</span> = <span class="php_fonc"><a class="php_fonc_lien" href="http://fr.php.net/manual/fr/function.exec.php">exec</a></span>(<span class="php_ch">'upsc myups@192.168.1.2 | grep "ups.status" | cut -d" " -f2'</span>); <br /> <span class="php_keyword">switch</span> (<span class="php_var">$ups</span>) {<br /> <span class="php_keyword">case</span> <span class="php_ch">"OL"</span>: <span class="php_keyword"><span class="php_fonc"><a class="php_fonc_lien" href="http://fr.php.net/manual/fr/function.echo.php">echo</a></span></span> <span class="php_ch">'<span style="color: green;">en ligne</span>'</span>; <span class="php_keyword">break</span>;<br /> <span class="php_keyword">case</span> <span class="php_ch">"OB"</span>: <span class="php_keyword"><span class="php_fonc"><a class="php_fonc_lien" href="http://fr.php.net/manual/fr/function.echo.php">echo</a></span></span> <span class="php_ch">'<span style="color: red;">sur batterie !</span>'</span>; <span class="php_keyword">break</span>;<br /> <span class="php_keyword">default</span>: <span class="php_keyword"><span class="php_fonc"><a class="php_fonc_lien" href="http://fr.php.net/manual/fr/function.echo.php">echo</a></span></span> <span class="php_ch">'indéterminé'</span>;<br /> }<br />?>
|
7. Clients NUT
8. Conclusion
N'hésitez pas à m'envoyer un commentaire constructif html.
9. Remerciements
Source
- developpez.com html