Content-type: text/html
This companion man page illustrates these directives, showing some practical examples of how they might be used.
agentuser nobody agentgroup snmp
agentuser #10 agentgroup #10
createUser me MD5 "single pass phrase" createUser myself MD5 "single pass phrase" DES createUser andI MD5 "single pass phrase" DES "single pass phrase"
Separate pass phrases can be specified for authentication and encryption:
rouser me rwuser onering
rouser myself .1.3.6.1.2 rwuser andI system
Note that a combination repeating the same user, such as:
rouser onering rwuser onering
The directives:
rocommunity public rwcommunity private
A slightly less vulnerable configuration might restrict what information could be retrieved:
# sec.name source community com2sec public default public com2sec mynet 10.10.10.0/24 private com2sec6 mynet fec0::/64 private # sec.model sec.name group worldGroup v1 public group worldGroup v2c public group myGroup v1 mynet group myGroup v2c mynet # incl/excl subtree [mask] view all included .1 view sysView included system # context model level prefix read write notify (unused) access worldGroup "" any noauth exact system none none access myGroup "" any noauth exact all all none
There are several points to note in this example:
The group directives must be repeated for both SNMPv1 and SNMPv2c requests.
The com2sec security name is distinct from the community string that is mapped to it. They can be the same ("public") or different ("mynet"/"private") - but what appears in the group directive is the security name, regardless of the original community string.
Both of the view directives are defining simple OID subtrees, so neither of these require an explicit mask. The same holds for the "combined subtree2 view defined below. In fact, a mask field is only needed when defining row slices across a table (or similar views), and can almost always be omitted.
In general, it is advisible not to mix traditional and VACM-based access configuration settings, as these can sometimes interfere with each other in unexpected ways. Choose a particular style of access configuration, and stick to it.
view sys2View included system view sys2View included .1.3.6.1.2.1.25.1 authcommunity read public default -v sys2View authcommunity read,write private 10.10.10.0/8
This mechanism allows multi-subtree (or other non-simple) views to be used with the one-line rocommunity style of configuration.
It would also support configuring "write-only" access, should this be required.
# Override 'uname -a' and hardcoded system OID - inherently read-only values sysDescr Universal Turing Machine mk I sysObjectID .1.3.6.1.4.1.8072.3.2.1066 # Override default values from 'configure' - makes these objects read-only sysContact Alan.Turing@pre-cs.man.ac.uk sysName tortoise.turing.com sysLocation An idea in the mind of AT # Standard end-host behaviour sysServices 72
ignoredisk /dev/rdsk/c0t[!6]d0 ignoredisk /dev/rdsk/c0t[0-57-9a-f]d0
# At least one web server process must be running at all times proc httpd procfix httpd /etc/rc.d/init.d/httpd restart # There should never be more than 10 mail processes running # (more implies a probable mail storm, so shut down the mail system) proc sendmail 10 procfix sendmail /etc/rc.d/init.d/sendmail stop # There should be a single network management agent running # ("There can be only one") proc snmpd 1 1
includeAllDisks 10% disk /var 20% disk /usr 3% # Keep 100 MB free for crash dumps disk /mnt/crash 100000
authtrapenable 1 trapcommunity public trap2sink localhost
trapsink localhost trap2sink localhost informsink localhost
TODO - discuss SNMPv3 traps
TODO - mention trapd access configuration
# Set up the credentials to retrieve monitored values createUser _internal MD5 "the first sign of madness" iquerySecName _internal rouser _internal # Active the standard monitoring entries defaultMonitors yes linkUpDownNotifications yes # If there's a problem, then tell someone! trap2sink localhost
The first block sets up a suitable user for retrieving the information to by monitored, while the following pair of directives activates various built-in monitoring entries.
Note that the DisMan directives are not themselves sufficient to actively report problems - there also needs to be a suitable destination configured to actually send the resulting notifications to.
A more detailed monitor example is given by:
This defines an explicit boolean monitor entry, looking for any process using more than 10MB of active memory. Such processes will be reported using the (standard) DisMan trap mteTriggerFired, but adding an extra (wildcarded) varbind hrSWRunName.
This entry also specifies an explicit user (me, as defined earlier) for retrieving the monitored values, and building the trap.
Objects that could potentially fluctuate around the specified level are better monitored using a threshold monitor entry:
This will send a mteTriggerRising trap whenever the incoming traffic rises above (roughly) 500 kB/s on any network interface, and a corresponding mteTriggerFalling trap when it falls below 100 kB/s again.
Note that this monitors the deltas between successive samples (-D) rather than the actual sample values themselves. The same effect could be obtained using:
The linkUpDownNotifications directive above is broadly equivalent to:
notificationEvent linkUpTrap linkUp ifIndex ifAdminStatus ifOperStatus notificationEvent linkDownTrap linkDown ifIndex ifAdminStatus ifOperStatus monitor -r 60 -e linkUpTrap "Generate linkUp" ifOperStatus != 2 monitor -r 60 -e linkDownTrap "Generate linkDown" ifOperStatus == 2
This defines the traps to be sent (using notificationEvent), and explicitly references the relevant notification in the corresponding monitor entry (rather than using the default DisMan traps).
The defaultMonitors directive above is equivalent to a series of (boolean) monitor entries:
monitor -o prNames -o prErrMessage "procTable" prErrorFlag != 0 monitor -o memErrorName -o memSwapErrorMsg "memory" memSwapError != 0 monitor -o extNames -o extOutput "extTable" extResult != 0 monitor -o dskPath -o dskErrorMsg "dskTable" dskErrorFlag != 0 monitor -o laNames -o laErrMessage "laTable" laErrorFlag != 0 monitor -o fileName -o fileErrorMsg "fileTable" fileErrorFlag != 0
An alternative approach would be to automatically invoke the corresponding "fix" action:
setEvent prFixIt prErrFix = 1 monitor -e prFixIt "procTable" prErrorFlag != 0
Alternatively this could be configured to be run at specific times of day (perhaps following rotation of the logs):
The one-shot style of scheduling is rather less common, but the secret SNMP virus could be activated on the next occurance of Friday 13th using:
exec [MIBOID] NAME PROG ARGS" sh [MIBOID] NAME PROG ARGS" execfix NAME PROG ARGS"
extend [MIBOID] NAME PROG ARGS" extendfix [MIBOID] NAME PROG ARGS"
disablePerl false perlInitFile /usr/local/share/snmp/snmp_perl.pl
perl use Data::Dumper; perl sub myroutine { print "got called: ",Dumper(@_),"\n"; } perl $agent->register('mylink', '.1.3.6.1.8765', \&myroutine);
This relies on the $agent object, defined in the example snmp_perl.pl file.
A more realistic MIB handler might be:
XXX - WHAT ???
com2sec -Cn rem1context rem1user default remotehost1 com2sec -Cn rem2context rem2user default remotehost2 proxy -Cn rem1context -v 1 -c public remotehost1 .1.3 proxy -Cn rem2context -v 1 -c public remotehost2 .1.3
The same proxy directives would also work with (incoming) SNMPv3 requests, which can specify a context directly. It would probably be more sensible to use contexts of remotehost1 and remotehost2 - the names above were chosen to indicate how these directives work together.
Note that the administrative settings for the proxied request are specified explicitly, and are independent of the settings from the incoming request.
An alternative use for the proxy directive is to pass part of the OID tree to another agent (either on a remote host or listening on a different port on the same system), while handling the rest internally:
A less usual approach is to map one subtree into a different area of the overall MIB tree (either locally or on a remote system):
# uses SNMPv3 to access the MIB tree .1.3.6.1.2.1.1 on 'remotehost' # and maps this to the local tree .1.3.6.1.3.10 proxy -v 3 -l noAuthNoPriv -u user remotehost .1.3.6.1.3.10 .1.3.6.1.2.1.1
smuxsocket 127.0.0.1 smuxpeer .1.3.6.1.2.1.14 ospf_pass
master agentx agentXSocket /tmp/agentx/master agentXPerms 0660 0550 nobody snmp
netsnmp_ds_set_string(NETSNMP_DS_APPLICATION_ID, NETSNMP_DS_AGENT_X_SOCKET, "/tmp/agentx/master");
A loopback networked AgentX configuration could be set up using:
agentXSocket tcp:localhost:705 agentXTimeout 5 agentXRetries 2
agentXSocket tcp:localhost:705 agentXTimeout 10 agentXRetries 1 agentXPingInterval 600
Note that the timeout and retry settings can be asymmetric for the two directions, and the sub-agent can poll the master agent at regular intervals (600s = every 10 minutes), to ensure the connection is still working.