Avec SNMP, il est possible d'exposer tout ou partie de l'arborescence soit selon le modèle "expose uniquement telle partie" soit selon le modèle "expose tout sauf cette partie". C'est le principe des vues.
Prenons un cas concret : Zabbix ne sait pas interpréter les valeurs qu'il remonte concernant la shared memory dont la taille varie (à la hausse comme à la baisse) en fonction des besoins jusqu'à attendre le maximum défini par kernel.shmall dont on peut positionner la valeur avec sysctl. Cette mal-interprétation génère des fausses alertes qui, en plus d'être pénibles, habituent les techs à ne plus prêter attention aux mails émis par la supervision ce qui représente la pire situation possible.
Plutôt que de trifouiller SNMP, est-ce qu'on ne pourrait pas demander à Zabbix d'exclure la shared memory ? Zabbix la découvre tout seul, avec un discovery et tout le bazar... Il faudrait créer un filtre et tout et tout, voir
https://www.zabbix.com/documentation/2.4/manual/discovery/low_level_discovery point 3.1 . Ce n'est pas fun à mes yeux et pour une fois que j'avais un alibi pour creuser la syntaxe d'un fichier snmpd... Bon ça va, ok, je le reconnais : en vrai, je suis maso. :P
Cet exemple est bateau mais le masquage d'une partie ou de l'intégralité de l'arborescence SNMP peut servir (exemple parmi d'autres : générer un graphe de débit pour une seule interface réseau pour que seul l'utilisateur branché sur cette interface puisse consulter ce graphe, voir
http://net-snmp.sourceforge.net/wiki/index.php/Vacm#VACM_Masks.2C_or_How_to_restrict_access_to_a_particular_index_.28row.29_in_a_Table) donc ce n'est pas inintéressant de se pencher sur ça.
Dans l'arborescence SNMP, c'est le tableau nommé « hrStorageTable » qui contient, entre autres, la description, la taille d'une allocation, le nombre total d'allocations possibles et le nombre d'allocations réalisées de chaque espace logique de stockage (RAM, shared memory, points de montage,...). Voir
http://www.net-snmp.org/docs/mibs/host.html#hrStorageTable . Donc pour récupérer les tailles exprimées sous la forme qu'on leur connaît (Mio, Gio, Tio,...), il faut multiplier le bon nombre d'allocations par la taille d'une allocation. Exemple : espace occupé sur le stockage en octets = taille d'une allocation * nombre d'allocations réalisées. #IZI
L'OID (l'identifiant unique d'un élément dans l'arborescence SNMP) de ce tableau hrStorageTable est .1.3.6.1.2.1.25.2.3 (ou HOST-RESOURCES-MIB::hrStorageTable en langage presque courant...). Ensuite, on met la colonne à laquelle on souhaite accéder : .1.3.6.1.2.1.25.2.3.1.3 = HOST-RESOURCES-MIB::hrStorageTable.1.3 = description de tous les points de montage, .1.3.6.1.2.1.25.2.3.1.6 = HOST-RESOURCES-MIB::hrStorageTable.1.6 nombre d'allocations utilisées,... Ensuite, on met l'ID du stockage : dans mon cas .1.3.6.1.2.1.25.2.3.1.3.1 = HOST-RESOURCES-MIB::hrStorageTable.1.3.1 = nom donné à ma RAM, .1.3.6.1.2.1.25.2.3.1.3.31 = nom donné à la racine (/),...
Les ID / descriptions ne se devinent pas, on les remonte avec : snmpwalk -v2c -c <communauté> <IP_agent_SNMP> HOST-RESOURCES-MIB::hrStorageTable.1.3 :)
La shared memory a l'ID 8. Ce que nous voulons faire c'est donc dégager tout ce qui concerne .1.3.6.1.2.1.25.2.3.1.X.8. Peu importe la valeur de X puisque l'on veut virer la description, l'ID, la taille d'une allocation, les allocations effectuées,... Bref, nous voulons faire disparaître toute information sur l'objet d'ID 8 de la table hrStorageTable.
On a l'OID : .1.3.6.1.2.1.25.2.3.1.X.8, il reste à calculer le masque. Cet OID nécessite 12 bits pour être représenté (ne faites pas attention aux nombres > 1, c'pas comme ça qu'on compte :D ). Il nous faudra donc deux octets, c'est plié d'avance.
Mettons un 1 sous chaque élément de l'OID que l'on souhaite invariant. Et mettons 0 sous chaque partie variante. Dit de manière plus simple : on met un 1 en dessus de chaque élément de l'OID que l'on veut matcher dans la requête SNMP qui sera adressée au serveur. Nous voulons matcher tous les bits sauf le 11e, peu importe ce que contient ce dernier.
OID : .1.3.6.1.2.1.25.2.3.1.X.8
Masque : 1 1 1 1 1 1 1 1 1 1 0 1 0 0 0 0
On regroupe les bits en paquets de 8 (pour faire des octets) et on convertit en hexadécimal : 1 1 1 1 1 1 1 1 = ff ; 1 1 0 1 0 0 0 0 = d0 . Masque final : ff:d0 \o/
On a donc tout pour créer notre vue : « view <label> excluded .1.3.6.1.2.1.25.2.3.1.3.8 ff:d0 ».
Ici, on dit donc que l'on exclut la ligne d'ID 8 dans la table hrStorageTable, peu importe la colonne. #IZI
Si l'on remplaçait le masque par ff:f0, on dirait que seulement l'OID .1.3.6.1.2.1.25.2.3.1.3.8 doit être exclu. On exclurait donc uniquement la description de la shared memory mais on pourrait toujours récupérer la taille d'une allocation en .1.3.6.1.2.1.25.2.3.1.4.8, par exemple. #IZI
Si l'on remplaçait « excluded » par « included », on dirait bien que seul .1.3.6.1.2.1.25.2.3.1.X.8 peut être lu. On pourrait donc récupérer uniquement les infos sur la shared memory. Et si on remplaçait « excluded » par « included » et le masque par ff:f0, alors on autoriserait uniquement la consultation de la description de la shared memory. #IZI
Mais avant de dire ce que l'on exclu, il faudrait peut-être dire ce que l'on inclu ? Car exclure quelque chose du néant, ça va pas être possible. Voici donc la vue finale :
« view <label> included .iso
view <label> excluded .1.3.6.1.2.1.25.2.3.1.3.8 ff:d0 »
On inclus tout l'arbre SNMP et on dégage la ligne de la table hrStorageTable qui concerne la shared memory.
Maintenant, il faut écrire le fichier de configuration de snmpd kiVaBien. La page pointée par ce shaarli n'est plus vraiment appropriée, je lui préfère
https://aresu.dsi.cnrs.fr/spip.php?article175 que j'ai shaarlié y'a quelque temps en
http://shaarli.guiguishow.info/?t_NB6w.
Pour simplifier, je vais développer un exemple complet :
« ## Listen
agentAddress udp:161,udp6:161
## Qui suis-je ?
# snmpd remplit le sysName tout seul avec le FQDN de la machine
sysLocation Internet
sysContact guigui@example.com
## Qui voit quoi ?
# Déclaration des machines autorisées
# Se lit comme : les machines avec les IP 192.0.2.1 et 127.0.0.1, qui viennent nous causer
# en positionnant la communauté à la valeur « zabbix » font partie de la comsec nommée « supervision »
# Nom Source Communauté
com2sec supervision 127.0.0.1 zabbix
com2sec supervision 192.0.2.1 zabbix
# Déclaration des groupes d'accès
# Les machines de la comsec supervision font partie du groupe nommé « ReadOnly » (ce n'est qu'un label,
# pas une permission effective !) qu'ils utilisent SNMP version 1 ou 2c
# Nom Version Com2sec
group ReadOnly v2c supervision
group ReadOnly v1 supervision
# Déclaration des vues
# La vue NoSharedMem masque HOST-RESOURCES-MIB::hrStorageTable.hrStorageEntry.X.8
# Donc on vire les infos à propos de la shared memory que Zabbix ne sait pas interpréter
# Nom Incl/Excl Subtree Masque (optionnel)
view NoSharedMem included .iso
view NoSharedMem excluded .1.3.6.1.2.1.25.2.3.1.3.8 ff:d0
# Association entre un groupe et une vue
# Le groupe ReadOnly est associé a la vue NoSharedMem en lecture seule
# GroupName Contexte Version SecLevel Prefix Read Write Notif
access ReadOnly "" any noauth exact NoSharedMem none none
## Params divers
# To keep "snmpd[3458]: Connection from UDP: [127.0.0.1]:48911" from filling your logs
dontLogTCPWrappersConnects true »
Notons que, sans la vue, une configuration snmpd qui autorise les mêmes deux machines à lire toute l'arborescence sans aucun droit d'écriture, ça se dit : « rocommunity zabbix 89.234.141.72/32 ». On voit donc que les vues sont complexes et pas toujours appropriées. :)
Il ne reste plus qu'à déployer ce fichier de configuration avec Puppet^WAnsible ou autre selon vos goûts. :)