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.
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
- The Cuddletech Guide to SNMP Programming
- Cuddletech SNMP Reference
- IPMI
- Cisco SNMP Page
- Sun Blog Walking the system (hardware) SNMP maze
Attribution
This content was donated by Joyent.
