Analyse du protocole

Nous allons regarder avec Wireshark, notre sniffeur favori, ce qu'il se passe en utilisant trois commandes classiques : snmpget, snmpwalk et snmpbulkwalk (utilisable seulement avec la version v2c ou supérieure de SNMP).

snmpget

Demandons, une fois encore à notre switch de nous dire son nom :

~$ snmpget -v 1 -c public -Ot 172.16.252.2 SNMPv2-MIB::sysName.0
SNMPv2-MIB::sysName.0 = STRING: ProCurve Switch 2650-1

Voyons ce que notre sniffeur a épié :

No.     Time        Source                Destination           Protocol Info
      1 0.000000    192.168.0.16          172.16.252.2          SNMP     get-request 1.3.6.1.2.1.1.5.0

Frame 1 (85 bytes on wire, 85 bytes captured)
...
User Datagram Protocol, Src Port: 42380 (42380), Dst Port: snmp (161)
    Source port: 42380 (42380)
    Destination port: snmp (161)
    Length: 51
    Checksum: 0x6910 [validation disabled]
        [Good Checksum: False]
        [Bad Checksum: False]
Simple Network Management Protocol
    version: version-1 (0)
    community: public
    data: get-request (0)
        get-request
            request-id: 925410341
            error-status: noError (0)
            error-index: 0
            variable-bindings: 1 item
                1.3.6.1.2.1.1.5.0: Value (Null)
                    Object Name: 1.3.6.1.2.1.1.5.0 (iso.3.6.1.2.1.1.5.0)

Nous sommes bien en UDP et le port cible est bien 161.

SNMP est bien utilisé en version 1, la commande est get-request et l'OID demandée est 1.3.6.1.2.1.1.5.0.

La réponse :

No.     Time        Source                Destination           Protocol Info
      2 0.072588    172.16.252.2          192.168.0.16          SNMP     get-response 1.3.6.1.2.1.1.5.0

Frame 2 (107 bytes on wire, 107 bytes captured)
...
User Datagram Protocol, Src Port: snmp (161), Dst Port: 42380 (42380)
    Source port: snmp (161)
    Destination port: 42380 (42380)
    Length: 73
    Checksum: 0x180f [validation disabled]
        [Good Checksum: False]
        [Bad Checksum: False]
Simple Network Management Protocol
    version: version-1 (0)
    community: public
    data: get-response (2)
        get-response
            request-id: 925410341
            error-status: noError (0)
            error-index: 0
            variable-bindings: 1 item
                1.3.6.1.2.1.1.5.0: 50726F43757276652053776974636820323635302D31
                    Object Name: 1.3.6.1.2.1.1.5.0 (iso.3.6.1.2.1.1.5.0)
                    Value (OctetString): 50726F43757276652053776974636820323635302D31

Nous avons la réponse (get-response), elle n'est pas très lisible car donnée sous forme numérique (la version 1.2.7 de wireshark semblant avoir du mal avec le décodage de SNMP).

Nous ne referons pas la manipulation en v2c, le résultat étant le même.

snmpwalk

Voyons maintenant la branche system en entier, avec la commande snmpwalk :

$ snmpwalk -v 1 -c public -Ot 172.16.252.2 SNMPv2-MIB::system
SNMPv2-MIB::sysDescr.0 = STRING: ProCurve J4899B Switch 2650, revision H.10.35, ROM H.08.02 (/sw/code/build/fish(mkfs))
SNMPv2-MIB::sysObjectID.0 = OID: SNMPv2-SMI::enterprises.11.2.3.7.11.44
DISMAN-EVENT-MIB::sysUpTimeInstance = 1123840470
SNMPv2-MIB::sysContact.0 = STRING: sysop
SNMPv2-MIB::sysName.0 = STRING: ProCurve Switch 2650-1
SNMPv2-MIB::sysLocation.0 = STRING: 
SNMPv2-MIB::sysServices.0 = INTEGER: 74

Wireshark a vu une suite de commandes :

No.     Time        Source                Destination           Protocol Info
      1 0.000000    192.168.0.16          172.16.252.2          SNMP     get-next-request 1.3.6.1.2.1.1
      2 0.101794    172.16.252.2          192.168.0.16          SNMP     get-response 1.3.6.1.2.1.1.1.0
      3 0.101915    192.168.0.16          172.16.252.2          SNMP     get-next-request 1.3.6.1.2.1.1.1.0
      4 0.172930    172.16.252.2          192.168.0.16          SNMP     get-response 1.3.6.1.2.1.1.2.0
      5 0.173003    192.168.0.16          172.16.252.2          SNMP     get-next-request 1.3.6.1.2.1.1.2.0
      6 0.244100    172.16.252.2          192.168.0.16          SNMP     get-response 1.3.6.1.2.1.1.3.0
      7 0.244174    192.168.0.16          172.16.252.2          SNMP     get-next-request 1.3.6.1.2.1.1.3.0
      8 0.315341    172.16.252.2          192.168.0.16          SNMP     get-response 1.3.6.1.2.1.1.4.0
      9 0.315412    192.168.0.16          172.16.252.2          SNMP     get-next-request 1.3.6.1.2.1.1.4.0
     10 0.389045    172.16.252.2          192.168.0.16          SNMP     get-response 1.3.6.1.2.1.1.5.0
     11 0.389109    192.168.0.16          172.16.252.2          SNMP     get-next-request 1.3.6.1.2.1.1.5.0
     12 0.460725    172.16.252.2          192.168.0.16          SNMP     get-response 1.3.6.1.2.1.1.6.0
     13 0.460787    192.168.0.16          172.16.252.2          SNMP     get-next-request 1.3.6.1.2.1.1.6.0
     14 0.532128    172.16.252.2          192.168.0.16          SNMP     get-response 1.3.6.1.2.1.1.7.0
     15 0.532189    192.168.0.16          172.16.252.2          SNMP     get-next-request 1.3.6.1.2.1.1.7.0
     16 0.624758    172.16.252.2          192.168.0.16          SNMP     get-response 1.3.6.1.2.1.2.1.0

Pas la peine de détailler, nous voyons bien une suite de get-next-request émises par le client, suivies des get-response de l'agent SNMP du switch. Nous avons ici 8 trames d'interrogation et 8 trames de réponses. Si l'on désire parcourir une branche importante, le réseau va avoir du travail.

snmpbulkwalk

Innovation de la version 2c, observons la différence :

$ snmpbulkwalk -v 1 -c public -Ot 172.16.252.2 SNMPv2-MIB::system
snmpbulkwalk: Cannot send V2 PDU on V1 session

Juste pour vérifier que cette commande ne peut fonctionner si l'on utilise SNMP v1.

$ snmpbulkwalk -v 2c -c public -Ot 172.16.252.2 SNMPv2-MIB::system
SNMPv2-MIB::sysDescr.0 = STRING: ProCurve J4899B Switch 2650, revision H.10.35, ROM H.08.02 (/sw/code/build/fish(mkfs))
SNMPv2-MIB::sysObjectID.0 = OID: SNMPv2-SMI::enterprises.11.2.3.7.11.44
DISMAN-EVENT-MIB::sysUpTimeInstance = 1123894614
SNMPv2-MIB::sysContact.0 = STRING: sysop
SNMPv2-MIB::sysName.0 = STRING: ProCurve Switch 2650-1
SNMPv2-MIB::sysLocation.0 = STRING: 
SNMPv2-MIB::sysServices.0 = INTEGER: 74

A première vue, nous obtenons exactement le même résultat qu'avec snmpwalk. Cependant, voici ce qu'a vu Wireshark en vue condensée :

No.     Time        Source                Destination           Protocol Info
      1 0.000000    192.168.0.16          172.16.252.2          SNMP     getBulkRequest 1.3.6.1.2.1.1
      2 0.077623    172.16.252.2          192.168.0.16          SNMP     get-response 1.3.6.1.2.1.1.1.0 1.3.6.1.2.1.1.2.0 1.3.6.1.2.1.1.3.0 1.3.6.1.2.1.1.4.0 1.3.6.1.2.1.1.5.0 1.3.6.1.2.1.1.6.0 1.3.6.1.2.1.1.7.0 1.3.6.1.2.1.2.1.0 1.3.6.1.2.1.2.2.1.1.1 1.3.6.1.2.1.2.2.1.1.2

Deux trames seulement. Voyons maintenant le détail :

Frame 1 (83 bytes on wire, 83 bytes captured)
...
Simple Network Management Protocol
    version: v2c (1)
    community: public
    data: getBulkRequest (5)
        getBulkRequest
            request-id: 112026182
            non-repeaters: 0
            max-repetitions: 10
            variable-bindings: 1 item
                1.3.6.1.2.1.1: Value (Null)
                    Object Name: 1.3.6.1.2.1.1 (iso.3.6.1.2.1.1)
                    Value (Null)

La requête est ici getBulkRequest et elle est unique. Tout le détail de la branche se trouve dans une seule réponse :

Frame 2 (353 bytes on wire, 353 bytes captured)
...
Simple Network Management Protocol
    version: v2c (1)
    community: public
    data: get-response (2)
        get-response
            request-id: 112026182
            error-status: noError (0)
            error-index: 0
            variable-bindings: 10 items
                1.3.6.1.2.1.1.1.0: 50726F4375727665204A3438393942205377697463682032...
                    Object Name: 1.3.6.1.2.1.1.1.0 (iso.3.6.1.2.1.1.1.0)
                    Value (OctetString): 50726F4375727665204A3438393942205377697463682032...
                1.3.6.1.2.1.1.2.0: 1.3.6.1.4.1.11.2.3.7.11.44 (iso.3.6.1.4.1.11.2.3.7.11.44)
                    Object Name: 1.3.6.1.2.1.1.2.0 (iso.3.6.1.2.1.1.2.0)
                    Value (OID): 1.3.6.1.4.1.11.2.3.7.11.44 (iso.3.6.1.4.1.11.2.3.7.11.44)
                1.3.6.1.2.1.1.3.0: 1123894614
                    Object Name: 1.3.6.1.2.1.1.3.0 (iso.3.6.1.2.1.1.3.0)
                    Value (Timeticks): 1123894614
                1.3.6.1.2.1.1.4.0: 7379736F70
                    Object Name: 1.3.6.1.2.1.1.4.0 (iso.3.6.1.2.1.1.4.0)
                    Value (OctetString): 7379736F70
                1.3.6.1.2.1.1.5.0: 50726F43757276652053776974636820323635302D31
                    Object Name: 1.3.6.1.2.1.1.5.0 (iso.3.6.1.2.1.1.5.0)
                    Value (OctetString): 50726F43757276652053776974636820323635302D31
                1.3.6.1.2.1.1.6.0: 
                    Object Name: 1.3.6.1.2.1.1.6.0 (iso.3.6.1.2.1.1.6.0)
                    Value (OctetString): 
                1.3.6.1.2.1.1.7.0: 74
                    Object Name: 1.3.6.1.2.1.1.7.0 (iso.3.6.1.2.1.1.7.0)
                    Value (Integer32): 74
                1.3.6.1.2.1.2.1.0: 55
                    Object Name: 1.3.6.1.2.1.2.1.0 (iso.3.6.1.2.1.2.1.0)
                    Value (Integer32): 55
                1.3.6.1.2.1.2.2.1.1.1: 1
                    Object Name: 1.3.6.1.2.1.2.2.1.1.1 (iso.3.6.1.2.1.2.2.1.1.1)
                    Value (Integer32): 1
                    Object Name: 1.3.6.1.2.1.2.2.1.1.2 (iso.3.6.1.2.1.2.2.1.1.2)
                    Value (Integer32): 2
Deux trames qui font le même boulot que les 16 précédentes avec snmpwalk, le réseau va apprécier. De quoi convaincre d'utiliser plutôt v2c, quand c'est possible.