Simple Network Management Protocol
protocole de requêtage réseau très simple
get
, get-next
, get-bulk
, set
, walk
clients et serveurs sont nommés "agents"
s'appuie sur le standard de description ASN.1
(en réalité, un sous-ensemble, SMI (Structure of Management Information))
valeurs scalaires :
entier générique, gauge, compteur, ticks, adresse IP, ID d'objet (OID), chaîne
tables multi-indexées
"chemin" d'accès à un attribut
suite de nombres séparés par des points
.1.3.6.1.2.1.1.3
peut s'écrire sous forme de noms
.iso.org.dod.internet.mgmt.mib-2.system.sysUpTime.0
chaque nom censé être unique
Management Information Base
définition à la fois de la hiérarchie et de la correspondance entre nombres et noms
MIB standards (RFC) fournissant de nombreuses définitions de base
MIB fournies par des constructeurs et éditeurs
.iso(1).org(3).dod(6).internet(1).private(4).enterprises(1)
possibilité de définir ses propres MIB
enregistrement gratuit auprès du IANA
le logiciel standard du monde Unix
(anciennement UCD-SNMP)
le Apache du SNMP
serveurs : snmpd
, snmptrapd
clients : snmpget
, snmpwalk
, snmptrap
informations natives sur les interfaces réseau, processus, volumes, charges CPU et mémoire
ajout de hiérarchies d'OID
extension par de nombreux mécanismes :
exécution de commandes : exec
, extend
, pass
, pass_persist
chargement de code : Perl embarqué, dlmod
communication avec d'autres agents : proxy
, SMUX, AgentX
pass
pass MIBOID COMMAND
exécution de la commande pour chaque requête
COMMAND -g OID # get COMMAND -n OID # get-next COMMAND -s OID TYPE VALUE # set
facile à mettre en place
mais peu efficace en cas d'appels fréquents ou de commande lente
pass_persist
pass_persist MIBOID COMMAND
exécution de la commande lors de la première requête
communication avec Net-SNMP via stdin/stdout, par un petit protocole
meilleure tenue en charge
mais nécessité de gérer le protocole
SNMP::Extension::PassPersist
permet d'écrire simplement des extensions pass
et pass_persist
conçu pour être utilisable immédiatement
peu de dépendances, faible consommation de ressources
fonctionnement :
ajout d'entrées (OID, type, valeur)
boucle d'exécution qui se charge du reste
possibilité de forker la partie mise à jour des valeurs
SNMP::Extension::PassPersist
synopsis typique pour un programme pass
:
#!/usr/bin/perl use strict; use SNMP::Extension::PassPersist; my $root_oid = ".1.3.6.1.4.1.32272"; # create the object my $extsnmp = SNMP::Extension::PassPersist->new; # add a few OID entries $extsnmp->add_oid_entry("$root_oid.42.1", "integer", 42); $extsnmp->add_oid_entry("$root_oid.42.2", "string" , "the answer"); # run the program $extsnmp->run;
SNMP::Extension::PassPersist
synopsis typique pour un programme pass_persist
:
#!/usr/bin/perl use strict; use SNMP::Extension::PassPersist; my $root_oid = ".1.3.6.1.4.1.32272"; # create the object my $extsnmp = SNMP::Extension::PassPersist->new( backend_collect => \&update_tree, ); # run the program $extsnmp->run; sub update_tree { my ($self) = @_; # add a few OID entries $self->add_oid_entry("$root_oid.42.1", "integer", 42); $self->add_oid_entry("$root_oid.42.2", "string" , "the answer"); }
protocole d'envoi des requêtes à un sous-agent externe
permet de décorréler les sous-agents du daemon Net-SNMP
typiquement exécutés eux-mêmes comme daemons
API disponible en Perl avec NetSNMP::Agent
documentation peu claire
propre boucle d'exécution
POE::Component::NetSNMP::agent
fine couche POE autour de NetSNMP::agent
services supplémentaires
POE::Component::NetSNMP::agent
comme avec NetSNMP::agent, mais compatible POE :
my $agent = POE::Component::NetSNMP::agent->spawn( Alias => "snmp_agent", AgentX => 1, ); $agent->register(".1.3.6.1.4.1.32272", \&agent_handler); POE::Kernel->run; exit; sub agent_handler { my ($kernel, $heap, $args) = @_[ KERNEL, HEAP, ARG1 ]; my ($handler, $reg_info, $request_info, $requests) = @$args; # the rest of the code works like a classic NetSNMP::agent callback my $mode = $request_info->getMode; for (my $request = $requests; $request; $request = $request->next) { if ($mode == MODE_GET) { # ... } elsif ($mode == MODE_GETNEXT) { # ... } else { # ... } } }
POE::Component::NetSNMP::agent
plus simple, le module gère les requêtes :
POE::Session->create( inline_states => { _start => sub { $_[HEAP]{agent} = POE::Component::NetSNMP::agent->spawn( Alias => "snmp_agent", AgentX => 1, AutoHandle => ".1.3.6.1.4.1.32272", ); $_[KERNEL]->yield("update_tree"); }, update_tree => \&update_tree, }, ); POE::Kernel->run; exit; sub update_tree { my ($kernel, $heap) = @_[ KERNEL, HEAP ]; # next update in 30 sec $kernel->delay(update_tree => 30); # add one OID entry $kernel->post(AGENT_ALIAS, add_oid_entry => BASE_OID.".1", ASN_OCTET_STR, "hello"); # add several OID entries at once $kernel->post(AGENT_ALIAS, add_oid_tree => { BASE_OID.".2" => [ ASN_INTEGER, 42 ], BASE_OID.".3" => [ ASN_COUNTER, 1873541 ], BASE_OID.".4" => [ ASN_GAUGE, 235 ], }); }
POE::Component::NetSNMP::agent
encore plus simple, on ne se charge plus que de mettre à jour les données :
my $agent = POE::Component::NetSNMP::agent->new( AgentX => 1, AutoHandle => ".1.3.6.1.4.1.32272", AutoUpdate => [[ \&update_tree, 30 ]], ); $agent->run; sub update_tree { my ($self) = @_; # add one OID entry $self->add_oid_entry(BASE_OID.".1", ASN_OCTET_STR, "hello"); # add several OID entries at once $self->add_oid_tree({ BASE_OID.".2" => [ ASN_INTEGER, 42 ], BASE_OID.".3" => [ ASN_COUNTER, 1873541 ], BASE_OID.".4" => [ ASN_GAUGE, 235 ], }); }