SNMP

From Genunix

The Simple Network Management Protocol (SNMP) forms part of the internet protocol suite as defined by the Internet Engineering Task Force (IETF). SNMP is used in network management systems to monitor network-attached devices for conditions that warrant administrative attention. It consists of a set of standards for network management, including an Application Layer protocol, a database schema, and a set of data objects.

For Solaris specific implementation please see Solaris SNMP: System Management Agent

Contents

Architecture

SNMP uses a client-server architecture wherein managers (clients) send requests to agents (servers). Servers being monitored use a delegated architecture wherein a Master Agent delegates requests to applicable Sub-Agents. These sub-agents use the Agent X protocol defined in RFC2741.

snmp-architecture.gif

Typically the manager is a Network Management Station (NMS) software solution such as Tivoli, HP OpenView, OpenNMS, Nagios, or other such application.

SNMP Version 3

SNMPv3 brings significant security features to the SNMP protocol, including:

  • Message integrity to ensure that a packet has not been tampered with in transit.
  • Authentication to verify that the message is from a valid source.
  • Encryption of packets to prevent snooping by an unauthorized source.

Most simply put, SNMPv3 mandates users and password. Each user is assigned both a protocol and password/key both authentication (MD5/SHA) and privacy (DES/AES). The associated buzzwords are User Security Model (USM) and View Access Control Model (VACM).

In addition to this, SNMPv3 does away with the previous agent/manager verbage and instead view either as an entity. Sub-agents are therefore now refered to as applications, so on and so forth. While this has no practical implications (of which I am aware) it creates a more clearly defined architecture than was previously provided.

Net-SNMP Tools and SNMPv3

SNMPv3 does away with communities, and thus Net-SNMP tools like snmpwalk and snmpget require different syntax. The following arguments replace -c community:


-a PROTOCOL 
set authentication protocol (MD5|SHA)
-A PASSPHRASE 
set authentication protocol pass phrase
-e ENGINE-ID 
set security engine ID (e.g. 800000020109840301)
-E ENGINE-ID 
set context engine ID (e.g. 800000020109840301)
-l LEVEL 
set security level (noAuthNoPriv|authNoPriv|authPriv)
-n CONTEXT 
set context name (e.g. bridge1)
-u USER-NAME 
set security name (e.g. bert)
-x PROTOCOL 
set privacy protocol (DES)
-X PASSPHRASE 
set privacy protocol pass phrase
-Z BOOTS,TIME 
set destination engine boots/time

Thus, the following flags will commonly be used:

                        -u USER
                        -l SECURITY_LEVEL
 Authentication:        -a PROTO -A PASSWD
 Privacy:               -x PROTO -X PASSWD

There are three security levels [1]:

  • noAuthNoPriv: No Authentication or Privacy (just -u and -l)
  • authNoPriv: Authentication but No Privacy (use -aA)
  • authPriv: Authentication and Privcay (use -aA and -xX)

Examples:

benr@ultra ~$ /opt/csw/bin/snmpwalk -v3 -l authNoPriv -u benr -a SHA -A "joyent007" 192.168.0.200 .1
snmpwalk: Authentication failure (incorrect password, community or key)

benr@ultra ~$ /opt/csw/bin/snmpwalk -v3 -l authNoPriv -u benr -a SHA -A "joyent007" -x DES -X "joyentdes" 192.168.0.200 .1
snmpwalk: Authentication failure (incorrect password, community or key)

Drawbacks

While SNMPv3 adds much needed security to its predicessors. User management in Net-SNMP is a major pain in the ass and the following except from Essential SNMP illustrates the problem:

"After [adding a user], stop and restart the agent. When the agent is started, it reads the configuration file, computes secret keys for the users you have added, and deletes the createUser commands from the file. It then places the secret key in the configuration file. This behavior has a number of consequences. The secret key is based on the engine ID, which for Net-SNMP is based on the IP address. Therefore, you can't copy configuration files from one machine to another. Furthermore, if you change a machine's IP address, you will have to reconfigure Net-SNMP: stop the agent, edit /var/ucd-snmp/snmpd.conf, delete any entries Net-SNMP has added for your users, add createUser commands to recreate your users, and start the agent again."

See [2].

Conclusions

For these reasons, SNMPv3 should be seen as an "only if you really need it!" solution to be used in circumstances where SNMPv2 simply isn't wise, such as when polling an SNMP device on the public internet. When ever possible use SNMPv2 on a private network.

SMUX, AgentX, and Sub-Agents

SMUX (RFC 1227) and AgentX (RFC 2741) are protocals for implementing SNMP sub-agents which query data and export it via an SNMP MIB.

For more discussion see [3].

SMUX

From the RFC introduction:

"On typical kernel/user systems, an agent speaking the SNMP [1] is

  often implemented as a user-process, that reads kernel variables in
  order to realize the Internet-standard MIB [2].  This approach works
  fine as long as all of the information needed by the SNMP agent
  resides in either the kernel or in stable storage (i.e., files).
  However, when other user-processes are employed to implement other

"Network services, such as routing protocols, communication between

  the SNMP agent and other processes is problematic.

"In order to solve this problem, a new protocol, the SNMP multiplexing

  (SMUX) protocol is introduced.  When a user-process, termed a SMUX
  peer, wishes to export a MIB module, it initiates a SMUX association
  to the local SNMP agent, registers itself, and (later) fields
  management operations for objects in the MIB module."

AgentX

AgentX is the current standard for implementing agents and is vastly superior to SMUX is many ways. For details please refer directly to RFC 2741.

Documentation regarding the construction of agents using AgentX are very cryptic and hard to find with any reasonable clarity. Good luck on writing one.

Extending Agents Without Writing Your Own

Net-SNMP provides an extensible agent that allows you to provide the data you want without having to write your own agent from scratch using AgentX sub-agents or other silliness.

Exec

The simplest and most straight forward method is to use the exec method. This involves adding an "exec" directive to snmpd.conf that specifies a script to be executed when a given OID is queried. The result is each line of output from the scripts STDOUT being given an incrementing OID benieth the specified OID.

The following is an example declaration in 'snmpd.conf:

#
# Extensions:
#

exec  .1.3.6.1.4.1.2021.66 nfs_client /var/sma_snmp/nfs_client_solaris.sh

In the above example, the OID here is UCD-SNMP-MIB::ucdavis (.1.3.6.1.4.1.2021) followed by an arbitrary number which simply needs to be unique. The string "nfs_client" is returned via an SNMP query to specify the following OIDs.

The script here gathers NFSv3 client stats via Kstats:

#!/bin/bash

proc="getattr setattr lookup access readlink read write create mkdir symlink mknod remove rmdir rename link readdir readdirplus fsstat fsinfo pathconf commit"

for a in $proc; do
       #echo -n "$a.value "

        kstat -p nfs:0:rfsreqcnt_v3:${a} | awk '{print $2}'     

done

When running the script on its own the output looks like this:

root@x4150-01 snmp$ /var/sma_snmp/nfs_client_solaris.sh
47820
0
438
47808
2543
988
0
0
0
0
0
0
0
0
0
0
47822
26
2
0
0

When queried via an snmpwalk the output looks like this:

benr@ultra mibs$ snmpwalk -v2c -c public  ev2-x4150-01.joyent.us .1.3.6.1.4.1.2021.66
UCD-SNMP-MIB::ucdavis.66.1.1 = INTEGER: 1
UCD-SNMP-MIB::ucdavis.66.2.1 = STRING: "nfs_client"
UCD-SNMP-MIB::ucdavis.66.3.1 = STRING: "/var/sma_snmp/nfs_client_solaris.sh"
UCD-SNMP-MIB::ucdavis.66.100.1 = INTEGER: 0
UCD-SNMP-MIB::ucdavis.66.101.1 = STRING: "47820"
UCD-SNMP-MIB::ucdavis.66.101.2 = STRING: "0"
UCD-SNMP-MIB::ucdavis.66.101.3 = STRING: "438"
UCD-SNMP-MIB::ucdavis.66.101.4 = STRING: "47808"
UCD-SNMP-MIB::ucdavis.66.101.5 = STRING: "2543"
UCD-SNMP-MIB::ucdavis.66.101.6 = STRING: "988"
UCD-SNMP-MIB::ucdavis.66.101.7 = STRING: "0"
UCD-SNMP-MIB::ucdavis.66.101.8 = STRING: "0"
UCD-SNMP-MIB::ucdavis.66.101.9 = STRING: "0"
UCD-SNMP-MIB::ucdavis.66.101.10 = STRING: "0"
UCD-SNMP-MIB::ucdavis.66.101.11 = STRING: "0"
UCD-SNMP-MIB::ucdavis.66.101.12 = STRING: "0"
UCD-SNMP-MIB::ucdavis.66.101.13 = STRING: "0"
UCD-SNMP-MIB::ucdavis.66.101.14 = STRING: "0"
UCD-SNMP-MIB::ucdavis.66.101.15 = STRING: "0"
UCD-SNMP-MIB::ucdavis.66.101.16 = STRING: "0"
UCD-SNMP-MIB::ucdavis.66.101.17 = STRING: "47822"
UCD-SNMP-MIB::ucdavis.66.101.18 = STRING: "26"
UCD-SNMP-MIB::ucdavis.66.101.19 = STRING: "2"
UCD-SNMP-MIB::ucdavis.66.101.20 = STRING: "0"
UCD-SNMP-MIB::ucdavis.66.101.21 = STRING: "0"
UCD-SNMP-MIB::ucdavis.66.102.1 = INTEGER: 0

Here the OIDs are:

  • BASE_OID.1.1: The table's index numbers for each of the directives listed below.
  • BASE_OID.2.1: The name of the given table entry. It is recommended that this name be unique, but is not required to be.
  • BASE_OID.3.1: The path of the script itself
  • BASE_OID.100.1: Scripts Exit Value
  • BASE_OID.101.1: Complete STDOUT, Line by Line

Pass

The pass directive allows you to turn over control of an OID range to an external program without writing a proper agent. A script is passed 2 values via STDIN and should return 3 lines via STDOUT.

The STDIN is:

get
.1.3.6.1.4.100

The first line is the command, either "get" or "get-next", the second line is the OID requested.

And thus the STDOUT should be:

.1.3.6.1.4.100
integer
42

Where the first line is the OID being returned, the return type, and finally the value itself.

Using pass allows some fairly complex and powerful solutions to be built.

SNMP Tables

If you walk an agent your likely to come across several tables, you'll commonly see these as "index" values that seemingly have no purpose. These tables can be seen properly using the snmptable command. Example:

benr@ultra ~$ snmptable -v2c -c public ev2-x4150-01.joyent.us .iso.org.dod.internet.mgmt.mib-2.host.hrStorage.hrStorageTable
SNMP table: HOST-RESOURCES-MIB::hrStorageTable

 hrStorageIndex                                hrStorageType                        hrStorageDescr hrStorageAllocationUnits hrStorageSize hrStorageUsed hrStorageAllocationFailures
              2           HOST-RESOURCES-TYPES::hrStorageRam                           Real Memory               4096 Bytes       8388479       1427684                           ?
              3 HOST-RESOURCES-TYPES::hrStorageVirtualMemory                            Swap Space               4096 Bytes      26089841        483688                           ?
              4     HOST-RESOURCES-TYPES::hrStorageFixedDisk                                     /               1024 Bytes       2062186        364635                           ?
              5     HOST-RESOURCES-TYPES::hrStorageFixedDisk                              /devices                512 Bytes             0             0                           ?
              6     HOST-RESOURCES-TYPES::hrStorageFixedDisk                                  /dev                512 Bytes             0             0                           ?
              7     HOST-RESOURCES-TYPES::hrStorageFixedDisk                      /system/contract                512 Bytes             0             0                           ?
              8     HOST-RESOURCES-TYPES::hrStorageFixedDisk                                 /proc                512 Bytes             0             0                           ?
...

The following is a list of tables that may be available on an Net-SNMP agent:

  • HOST-RESOURCES-MIB::
    • hrStorageTable
    • hrDeviceTable
    • hrProcessorTable
    • hrNetworkTable
    • hrPrinterTable
    • hrDiskStorageTable
    • hrPartitionTable
    • hrFSTable
    • hrSWRunTable
    • hrSWRunPerfTable
    • hrSWInstalledTable
  • UDP-MIB::
    • udpTable
  • TCP-MIB::
    • tcpConnTable
  • IF-MIB::
    • ifTable

This is by no means a complete list.

See Also

Attribution

This content was donated by Joyent.