snmp

Published: 26-06-2017

Updated: 27-07-2017

By: Maxime de Roucy

tags: debian snmp

paquets

Je connais trois paquets principaux sous debian :

Binaire installé par chacun de ces paquets :

root@testhost # dpkg -L snmpd | grep 'bin/'
/usr/sbin/snmpd
/usr/sbin/snmptrapd

root@testhost # dpkg -L snmp | grep 'bin/'
/usr/bin/snmpwalk
/usr/bin/snmpdf
/usr/bin/snmpget
/usr/bin/snmpbulkget
/usr/bin/snmpvacm
/usr/bin/snmpbulkwalk
/usr/bin/snmptest
/usr/bin/snmpgetnext
/usr/bin/traptoemail
/usr/bin/snmptrap
/usr/bin/snmpset
/usr/bin/fixproc
/usr/bin/snmpconf
/usr/bin/encode_keychange
/usr/bin/snmpstatus
/usr/bin/snmptable
/usr/bin/snmpnetstat
/usr/bin/snmpusm
/usr/bin/snmpdelta
/usr/bin/snmptranslate
/usr/bin/snmpinform

root@testhost # dpkg -L snmp-mibs-downloader | grep 'bin/'
/usr/bin/download-mibs

configuration

La configuration par défaut est la suivante. Attention, l’ordre des instructions est importante (J’ai essayé d’ajouter un “rocommunity” en fin de fichier… sans succès).

root@testhost # grep -v -e '^\s*#' -e '^\s*$'  /etc/snmp/snmpd.conf
agentAddress  udp:127.0.0.1:161
view   systemonly  included   .1.3.6.1.2.1.1
view   systemonly  included   .1.3.6.1.2.1.25.1
 rocommunity public  default    -V systemonly
 rocommunity6 public  default   -V systemonly
 rouser   authOnlyUser
sysLocation    Sitting on the Dock of the Bay
sysContact     Me <me@example.org>
sysServices    72
proc  mountd
proc  ntalkd    4
proc  sendmail 10 1
disk       /     10000
disk       /var  5%
includeAllDisks  10%
load   12 10 5
 trapsink     localhost public
iquerySecName   internalUser
rouser          internalUser
defaultMonitors          yes
linkUpDownNotifications  yes
 extend    test1   /bin/echo  Hello, world!
 extend-sh test2   echo Hello, world! ; echo Hi there ; exit 35
 master          agentx

Par défaut une partie de la MIB est publique.

root@testhost # grep rocommunity /etc/snmp/snmpd.conf | grep -v '^\s*#'
 rocommunity public  default    -V systemonly
 rocommunity6 public  default   -V systemonly

root@testhost # snmpget -v 2c -c public 127.0.0.1 .1.3.6.1.2.1.1.5.0
iso.3.6.1.2.1.1.5.0 = STRING: "testhost"

quelques OIDs

snmpwalk :

snmpget :

Liens utils : * oid-info.com * cric.grenoble.cnrs.fr

snmpget & snmpwalk

snmpget permet de récupérer un OID en particulier, une feuil de la MIB, tandis que snmpwalk récupère tout un subtree de la MIB.

Exemple pour le hostname :

max@testhost % snmpwalk -v 2c -c public localhost .1.3.6.1.2.1.1.5
iso.3.6.1.2.1.1.5.0 = STRING: "testhost"
max@testhost % snmpwalk -v 2c -c public localhost .1.3.6.1.2.1.1.5.0
iso.3.6.1.2.1.1.5.0 = STRING: "testhost"
max@testhost % snmpget -v 2c -c public localhost .1.3.6.1.2.1.1.5
iso.3.6.1.2.1.1.5 = No Such Instance currently exists at this OID
max@testhost % snmpget -v 2c -c public localhost .1.3.6.1.2.1.1.5.0
iso.3.6.1.2.1.1.5.0 = STRING: "testhost"

tcpdump

Les OIDS sont visible via tcpdump :

root@testhost # tcpdump -w snmp.out -i lo -vn port 161 &> /dev/null &
root@testhost # snmpget -v 2c -c public 127.0.0.1 .1.3.6.1.2.1.1.5.0
iso.3.6.1.2.1.1.5.0 = STRING: "testhost"
root@testhost # kill %1
root@testhost # tcpdump -r snmp.out -vn
reading from file snmp.out, link-type EN10MB (Ethernet)
23:26:05.962441 IP (tos 0x0, ttl 64, id 20725, offset 0, flags [DF], proto UDP (17), length 71)
    127.0.0.1.33921 > 127.0.0.1.161:  { SNMPv2c { GetRequest(28) R=1198205535  .1.3.6.1.2.1.1.5.0 } }
23:26:05.962681 IP (tos 0x0, ttl 64, id 20726, offset 0, flags [DF], proto UDP (17), length 79)
    127.0.0.1.161 > 127.0.0.1.33921:  { SNMPv2c { GetResponse(36) R=1198205535  .1.3.6.1.2.1.1.5.0="testhost" } }

utilisation des noms

Pour pouvoir utiliser des OIDs sous leurs formes textuel il est obligatoire d’installer snmp-mibs-downloader.

root@testhost # cat /etc/apt/sources.list
deb http://ftp2.fr.debian.org/debian jessie main
root@testhost # sed -i 's/$/ non-free/' /etc/apt/sources.list
root@testhost # cat /etc/apt/sources.list
deb http://ftp2.fr.debian.org/debian jessie main non-free
root@testhost # apt update
root@testhost # apt install snmp-mibs-downloader

Pour connaitre la représentation textuel/numérique d’une OID j’utilise snmptranslate :

root@testhost # snmptranslate -m ALL -Tl .1.3.6.1.2.1.1.5.0 2>/dev/null
SNMPv2-MIB::sysName.0
root@testhost # snmptranslate -m ALL -On SNMPv2-MIB::sysName.0 2>/dev/null
.1.3.6.1.2.1.1.5.0
root@testhost # snmptranslate -m ALL -Tl .1.3.6.1.4.1.8072.1.3.2.4.1.2 2>/dev/null
NET-SNMP-EXTEND-MIB::nsExtendOutLine
root@testhost # snmptranslate -m ALL -Td .1.3.6.1.2.1.1.5.0 2>/dev/null
SNMPv2-MIB::sysName.0
sysName OBJECT-TYPE
  -- FROM       SNMPv2-MIB, RFC1213-MIB
  -- TEXTUAL CONVENTION DisplayString
  SYNTAX        OCTET STRING (0..255)
  DISPLAY-HINT  "255a"
  MAX-ACCESS    read-write
  STATUS        current
  DESCRIPTION   "An administratively-assigned name for this managed
            node.  By convention, this is the node's fully-qualified
            domain name.  If the name is unknown, the value is
            the zero-length string."
::= { iso(1) org(3) dod(6) internet(1) mgmt(2) mib-2(1) system(1) sysName(5) 0 }
root@testhost # snmptranslate -m ALL -Tl 2>/dev/null | head
.iso(1).org(3)
.iso(1).org(3).dod(6)
.iso(1).org(3).dod(6).internet(1)
.iso(1).org(3).dod(6).internet(1).directory(1)
.iso(1).org(3).dod(6).internet(1).mgmt(2)
.iso(1).org(3).dod(6).internet(1).mgmt(2).mib-2(1)
.iso(1).org(3).dod(6).internet(1).mgmt(2).mib-2(1).system(1)
.iso(1).org(3).dod(6).internet(1).mgmt(2).mib-2(1).system(1).sysDescr(1)
.iso(1).org(3).dod(6).internet(1).mgmt(2).mib-2(1).system(1).sysObjectID(2)
.iso(1).org(3).dod(6).internet(1).mgmt(2).mib-2(1).system(1).sysUpTime(3)

Étendre la MIB

extend

Sources :

Il est possible d’ajouter des éléments à la MIB. Il s’agit de l’extension « NET-SNMP-EXTEND-MIB » (OID racine : .1.3.6.1.4.1.8072.1.3).

root@testhost # grep -v -e '^\s*#' -e '^\s*$'  /etc/snmp/snmpd.conf | grep 'extend'
 extend    test1   /bin/echo  Hello, world!
 extend-sh test2   echo Hello, world! ; echo Hi there ; exit 35
root@testhost # snmpwalk -v 2c -c public 127.0.0.1  .1.3.6.1.4.1.8072.1.3.2.4.1.2
iso.3.6.1.4.1.8072.1.3.2.4.1.2.5.116.101.115.116.49.1 = STRING: "Hello, world!"
iso.3.6.1.4.1.8072.1.3.2.4.1.2.5.116.101.115.116.50.1 = STRING: "Hello, world!"
iso.3.6.1.4.1.8072.1.3.2.4.1.2.5.116.101.115.116.50.2 = STRING: "Hi there"
root@testhost # echo 'extend test /bin/echo toto' >> /etc/snmp/snmpd.conf
root@testhost # systemctl restart snmpd
root@testhost # snmpwalk -v 2c -c public 127.0.0.1  .1.3.6.1.4.1.8072.1.3.2.4.1.2
iso.3.6.1.4.1.8072.1.3.2.4.1.2.4.116.101.115.116.1 = STRING: "toto"
iso.3.6.1.4.1.8072.1.3.2.4.1.2.5.116.101.115.116.49.1 = STRING: "Hello, world!"
iso.3.6.1.4.1.8072.1.3.2.4.1.2.5.116.101.115.116.50.1 = STRING: "Hello, world!"
iso.3.6.1.4.1.8072.1.3.2.4.1.2.5.116.101.115.116.50.2 = STRING: "Hi there"

Par défaut cette branche de la MIB n’est pas accessible :

root@testhost # snmpwalk -v 2c -c public 127.0.0.1 NET-SNMP-EXTEND-MIB::nsExtendOutLine | head -1
NET-SNMP-EXTEND-MIB::nsExtendOutLine = No more variables left in this MIB View (It is past the end of the MIB tree)

Pour pouvoir la requêter il faut decommenter la ligne rocommunity public localhost du fichier de configuration :

root@testhost # sed -i 's/^#\(rocommunity\s\+public\s\+localhost\)$/\1/' /etc/snmp/snmpd.conf
root@testhost # systemctl restart snmpd
root@testhost # snmpwalk -v 2c -c public 127.0.0.1 NET-SNMP-EXTEND-MIB::nsExtendOutLine
NET-SNMP-EXTEND-MIB::nsExtendOutLine."test1".1 = STRING: Hello, world!
NET-SNMP-EXTEND-MIB::nsExtendOutLine."test2".1 = STRING: Hello, world!
NET-SNMP-EXTEND-MIB::nsExtendOutLine."test2".2 = STRING: Hi there

Cette extention définit plusieurs OIDs :

root@testhost # echo 'extend test /bin/echo toto' >> /etc/snmp/snmpd.conf
root@testhost # systemctl restart snmpd
root@testhost # snmpwalk -v 2c -c public 127.0.0.1 NET-SNMP-EXTEND-MIB::nsExtendOutput1Table
NET-SNMP-EXTEND-MIB::nsExtendOutput1Line."test" = STRING: toto
NET-SNMP-EXTEND-MIB::nsExtendOutput1Line."test1" = STRING: Hello, world!
NET-SNMP-EXTEND-MIB::nsExtendOutput1Line."test2" = STRING: Hello, world!
NET-SNMP-EXTEND-MIB::nsExtendOutputFull."test" = STRING: toto
NET-SNMP-EXTEND-MIB::nsExtendOutputFull."test1" = STRING: Hello, world!
NET-SNMP-EXTEND-MIB::nsExtendOutputFull."test2" = STRING: Hello, world!
Hi there
NET-SNMP-EXTEND-MIB::nsExtendOutNumLines."test" = INTEGER: 1
NET-SNMP-EXTEND-MIB::nsExtendOutNumLines."test1" = INTEGER: 1
NET-SNMP-EXTEND-MIB::nsExtendOutNumLines."test2" = INTEGER: 2
NET-SNMP-EXTEND-MIB::nsExtendResult."test" = INTEGER: 0
NET-SNMP-EXTEND-MIB::nsExtendResult."test1" = INTEGER: 0
NET-SNMP-EXTEND-MIB::nsExtendResult."test2" = INTEGER: 8960
root@testhost # snmpwalk -v 2c -c public 127.0.0.1 NET-SNMP-EXTEND-MIB::nsExtendOutLine
NET-SNMP-EXTEND-MIB::nsExtendOutLine."test".1 = STRING: toto
NET-SNMP-EXTEND-MIB::nsExtendOutLine."test1".1 = STRING: Hello, world!
NET-SNMP-EXTEND-MIB::nsExtendOutLine."test2".1 = STRING: Hello, world!
NET-SNMP-EXTEND-MIB::nsExtendOutLine."test2".2 = STRING: Hi there

OID

root@testhost # snmptranslate -On 'NET-SNMP-EXTEND-MIB::nsExtendOutput1Line."test"'
.1.3.6.1.4.1.8072.1.3.2.3.1.1.4.116.101.115.116

Le(s) OID correspondant à un extend se décompose en 4 parties :

pass

pass permet d’associer un OID à une commande mais est beaucoup moin souple (je trouve). Il faut définir soit-même l’OID ce qui peut être problématique losqu’on en ajoute beaucoup. Il faut que le programme appelé ai un output particulier.

Ici je me contenterai de citer le man :

pass [-p priority] MIBOID PROG

will pass control of the subtree rooted at MIBOID to the specified PROG command. GET and GETNEXT requests for OIDs within this tree will trigger this command, called as:

respectively, where OID is the requested OID. The PROG command should return the response varbind as three separate lines printed to stdout - the first line should be the OID of the returned value, the second should be its TYPE (one of the text strings integer, gauge, counter, timeticks, ipaddress, objectid, or string ), and the third should be the value itself.