# SNMP # Simple Network Managment Protocol lets us collect information about devices on IP networks, including routers, switches, printers, etc. It's also possible to write configurations using (some versions of) SNMP. SNMP has three major versions: SNMPv1, SNMPv2c, and SNMPv3. The version are incompatible with each other. SNMPv3 offers improved security. SNMPv1 is still the most widely used. A _manager_ running on a Network Management Station collects information from _agents_ running on Managed Devices. SNMP agents expose data organized as hierarchies of key-value pairs. The hierarchy for a particular device is described in a Management Information Base (MIB). Each key/value in that hierarchy is known as an OID (Object Identifier). The SNMP manager sends requests to UDP port 161 of the managed devices (or port 10161 with TLS). The manager receives notifications (traps and InformRequests) on port 162 (or 10162 for TLS). The only real security in SNMP versions 1 and 2 is the secret community name, which is itself susceptible to sniffing. SNMP _traps_ allow agents to send notifications to managers, usually triggered by an event on the managed device (e.g. a predefined threshold exceeded). Debian has a package with several SNMP tools/utilities (snmpwalk, snmptable, snmptest, snmpset, snmptranslate, etc.): % sudo apt-get install snmp snmp-mibs-downloader % snmpwalk -c foo_community -v 1 -m ALL 10.0.0.1 What the values returned by snmpwalk represent may not be obvious. They vary by device. Some devices are better than other at making the values decipherable. A MIB module (definition file) from the device vendor may provide better information. Having the MIB module means the difference between snmpwalk returning the raw numeric key versus descriptive key: iso.3.6.1.2.1.31.1.4.1.3.1.6.0.21.23.180.44.42 = INTEGER: 3 IF-MIB::ifRcvAddressType.1."....,*" = INTEGER: nonVolatile(3) This may or may not be helpful. The numbering of the tree is actually defined in the ISO standard. We're usually going to be looking at OIDs under .1.3.6.1.2.1.1, where 1 = iso, 3 = org, 6 = dod, 1 = internet, 2 = mgmt, 1 = mib, 1 = system.... These two commands are equivalent, for example: % snmpwalk -c foo_community -v 1 -m ALL 10.0.0.1 .1.3.6.1.2.1.1 % snmpwalk -c foo_community -v 1 -m ALL 10.0.1.1 .iso.org.dod.internet.mgmt.mib-2.system RFC 1213, RFC 2863, and RFC 3418 define a number of standard OIDs found in most devices (e.g. 'system.sysDescr', 'system.sysUpTime', 'interfaces.ifNumber'). % snmpwalk -c foo_community -v 1 -m ALL 10.0.0.1 ifDescr && snmpwalk -c foo_community -v 1 -m ALL 10.0.0.1 ifOperStatus Or just: % snmpwalk -c foo_community -m ALL -v 1 10.0.0.1 interfaces `snmpwalk` can translate between names and numeric OIDs (and do other formatting) using the `-O` flag: % snmpwalk -c foo_community -m ALL -v 2c 10.0.0.1 BEGEMOT-PF-MIB::pfStateTableCount -On .1.3.6.1.4.1.12325.1.200.1.3.1.0 = Gauge32: 7182 % snmpwalk -c foo -m ALL -v 2c 10.0.0.1 BEGEMOT-PF-MIB::pfStateTableCount -Of .iso.org.dod.internet.private.enterprises.fokus.begemot.begemotPf.begemotPfObjects.pfStateTable.pfStateTableCount.0 = Gauge32: 7753 For general CPU info, try the UCD-SNMP-MIB::systemStats: % snmpwalk -c foo -m ALL -v 2c 10.0.18.1 .1.3.6.1.4.1.2021.11 For general memory info, try the UCD-SNMP-MIB::memory: % snmpwalk -c foo -m ALL -v 2c 10.0.18.1 .1.3.6.1.4.1.2021.4 Or for load, try UCD-SNMP-MIB::laLoad: % snmpwalk -c foo -m ALL -v 2c 10.0.18.1 UCD-SNMP-MIB::laLoad The 1-minute load average is OID ".1.3.6.1.4.1.2021.10.1.3.1". ## Traps ## Traps let an agent send notifications to a manager. To find pre-defined traps an agent supports, search the MIB for "TRAP-TYPE" (SMIv1) or "NOTIFICATION-TYPE" (SMIv2). Traps are either generic or enterprise-specific. There are seven types of traps: coldStart (0), warmStart (1), linkDown (2), linkUp (3), authenticationFailure (4), egpNeighborLoss (5), and enterpriseSpecific (6). ## Example Scenario ## We want to use collectd to monitor the bandwidth usage of interfaces on a pfSense box. Assume collectd is installed and working of our network management station, and that we've turned on the SNMP service on pfSense. We may want to grab the MIBs from , and save them in `$HOME/.snmp/mibs/` or `/usr/share/snmp/mibs/`. And . It's often useful to browse MIBs (which are structured plain text) to find interesting OIDs, which _should_ all have DESCRIPTION values. We check what OIDs are available (output condensed to the interesting OIDs): % snmpwalk -c foo -m ALL -v 1 10.0.0.1 interfaces IF-MIB::ifDescr.1 = STRING: em0 IF-MIB::ifDescr.2 = STRING: em1 IF-MIB::ifDescr.3 = STRING: em2 IF-MIB::ifDescr.4 = STRING: re0 IF-MIB::ifSpeed.1 = Gauge32: 100000000 IF-MIB::ifSpeed.2 = Gauge32: 100000000 IF-MIB::ifSpeed.3 = Gauge32: 100000000 IF-MIB::ifSpeed.4 = Gauge32: 1000000000 IF-MIB::ifOperStatus.1 = INTEGER: up(1) IF-MIB::ifOperStatus.2 = INTEGER: up(1) IF-MIB::ifOperStatus.3 = INTEGER: up(1) IF-MIB::ifOperStatus.4 = INTEGER: up(1) IF-MIB::ifInOctets.1 = Counter32: 367188816 IF-MIB::ifInOctets.2 = Counter32: 1123779670 IF-MIB::ifInOctets.3 = Counter32: 2528514260 IF-MIB::ifInOctets.4 = Counter32: 1251233569 IF-MIB::ifOutOctets.1 = Counter32: 2085484005 IF-MIB::ifOutOctets.2 = Counter32: 1263498734 IF-MIB::ifOutOctets.3 = Counter32: 1508835003 IF-MIB::ifOutOctets.4 = Counter32: 1282653750 % snmpwalk -c foo -m ALL -v 2c 10.0.0.1 BEGEMOT-PF-MIB::pfStateTableCount BEGEMOT-PF-MIB::pfStateTableCount.0 = Gauge32: 8154 % snmpwalk -c foo -m ALL -v 2c 10.0.0.1 BEGEMOT-PF-MIB::pfInterfacesIfDescr BEGEMOT-PF-MIB::pfInterfacesIfDescr.6 = STRING: "em0" BEGEMOT-PF-MIB::pfInterfacesIfDescr.7 = STRING: "em1" BEGEMOT-PF-MIB::pfInterfacesIfDescr.8 = STRING: "em2" BEGEMOT-PF-MIB::pfInterfacesIfDescr.9 = STRING: "enc" BEGEMOT-PF-MIB::pfInterfacesIfDescr.19 = STRING: "re0" % snmpwalk -c foo -m ALL -v 2c 10.0.0.1 BEGEMOT-PF-MIB::pfInterfacesIf4PktsInBlock BEGEMOT-PF-MIB::pfInterfacesIf4PktsInBlock.6 = Counter64: 1053480 BEGEMOT-PF-MIB::pfInterfacesIf4PktsInBlock.7 = Counter64: 426391 BEGEMOT-PF-MIB::pfInterfacesIf4PktsInBlock.8 = Counter64: 3523982 BEGEMOT-PF-MIB::pfInterfacesIf4PktsInBlock.19 = Counter64: 492 In the NMS's `/etc/collectd/collectd.conf`: LoadPlugin snmp Type "if_octets" Table false Instance "fergus_wan_t1_em0" Values "IF-MIB::ifInOctets.1" "IF-MIB::ifOutOctets.1" Type "if_octets" Table false Instance "fergust_wan_cable_em1" Values "IF-MIB::ifInOctets.2" "IF-MIB::ifOutOctets.2" Type "if_octets" Table false Instance "fergus_lan_em2" Values "IF-MIB::ifInOctets.3" "IF-MIB::ifOutOctets.3" Type "if_octets" Table false Instance "fergus_dmz_re0" Values "IF-MIB::ifInOctets.4" "IF-MIB::ifOutOctets.4" Type "pf_states" Table false Instance "pf_state_table_count" Values ".1.3.6.1.4.1.12325.1.200.1.3.1.0" Type "load" Table false Instance "load_avg" Values ".1.3.6.1.4.1.2021.10.1.3.1" ".1.3.6.1.4.1.2021.10.1.3.2" ".1.3.6.1.4.1.2021.10.1.3.3" Address 10.0.0.1 Version 1 Community "foo" Collect "fergus_wan_t1_em0" "fergus_wan_cable_em1" "fergus_lan_em2" "fergus_dmz_re0" "pf_state_table_count" "load_avg" - See - "Type" is mandatory for "Data" sections. The valid types are defined in `/usr/share/collectd/types.db` (or a location specified with the `TypesDB` directive in `collectd.conf`). - "Table" set is this is a single value ("false") or multiple values that will be pulled by `snmpget` ("true"). ## Links ## https://tools.ietf.org/html/rfc3418 https://en.wikipedia.org/wiki/Simple_Network_Management_Protocol https://www.digitalocean.com/community/tutorials/an-introduction-to-snmp-simple-network-management-protocol http://archive.oreilly.com/pub/a/perl/excerpts/system-admin-with-perl/twenty-minute-snmp-tutorial.html http://www.cisco.com/c/en/us/support/docs/ip/simple-network-management-protocol-snmp/8141-calculate-bandwidth-snmp.html https://collectd.org/documentation/manpages/collectd-snmp.5.shtml