All your poll are belong to us
Par hr le mercredi 5 mars 2008, 18:36 - système - Lien permanent
J'ai aujourd'hui besoin de tenir à l'oeil certaines valeurs sur un serveur, le plus simple semble d'utiliser net-snmp et mrtg. Ce serveur SNMP peut être très facilement étendu, mais est assez mal documenté à mon goût. Je vais donc faire un petit tour des méthodes simples d'utilisation de net-snmp pour récupérer des données non communes.
Les versions de net-snmp et mrtg installées sur ma debian etch sont snmpd (5.2.3-7etch2) et mrtg (2.14.7-2). Je suppose que vous êtes à l'aise avec le concept de SNMP et que net-snmp et mrtg sont configurés.
En faisant le tour du site web, du fichier de configuration par défaut et de goo^Winternet, j'ai pû lister les méthodes suivantes :
execextendpass
Je passe sur l'utilisation de subagent qui est plus complexe.
Le script que je vais utiliser tient en 2 lignes et se trouve dans /tmp/test_snmp :
#!/bin/sh echo 42
Pour information, le fichier /usr/share/snmp/mibs/UCD-SNMP-MIB.txt indique que l'OID 2021 correspond à ucdavis et se trouve après le noeud enterprise (ce qui donne .1.3.6.1.4.1.2021). Cet OID sera utilisé pour ajouter de nouvelles données en test, en réalité il faudrait utiliser un OID correspondant à l'environnement d'utilisation (un OID d'entreprise délivré par IANA par exemple).
exec
[...] exec test1 /tmp/test_snmp exec .1.3.6.1.4.1.2021.60 test2 /tmp/test_snmp [...]
Après redémarrage, on vérifie que les données sont bien accessibles en SNMP :
$ snmpwalk -v 1 -c private localhost .1.3.6.1.4.1.2021 [...] UCD-SNMP-MIB::extIndex.1 = INTEGER: 1 UCD-SNMP-MIB::extNames.1 = STRING: test_snmp UCD-SNMP-MIB::extCommand.1 = STRING: /tmp/test_snmp UCD-SNMP-MIB::extResult.1 = INTEGER: 0 UCD-SNMP-MIB::extOutput.1 = STRING: 42 UCD-SNMP-MIB::extErrFix.1 = INTEGER: 0 UCD-SNMP-MIB::extErrFixCmd.1 = STRING: [...] UCD-SNMP-MIB::ucdavis.60.1.1 = INTEGER: 1 UCD-SNMP-MIB::ucdavis.60.2.1 = STRING: "test_snmp" UCD-SNMP-MIB::ucdavis.60.3.1 = STRING: "/tmp/test_snmp" UCD-SNMP-MIB::ucdavis.60.100.1 = INTEGER: 0 UCD-SNMP-MIB::ucdavis.60.101.1 = STRING: "42" UCD-SNMP-MIB::ucdavis.60.102.1 = INTEGER: 0 UCD-SNMP-MIB::ucdavis.60.103.1 = "" [...]
La première forme est plus explicite et la deuxième forme est mieux maitrisée puisqu'on choisit l'OID destination.
Le problème est que le serveur snmp n'est pas très satisfait de l'utilisation de exec :
[...] Mar 4 17:28:45 snmp.priv snmpd[8678]: /etc/snmp/snmpd.conf: line 363: Error: Warning: relocatable 'exec' format will change in a future release - See 'NET-SNMP-EXTEND-MIB' for an alternative Mar 4 17:28:45 snmp.priv snmpd[8678]: net-snmp: 2 error(s) in config file(s)
extend
L'uilisation de extend se fait via une mib spéciale (NET-SNMP-EXTEND-MIB.txt), sur une debian elle se trouve dans /usr/share/snmp/mibs. L'utilisation de cette option permet de créer automatiquement des entrées sous l'OID .1.3.6.1.4.1.8072 par défaut.
extend test_snmp /tmp/test_snmp extend .1.3.6.1.4.1.2021.60 test_snmp /tmp/test_snmp
Les résultats se trouvent aux 2 endroits suivants :
$ snmpwalk -v 1 -c private localhost NET-SNMP-EXTEND-MIB::nsExtendObjects [...] NET-SNMP-EXTEND-MIB::nsExtendNumEntries.0 = INTEGER: 3 NET-SNMP-EXTEND-MIB::nsExtendCommand."test_snmp" = STRING: /tmp/test_snmp NET-SNMP-EXTEND-MIB::nsExtendArgs."test_snmp" = STRING: NET-SNMP-EXTEND-MIB::nsExtendInput."test_snmp" = STRING: NET-SNMP-EXTEND-MIB::nsExtendCacheTime."test_snmp" = INTEGER: 5 NET-SNMP-EXTEND-MIB::nsExtendExecType."test_snmp" = INTEGER: exec(1) NET-SNMP-EXTEND-MIB::nsExtendRunType."test_snmp" = INTEGER: run-on-read(1) NET-SNMP-EXTEND-MIB::nsExtendStorage."test_snmp" = INTEGER: permanent(4) NET-SNMP-EXTEND-MIB::nsExtendStatus."test_snmp" = INTEGER: active(1) NET-SNMP-EXTEND-MIB::nsExtendOutput1Line."test_snmp" = STRING: 42 NET-SNMP-EXTEND-MIB::nsExtendOutputFull."test_snmp" = STRING: 42 NET-SNMP-EXTEND-MIB::nsExtendOutNumLines."test_snmp" = INTEGER: 1 NET-SNMP-EXTEND-MIB::nsExtendResult."test_snmp" = INTEGER: 0 NET-SNMP-EXTEND-MIB::nsExtendOutLine."test_snmp".1 = STRING: 42 [...] $ snmpwalk -v 1 -c private localhost .1.3.6.1.4.1.2021.60 UCD-SNMP-MIB::ucdavis.60.1.0 = INTEGER: 1 UCD-SNMP-MIB::ucdavis.60.2.1.2.9.116.101.115.116.95.115.110.109.112 = STRING: "/tmp/test_snmp" UCD-SNMP-MIB::ucdavis.60.2.1.3.9.116.101.115.116.95.115.110.109.112 = "" UCD-SNMP-MIB::ucdavis.60.2.1.4.9.116.101.115.116.95.115.110.109.112 = "" UCD-SNMP-MIB::ucdavis.60.2.1.5.9.116.101.115.116.95.115.110.109.112 = INTEGER: 5 UCD-SNMP-MIB::ucdavis.60.2.1.6.9.116.101.115.116.95.115.110.109.112 = INTEGER: 1 UCD-SNMP-MIB::ucdavis.60.2.1.7.9.116.101.115.116.95.115.110.109.112 = INTEGER: 1 UCD-SNMP-MIB::ucdavis.60.2.1.20.9.116.101.115.116.95.115.110.109.112 = INTEGER: 4 UCD-SNMP-MIB::ucdavis.60.2.1.21.9.116.101.115.116.95.115.110.109.112 = INTEGER: 1 UCD-SNMP-MIB::ucdavis.60.3.1.1.9.116.101.115.116.95.115.110.109.112 = STRING: "42" UCD-SNMP-MIB::ucdavis.60.3.1.2.9.116.101.115.116.95.115.110.109.112 = STRING: "42" UCD-SNMP-MIB::ucdavis.60.3.1.3.9.116.101.115.116.95.115.110.109.112 = INTEGER: 1 UCD-SNMP-MIB::ucdavis.60.3.1.4.9.116.101.115.116.95.115.110.109.112 = INTEGER: 0 UCD-SNMP-MIB::ucdavis.60.4.1.2.9.116.101.115.116.95.115.110.109.112.1 = STRING: "42"
La deuxième forme revient à peu de choses près au résultat de la commande exec avec utilisation d'un chemin.
La première forme permet d'obtenir beaucoup d'informations intéressantes comme le nombre d'éléments qui étendent la mib (NET-SNMP-EXTEND-MIB::nsExtendNumEntries.0 on remarque donc que j'ai nettoyé la réponse puisqu'il annonce 3 scripts d'extension). On peut récupérer la réponse complète NET-SNMP-EXTEND-MIB::nsExtendOutputFull."test_snmp" ou les lignes une à une NET-SNMP-EXTEND-MIB::nsExtendOutLine."test_snmp".x.
Le point faible de cette méthode subsiste dans le type de donnée renvoyé, notre script envoit un chiffre et il est considéré comme une chaine de caractère. De la même façon, si on veut générer un compteur sur 32 ou 64 bits, c'est impossible avec cette méthode.
pass
L'utilisation de cette option de configuration oblige à choisir un OID en dessous duquel le script est entièrement maitre. Il faut donc avoir recours à un script plus complexe qui permet de donner le type de valeur et la valeur pour un OID donné. Le script passtest donne une bonne idée d'un script basique permettant cette intégration. Je ne rentrerai pas dans les détails.
pass .1.3.6.1.4.1.2021.60 /tmp/test_snmp
Dans l'idée, le script est appelé avec les arguments <reqtype> <miboid>. Avec reqtype qui correspond à -g pour une requête GET, -n pour un GETNEXT et un -s pour un SET. le chemin OID est donné par miboid.
Dans le cas des commandes GET et GETNEXT, la réponse est constituée de 3 lignes :
- l'OID de réponse;
- le type de la valeur retournée, au choix dans integer, gauge, counter, timeticks, ipaddress, objectid, ou string;
- la valeur.
Dans le cas de la commande SET, le script ne doit rien retourner.
Conclusion
Il faut bien en finir avec tout ce bazar, il est intéressant de jeter un coup d'oeil du côté de snmpd.conf(5) pour les détails, d'autres options de configuration comme pass_persist peuvent être utilisées. Personnellement, j'utilise la solution extend qui me semble raisonnablement simple à mettre en place et à utiliser.
Commentaires
Raaaa lovely (oui honteusement repique d'un de mes dessinateurs favoris :)
Sympa, merci bien pour ce petit éclaircissement