Traps SNMP dans Nagios

Lundi, 13 Novembre 2006 00:00
Imprimer
Note des utilisateurs: / 9
MauvaisTrès bien 
Voici la méthode tant attendue pour recevoir, de la manière la plus simple possible, des interruptions SNMP (SNMP traps in english) dans Nagios.

Les méthodes fleurissent sur le Web, tant sur le site officiel de Nagios que dans les forums ou ailleurs.

La présente méthode est directement issue de la documentation de SNMPTT. Elle a le grand mérite de ne compter que les éléments nécessaires et suffisants pour que ça marche. Je l'adapte à ma sauce, mais l'original est ici.

Prérequis

J'ai en ce qui me concerne récupéré sur SourceForge les RPM pour la Fedora 5 de net-snmp et net-snmp-perlmods.

L'installation de SNMPTT est manuelle, ce sont des exécutables qui sont distribués. Copier aux emplacements spécifiés dans la documentation au moins les commandes suivantes :

Fonctionnement général

Fonctionnement général

  1. Un hôte sur le réseau (ou plutôt une application de cet hôte) envoie une interruption SNMP au serveur qui héberge Nagios. Celui-ci la reçoit via le service snmptrapd (qui est en écoute sur le port UDP 162).
  2. Snmptrapd la passe ensuite à à SNMPTT, dont le rôle est de rendre intelligible l'interruption. Pour cela, il se base sur la MIB de l'application émettrice, que tu auras bien sûr récupérée et transformée au préalable pour en nourrir SNMPTT.
  3. SNMPTT envoie enfin l'interruption interprétée à Nagios, via le fichier de commandes externes de celui-ci. Il utilise pour cela la commande Nagios submit_check_result.

Dans ma configuration de Nagios, il n'y a qu'un service par hôte qui reçoit les traps SNMP. Cela signifie que si plusieurs traps sont reçus en provenance d'un même hôte, seul le dernier sera affiché. Par contre, chaque trap reçu générera bien une notification.

Pour acquitter une interruption dans Nagios, il faut soit forcer un check immédiat du service (qui fera un ping et remettra l'état à OK), soit soummettre manuellement un check passif, avec l'intitulé "Init", ou "RAZ", par exemple.

Configuration de l'agent SNMP distant

L'application qui enverra les traps SNMP à Nagios doit être configurée (cette configuration est propre à chaque application). Il faut généralement donner une adresse IP destination : c'est celle de l'hôte hébergeant Nagios, et une communauté : nous ne l'utilisons pas ici, tu peux mettre "public", par exemple.

La communauté peut servir, comme un mot de passe, à refuser les traps dans snmptrapd. Je ne l'ai pas mis en place pour l'instant.

Configuration du gestionnaire d'interruptions SNMP

Tout se passe maintenant sur l'hôte hébergeant Nagios, sous root.

Configuration de snmptrapd

Le fichier de configuration /etc/snmp/snmptrapd.conf doit contenir :

traphandle default /usr/sbin/snmptt
disableAuthorization yes
donotlogtraps yes

Ca veut dire :

Pour la petite histoire, snmptrad passe à SNMPTT les éléments de l'interruption qu'il a reçue via les paramétres de la ligne de commande.

Le lanceur du service snmptrapd doit être modifié pour ne pas traduire les OID, mais les laisser sous forme numérique. C'est SNMPTT qui fera la traduction. Sous Fedora, il faut modifier /etc/rc.d/init.d/snmptrapd :

OPTIONS="-On -Lsd -p /var/run/snmptrapd.pid"

En rouge l'option à ajouter. Relancer snmptrapd après modification :

service snmptrapd restart

Note : il arrive que les traps soient reçus en hexadécimal. Dans ce cas, l'option -Oa (forcer l'affichage en ASCII) du lanceur du service snmptrapd peut aider.

Configuration de SNMPTT

Nous allons faire fonctionner SNMPTT en mode "stand-alone" ; il sera appelé chaque fois que nécessaire par le gestionnaire d'interruptions snmptrapd. L'initialisation est plus longue dans ce cas, mais le paramétrage plus simple.

Le fichier de configuration /etc/snmp/snmptt.ini doit contenir (en rouge les éléments à noter) :

[General]
mode = standalone
multiple_event = 1
dns_enable = 1
strip_domain = 1
strip_domain_list = <<END
ton.domaine
END

resolve_value_ip_addresses = 0
net_snmp_perl_enable = 1
net_snmp_perl_best_guess = 0
translate_log_trap_oid = 0
translate_value_oids = 1
translate_enterprise_oid_format = 1
translate_trap_oid_format = 1
translate_varname_oid_format = 1
translate_integers = 1
wildcard_expansion_separator = " "
allow_unsafe_regex = 0
remove_backslash_from_quotes = 0
dynamic_nodes = 0
description_mode = 0
description_clean = 1

[Logging]
stdout_enable = 0
log_enable = 1
log_file = /var/log/snmptt.log
unknown_trap_log_enable = 1
unknown_trap_log_file = /var/log/snmpttunknown.log
statistics_interval = 0
syslog_enable = 1
syslog_facility = local0
syslog_level_debug = <<END
END
syslog_level_info = <<END
END
syslog_level_notice = <<END
END
syslog_level_warning = <<END
END
syslog_level_err = <<END
END
syslog_level_crit = <<END
END
syslog_level_alert = <<END
END
syslog_level = info
syslog_system_enable = 1
syslog_system_facility = local0
syslog_system_level = warning

[Exec]
exec_enable = 1
pre_exec_enable = 0
unknown_trap_exec =

[Debugging]
DEBUGGING = 0
DEBUGGING_FILE =
DEBUGGING_FILE_HANDLER =

[TrapFiles]
snmptt_conf_files = <<END
/etc/snmp/snmptt.conf
END

En rouge, on note donc :

"Compilation" des MIB

Il faut maintenant récupérer le ou les fichiers MIB des équipements à superviser, pour les convertir au format SNMPTT. Le but est d'extraire ce qui dans le fichier MIB est un commentaire, pour que SNMPTT le mette en correspondance avec l'OID qui sera reçu.

Pour chaque fichier MIB, on lance la commande :

snmpttconvertmib --in=<fichier MIB> --out=/etc/snmp/snmptt.conf.<equipement> \
--exec='/usr/local/nagios/libexec/eventhandlers/submit_check_result $r TRAP 1'

On obtiendra dans le fichier résultat des blocs de configuration pour SNMPTT, un par OID, qui ressemblent à ça :

EVENT unEvenement .1.3.6.1.4.1.6876.0.1 "Status Events" Normal
FORMAT $*
EXEC /usr/local/nagios/libexec/eventhandlers/submit_check_result $R TRAP 1 "$*"
SDESC
La description en toutes lettres du biniou.
EDESC

Ajouter enfin au fichier de configuration /etc/snmp/snmptt.ini les fichiers générés :

[...]
[TrapFiles]
snmptt_conf_files = <<END
/etc/snmp/snmptt.conf.<equipement1>
/etc/snmp/snmptt.conf.<equipement2>
END

Rotation des logs

Nous avons paramétré snmptrapd pour ne pas générer de logs ; par contre SNMPTT va le faire. Pour limiter la croissance de ces journaux, on ajoute au fichier /etc/logrotate.conf :

[...]
# system-specific logs may be also be configured here.

/var/log/snmp/snmptt.log /var/log/snmp/snmpttunknown.log {
missingok
}

Le paramétrage global de rotation des logs va s'appliquer, il s'agit pour la Fedora d'une rotation hebdomadaire avec 4 logs en rétention.

Configuration du serveur DNS

Les traps sont émis par une adresse IP, qui est convertie en nom d'hôte par SNMPTT, en demandant une résolution inverse (enregistrement DNS de type PTR) à son serveur DNS. Cette résolution est indispensable au bon fonctionnement de SNMPTT.

Dans mon cas, le serveur DNS est intégré à Active Directory. Si l'enregistrement PTR est créé automatiquement pour les machines Windows dans AD, il n'en va pas de même pour les Linux ou autres OS. Leur enregistrement est créé manuellement, il faut alors cocher la case "create associate PTR record", et vérifier que celui-ci existe bien. Si ce n'est pas le cas, il faut le créer manuellement (attention, le nom d'hôte se termine par ".", comme dans "machine.ton.domaine.").

Tu peux vérifier la présence de l'enregistrement PTR depuis le serveur Nagios avec la commande

dig -x <adresse IP>

Attention ! Lorsque SNMPTT résoud via DNS l'émetteur du trap en nom d'hôte, le résultat est en minuscules. Si l'HOTE est défini en majuscules dans Nagios, il faut le transformer avant d'exécuter le submit_check_result. Cela se fait au moyen de la directive REGEX du fichier snmptt.conf.<equipement>. Il faut l'ajouter manuellement :-( pour chaque évènement de ce fichier. Par exemple :

EVENT unEvenement .1.3.6.1.4.1.6876.0.1 "Status Events" Normal
FORMAT $*
EXEC /usr/local/nagios/libexec/eventhandlers/submit_check_result $R TRAP 1 "$*"
REGEX (monhote)(MONHOTE)
SDESC
[...]

Cela implique de définir une REGEX pour chaque hôte susceptible de générer le trap en question, ce qui est un peu lourdingue je l'avoue. On doit pouvoir l'éviter en utilisant des "unsafe regex", si les noms d'hôtes possibles peuvent s'exprimer sous forme d'une seule expression régulière. Voir la documentation de SNMPTT sur les REGEX.

Configuration de Nagios

Le principe est d'utiliser, pour recevoir les interruptions SNMP, des services passifs (logique...) mais aussi volatils, car si nous recevons une deuxième interruption pour le même hôte avant que la première ait été remise à OK, nous voulons être notifié à nouveau, ne voulons-nous pas ?

Pour cela, il faut (par exemple) définir un service générique pour les traps SNMP, dérivé de mon (désormais célèbre) service générique général :

define service{
name generic-service
register 0
check_period 24x7
max_check_attempts 3
normal_check_interval 15
retry_check_interval 5
active_checks_enabled 1
passive_checks_enabled 0
parallelize_check 1
obsess_over_service 0
check_freshness 0
event_handler_enabled 0
flap_detection_enabled 0
process_perf_data 1
retain_status_information 1
retain_nonstatus_information 1
notification_interval 60
notification_period 24x7
notification_options w,u,c,r
notifications_enabled 1
}

define service{
name snmptrap-service
use generic-service
register 0
service_description TRAP
is_volatile 1
check_command check-host-alive
max_check_attempts 1
normal_check_interval 1
retry_check_interval 1
passive_checks_enabled 1
check_period none
notification_interval 31536000
contact_groups toutlemonde
}

Et le dériver pour chaque machine supervisée, par exemple :

define service{
host_name tonserveur
use snmptrap-service
contact_groups maintenance
}

En rouge, tu as noté d'une part la commande check-host-alive (un bête ping) qui permet de remettre à OK l'état du service en forçant un contrôle actif. D'autre part, l'intervalle de notification est artificiellement long : un an ici. Il permet d'éviter de recevoir régulièrement des notifications pour la même interruption (tant que le service n'est pas ramené à l'état OK), laissant penser qu'une nouvelle interruption, identique à la précédente, a été reçue. Le corollaire, c'est qu'il faut redémarrer Nagios au moins une fois par an.

Allez, redémarre Nagios, tu as fini. Vérifie le fonctionnement en générant une interruption sur l'hôte supervisé. Le service "TRAP" associé à cet hôte devrait passer dans l'état WARNING, avec en description le texte extrait de la MIB.

Mis à jour le Lundi, 23 Mars 2009 15:13