Snmpd: Difference between revisions
Line 350: | Line 350: | ||
</source> | </source> | ||
* | <source> | ||
service snmpd restart | |||
* Restarting network management services: | |||
</source> | |||
<source> | <source> |
Latest revision as of 01:32, 25 April 2013
Ubuntu/Debian[edit]
<source> sudo apt-get install snmpd snmp libsnmp15 libsnmp-perl libsnmp-info-perl libsnmp-base libnet-snmp-perl snmp-mibs-downloader libparse-debian-packages-perl </source>
- /etc/snmp/snmpd.conf
<source>
agentAddress udp:161 rocommunity <secret> rouser authOnlyUser sysLocation ChangeME - Sitting on the Dock of the Bay sysContact You <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 ## this will allow you list the sw installed. Script required below perl do "/etc/snmp/hrswinstalled.pl"; master agentx
</source>
- list software installed script required
- /etc/snmp/hrswinstalled.pl
<source lang=perl>
- !/usr/bin/perl
- This is a rather quick (?) and dirty (!) script to implement the hrSWInstalled
- MIB on Debian and other dpkg based Linux distributions.
- If you have improvements, please send to rmk@bistromath.org
- Configuration
- maximum allowed cache age (in seconds)
- the agent will check the mtime on $statusfile if it hasn't checked in this long
$maxCacheAge = 10;
- location of dpkg files
my $statusfile = "/var/lib/dpkg/status"; my $infodir = "/var/lib/dpkg/info";
- 0 - quiet, 1 - basic debugging, 2 - trace debugging
$debug = 0;
my $regat = '1.3.6.1.2.1.25.6'; my $hrSWInstalledLastChange = $regat . ".1"; my $hrSWInstalledLastUpdateTime = $regat . ".2"; my $hrSWInstalledEntry = $regat . ".3.1"; my $hrSWInstalledIndex = $hrSWInstalledEntry . ".1"; my $hrSWInstalledName = $hrSWInstalledEntry . ".2"; my $hrSWInstalledID = $hrSWInstalledEntry . ".3"; my $hrSWInstalledType = $hrSWInstalledEntry . ".4"; my $hrSWInstalledDate = $hrSWInstalledEntry . ".5";
use Net::SNMP qw(oid_lex_sort); use YAML; use IO::File; use Parse::Debian::Packages; use Data::Dumper; use NetSNMP::OID (':all'); use NetSNMP::agent (':all'); use NetSNMP::ASN (':all'); use SNMP;
my $inittime = time(); my $lastCacheCheck; my $cacheAge = 0; my %oidtable; my @oidkeys; my %nextOIDMap;
BEGIN {
print STDERR "loading Debian hrSWInstalled MIB extension \n";
}
populateCaches();
- if we're not embedded, this will get auto-set below to 1
$subagent = 0;
- where we are going to hook onto
my $regoid = new NetSNMP::OID($regat); print STDERR "registering at ", $regoid, "\n" if ($debug);
- If we're not running embedded within the agent, then try to start
- our own subagent instead.
if ( !$agent ) {
$agent = new NetSNMP::agent( 'Name' => 'hrswinstalled', 'AgentX' => 1 ); # make us a subagent $subagent = 1; print STDERR "started us as a subagent ($agent)\n";
}
- we register ourselves with the master agent we're embedded in. The
- global $agent variable is how we do this:
$agent->register( 'myname', $regoid, \&hrSWInstalledHandler );
if ($subagent) {
# We need to perform a loop here waiting for snmp requests. We # aren't doing anything else here, but we could. $SIG{'INT'} = \&shutDown; $SIG{'QUIT'} = \&shutDown; $running = 1; while ($running) { $agent->agent_check_and_process(1); # 1 = block print STDERR "main loop\n" if ( $debug > 2 ); } $agent->shutdown();
}
- the actual SNMP handler
sub hrSWInstalledHandler {
my ( $handler, $registration_info, $request_info, $requests ) = @_; my $request;
#check package cache time populateCaches() if statusCacheUpdated($statusfile);
print STDERR "processing a request of type " . $request_info->getMode() . "\n" if $debug > 1;
for ( $request = $requests ; $request ; $request = $request->next() ) { my $oid = $request->getOID(); print STDERR " processing request of $oid\n" if $debug > 1;
if ( $request_info->getMode() == MODE_GET ) { my $numericOid = SNMP::translateObj($oid); $numericOid =~ s/^\.//; $request->setOID($numericOid); $request->setValue( $oidtable{$numericOid}{type}, $oidtable{$numericOid}{val} ); } elsif ( $request_info->getMode() == MODE_GETNEXT ) { print STDERR "requested oid $oid\n" if $debug > 1; for my $oidentry ( $nextOIDMap{$oid} ? ( $nextOIDMap{$oid}, @oidkeys ) : @oidkeys ) { if ( $oid < $oidtable{$oidentry}{oid} ) { print STDERR "returned $oidentry" if $debug > 1; $request->setOID($oidentry); $request->setValue( $oidtable{$oidentry}{type}, $oidtable{$oidentry}{val} ); last; } }
} }
print STDERR " finished processing\n" if $debug > 1;
}
- optimised oid map
sub nextOIDMap {
my ( $oidtable, $oidkeys ) = @_;
my %nextmap; my %oididx; my $idx = 0;
print STDERR "Generating OID cache...\n" if $debug;
#generate hash mapping OIDs in @{$oidkeys} array to the index of that key #within the array, for performance reasons for my $oidkey ( @{$oidkeys} ) { $oididx{$oidkey} = $idx; }
for my $oid ( keys %{$oidtable} ) { my $index = $oididx{$oid}; $nextmap{ $oidtable{$oid}{oid} } = $oidkeys->[ $index + 1 ]; } print STDERR "\t...done.\n" if $debug;
return %nextmap;
}
- check if package status has changed
sub statusCacheUpdated {
my ($statusfile) = @_;
#allow for max cache age return 0 if time() <= $lastCacheCheck + $maxCacheAge; $lastCacheCheck = time(); print STDERR "dpkg cache expired\n" if $debug && ( stat($statusfile) )[9] > $cacheAge; return ( stat($statusfile) )[9] > $cacheAge ? 1 : 0;
}
- enumerate package status
sub enumPkgs {
my ( $statusfile, $infodir ) = @_; my $index = 1; my %packages; my %oidtable;
print STDERR "Enumerating installed packages...\n" if $debug;
#remember our cache age $cacheAge = time();
my $fh = IO::File->new($statusfile);
my $parser = Parse::Debian::Packages->new($fh); while ( my %package = $parser->next ) { next unless $package{Status} =~ /(?<!not-)installed/; $packages{ $package{Package} } = \%package; }
close $fh;
for my $name ( sort keys %packages ) {
my $oid;
#hrSWInstalledIndex $oid = $hrSWInstalledIndex . "." . $index; $oidtable{$oid}{oid} = new NetSNMP::OID( $hrSWInstalledIndex . "." . "$index" ); $oidtable{$oid}{type} = ASN_INTEGER;
$oidtable{$oid}{val} = $index;
#hrSWInstalledName $oid = $hrSWInstalledName . "." . $index; $oidtable{$oid}{oid} = new NetSNMP::OID( $hrSWInstalledName . "." . "$index" ); $oidtable{$oid}{type} = ASN_OCTET_STR;
$oidtable{$oid}{val} = "$name $packages{$name}{Version}/$packages{$name}{Architecture} (" . ( $packages{$name}{Description} || "No description" ) . ")";
#hrSWInstalledDate $oid = $hrSWInstalledDate . "." . $index; $oidtable{$oid}{oid} = new NetSNMP::OID( $hrSWInstalledDate . "." . "$index" ); $oidtable{$oid}{type} = ASN_OCTET_STR;
my $mtime = ( stat( "$infodir" . "/" . $name . ".list" ) )[9]; $oidtable{$oid}{val} = snmpDateStamp($mtime);
#hrSWInstalledID $oid = $hrSWInstalledID . "." . $index; $oidtable{$oid}{oid} = new NetSNMP::OID( $hrSWInstalledID . "." . "$index" ); $oidtable{$oid}{type} = ASN_OBJECT_ID;
$oidtable{$oid}{val} = "0.0";
#hrSWInstalledType $oid = $hrSWInstalledType . "." . $index; $oidtable{$oid}{oid} = new NetSNMP::OID( $hrSWInstalledType . "." . "$index" ); $oidtable{$oid}{type} = ASN_INTEGER;
if ( $packages{$name}{Priority} eq "required" || $packages{$name}{Section} eq "base" ) {
#OS package $oidtable{$oid}{val} = 2; } else {
#application $oidtable{$oid}{val} = 4; }
#increment index $index++; }
#hrSWInstalledLastChange $oid = $hrSWInstalledLastChange . "." . $index; $oidtable{$oid}{oid} = new NetSNMP::OID( $hrSWInstalledLastChange . "." . "$index" ); $oidtable{$oid}{type} = ASN_TIMETICKS;
my $mtime = ( stat($statusfile) )[9]; $oidtable{$oid}{val} = ( time() - $inittime ) * 100;
#hrSWInstalledLastUpdateTime $oid = $hrSWInstalledLastUpdateTime . "." . $index; $oidtable{$oid}{oid} = new NetSNMP::OID( $hrSWInstalledLastUpdateTime . "." . "$index" ); $oidtable{$oid}{type} = ASN_TIMETICKS;
$oidtable{$oid}{val} = ( time() - $inittime ) * 100;
print "\tdone. (" . scalar( keys %packages ) . " packages)\n" if $debug; return %oidtable;
}
- convert unix timestamp to snmp TimeAndDate
sub snmpDateStamp {
my ($ts) = @_;
my ( $sec, $min, $hour, $mday, $mon, $year, $wday, $yday, $isdst ) = gmtime($ts); return pack 'n C6 a C2', $year + 1900, $mon + 1, $mday, $hour, $min, $sec, 0, '-', 0, 0;
}
sub populateCaches {
%oidtable = enumPkgs( $statusfile, $infodir ); @oidkeys = oid_lex_sort( keys %oidtable ); %nextOIDMap = nextOIDMap( \%oidtable, \@oidkeys );
}
sub shutDown {
$running = 0; print STDERR "shutting down\n" if ($debug);
} </source> <source> chmod +x /etc/snmp/hrswinstalled.pl </source>
- verify it can run
<source> root@servrr:/etc/snmp# /etc/snmp/hrswinstalled.pl
loading Debian hrSWInstalled MIB extension started us as a subagent (NetSNMP::agent=HASH(0x42575f0)) ## looks good - type ctrl-c to quit
</source>
<source> service snmpd restart
* Restarting network management services:
</source>
<source> snmpwalk -v2c -c <secret> localhost iso.3.6.1.2.1.1.1.0 = STRING: "Linux onion 3.2.0-40-generic #64-Ubuntu SMP Mon Mar 25 21:22:10 UTC 2013 x86_64" iso.3.6.1.2.1.1.2.0 = OID: iso.3.6.1.4.1.8072.3.2.10 iso.3.6.1.2.1.1.3.0 = Timeticks: (3536) 0:00:35.36 iso.3.6.1.2.1.1.4.0 = STRING: "Me <me@example.org>" iso.3.6.1.2.1.1.5.0 = STRING: "server" iso.3.6.1.2.1.1.6.0 = STRING: "Sitting on the Dock of the Bay" iso.3.6.1.2.1.1.7.0 = INTEGER: 72 ..... </source>