SNMP

Simple Network Management Protocol (abrégé SNMP), en français « protocole simple de gestion de réseau », est un protocole de communication qui permet aux administrateurs réseau de gérer les équipements du réseau, de superviser et de diagnostiquer des problèmes réseaux et matériels à distance.

Le protocole SNMP peut être utilisé avec nagios par exemple pour superviser des switchs ou des firewalls.

une requête snmp va nécessiter de connaître:

  • l’ip de l’élément qu’on souhaite surveiller
  • le domaine de la requête (souvent public)
  • l’OIDs de la requête (l’identifiant de la requête)

Sous linux il est très facile d’obtenir une information à partir de snmp

root@srvpzdeb01:~# snmpget -v 1 -c public 194.0.4.1 .1.3.6.1.2.1.2.2.1.10.14
iso.3.6.1.2.1.2.2.1.10.14 = Counter32: 3405673760

on fournit avec la commande snmpget:

  • la version 1
  • la communauté (ou domaine) public
  • l’ip 194.0.4.1
  • l’oid .1.3.6.1.2.1.2.2.1.10.14

Il est souvent difficile d’obtenir les OIDS, mais on peut utiliser pour cela des fichier MIB qui fournissent les différents éléments

Pour lire les fichiers MIB et obtenir des informations il existe un outil simple nommé Ireosoning MIB Browser

_images/20120706_01.png

cet outil permet simplement d’ouvrir un fichier MIB et d’explorer l’arbre des OIDS

et il permet rapidement d’avoir l’oid

_images/20120706_02.png
_images/20120706_03.png

via python et le module pysnmp il est possible de programmer rapidement des outils d’interrogation SNMP voir de sonde nagios.

Voici un exemple concret qui permet d’obtenir la vitesse des différentes interfaces d’un firewall fortigate

Le principe est le suivant:

l’oids 1,3,6,1,2,1,2,2,1,entry,network permet d’obtenir le nombre d’octet traités par l’interface.

  • network représente l’interface (1,2, ...)
  • entry le type octet 16: octets sortant de l’interface , 10: octets entrant de l’interface

Pour obtenir une vitesse, on effectue un relevé avec un intervalle de temps connu

#!/usr/bin/env python

import sys
import time
from pysnmp.entity.rfc3413.oneliner import cmdgen
import optparse

NAGIOS_OK = 0
NAGIOS_WARNING = 1
NAGIOS_CRITICAL = 2

def list(h,c,p,e,n,t):
    timer = int(t)
    host = str(h)
    community = str(c)
    port = int(p)
    entry = int(e)
    network = int(n)
    #print "polling devices"
    cg = cmdgen.CommandGenerator()
    comm_data = cmdgen.CommunityData('my-manager', community)
    transport = cmdgen.UdpTransportTarget((host,port))
    variables = (1,3,6,1,2,1,2,2,1,entry,network)
    errIndiction, errStatus, errIndex, result = cg.getCmd(comm_data, transport, variables)
    if errIndiction:
        print errIndiction
        sys.exit(NAGIOS_CRITICAL)
    elif errStatus:
        print errStatus
        sys.exit(NAGIOS_CRITICAL)
    elif errIndex:
        print errIndex
        sys.exit(NAGIOS_CRITICAL)
    elif result:
        for i in result:
            v = i[1]
            result1 = v
    time.sleep(timer)
    errIndiction, errStatus, errIndex, result = cg.getCmd(comm_data, transport, variables)
    if errIndiction:
        print errIndiction
        sys.exit(NAGIOS_CRITICAL)
    elif errStatus:
        print errStatus
        sys.exit(NAGIOS_CRITICAL)
    elif errIndex:
        print errIndex
        sys.exit(NAGIOS_CRITICAL)
    elif result:
        for i in result:
            v = i[1]
            result2 = v
    else:
        print "strange stupid error "
    try:
        vit= (int(result2)-int(result1))/(timer*1024)
        print "OK - speed of network on %.2f KB/s | 'vitesse'=%.2f;10000;10000;0;10000" % (vit,vit)
        sys.exit(NAGIOS_OK)
    except Exception as e:
        print 'CRITICAL - evaluate speed not possible - %s' % str(e)
        sys.exit(NAGIOS_CRITICAL)

def main():
    parser = optparse.OptionParser(description='evaluate speed network by snmp on TIMER seconds',
            prog='snmpfortigate.py',version='snmpfortigate.py 0.1',
            usage='%prog [-H hostname -C community -P port -E entry -N network -T timer]')
    parser.add_option('-H', '--host', dest="host_flag", help="specify the address of the host")
    parser.add_option('-C', '--community', dest="snmp_flag", help="snmp community string")
    parser.add_option('-P', '--port', dest="snmp_port", help="snmp port (161)")
    parser.add_option('-N', '--network', dest="snmp_net", help="id of network")
    parser.add_option('-E', '--entry', dest="snmp_entry", help="if of entry mib")
    parser.add_option('-T', '--timer', dest="snmp_timer", help="time betwwen two values")
    (options, args) = parser.parse_args()
    if options.host_flag and options.snmp_flag and options.snmp_port and options.snmp_entry and options.snmp_net and options.snmp_timer:
        list(options.host_flag,options.snmp_flag,options.snmp_port, options.snmp_entry, options.snmp_net, options.snmp_timer )
    elif len(args) !=1:
        parser.error("wrong number of arguments")
    else:
        print "bad argument, use -h for help.."


main()