diff --git a/images/snmp__fn-cpu.png b/images/snmp__fn-cpu.png new file mode 100755 index 00000000..a2f50b0d Binary files /dev/null and b/images/snmp__fn-cpu.png differ diff --git a/images/snmp__fn-memory.png b/images/snmp__fn-memory.png new file mode 100755 index 00000000..19846583 Binary files /dev/null and b/images/snmp__fn-memory.png differ diff --git a/images/snmp__fn-sessions.png b/images/snmp__fn-sessions.png new file mode 100755 index 00000000..e6a6153e Binary files /dev/null and b/images/snmp__fn-sessions.png differ diff --git a/images/snmp__fn-vpnsessions.png b/images/snmp__fn-vpnsessions.png new file mode 100755 index 00000000..a087874c Binary files /dev/null and b/images/snmp__fn-vpnsessions.png differ diff --git a/plugins/other/lvm_snap_used b/plugins/other/lvm_snap_used index cfcdc241..87574a24 100755 --- a/plugins/other/lvm_snap_used +++ b/plugins/other/lvm_snap_used @@ -14,17 +14,19 @@ #%# capabilities=autoconf # # 2011/05/20 - pmoranga - initial version +# +# 2012/01/27 - Sébastien Gross +# - Fix lvdisplay path + +lvdisplay=$(which lvdisplay) if [ "$1" = "autoconf" ]; then - /usr/sbin/lvdisplay 2>/dev/null >/dev/null - if [ $? -eq 0 ] - then - echo yes - exit 0 - else - echo "no lvdisplay found" - fi - exit 1 + if test -n "${lvdisplay}"; then + echo yes + exit 0 + fi + echo "no lvdisplay found" + exit 1 fi @@ -34,9 +36,9 @@ if [ "$1" = "config" ]; then echo 'graph_vlabel %' echo 'graph_category disk' echo 'graph_args --base 100' - /usr/sbin/lvdisplay -C | awk '$3 ~ /^s/{print $1".label "$1" snapshot of "$5} ' + ${lvdisplay} -C | awk '$3 ~ /^s/{print $1".label "$1" snapshot of "$5} ' exit 0 fi -/usr/sbin/lvdisplay -C | awk '$3 ~ /^s/{print $1".value",int($6)} ' +${lvdisplay} -C | awk '$3 ~ /^s/{print $1".value",int($6)} ' diff --git a/plugins/other/snmp__fn b/plugins/other/snmp__fn new file mode 100755 index 00000000..b481995a --- /dev/null +++ b/plugins/other/snmp__fn @@ -0,0 +1,173 @@ +#!/bin/bash +# +# File: snmp__fn +# Description: SNMP plugin to monitor open sessions, sslvpn, CPU and Memory on a +# Fortigate firewall. +# +# Author: Thom Diener +# License: This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License +# as published by the Free Software Foundation; version 2 dated +# June, 1991. +# +# Version: v1.00 30.10.2011 First draft of the fortigate plugin +# v1.01 19.01.2012 OID to MIB changed, plugins gets faster +# v1.02 25.01.2012 MIB file availability check added +# +# Parameters: config (required) +# autoconf (optional) +# +# Usage: place in /etc/munin/plugins/ (or link it there using ln -s) +# (Example: ln -s /usr/share/munin/plugins/snmp__fn \ +# /etc/munin/plugins/snmp_foo.example.com_fn) +# +# Global community string /etc/munin/plugin-conf.d/munin-node +# [snmp_*] +# env.community private +# timeout 45 # In case low latency or timeout +# +# Fortigate Activate snmp on your Fortigate firewall. Fortigate documentation +# at https://support.fortinet.com +# +# MIB Download and copy the original Fortigate MIB defintion file to +# /usr/share/snmp/mibs/FORTINET-300-MIB.txt (Filename depends on +# used Version) +# +# Tested with Fortinet Fortigate-50B, Firmware 3.00(MR6) on Ubuntu 10.04 LTS +# with Munin 1.4.4 installed. +# +#%# family=manual +# + + +#set -x + +### Constants ------------------------------------------------------------------ +SNMPCLIENT=`basename $0 | sed 's/^snmp_//g' | cut -d "_" -f1` +MIBFILE="/usr/share/snmp/mibs/FORTINET-300-MIB.20080414.txt" +FNTYPE=`echo $MIBFILE | cut -d "." -f1 | cut -d "/" -f6` +if [ -r $MIBFILE ]; then + SNMPGET="/usr/bin/snmpget -m $MIBFILE -c $community -v 2c $SNMPCLIENT" +else + echo no, MIB definition file not available or readable. + exit 1 +fi + +### Variables ------------------------------------------------------------------ +fnSysVersion="1.3.6.1.4.1.12356.1.3.0" +FGTcpu="$FNTYPE::fnSysCpuUsage.0" +fnSysVersion="$FNTYPE::fnSysVersion.0" +fnSysMemUsage="$FNTYPE::fnSysMemUsage.0" +fnSysSesCount="$FNTYPE::fnSysSesCount.0" +fnVPNSslStatsLoginUsers="$FNTYPE::fnVpnSslStatsLoginUsers.1" +fnVPNSslStatsActiveWebSessions="$FNTYPE::fnVpnSslStatsActiveWebSessions.1" +fnVPNSslStatsActiveTunnels="$FNTYPE::fnVpnSslStatsActiveTunnels.1" + +UNIT=`$SNMPGET $fnSysVersion | cut -d ":" -f4 | cut -d " " -f2 | cut -d "\"" -f2` +SCPU=`$SNMPGET $FGTcpu | cut -d ":" -f4 | cut -d " " -f2` +SMEM=`$SNMPGET $fnSysMemUsage | cut -d ":" -f4 | cut -d " " -f2` +SCNT=`$SNMPGET $fnSysSesCount | cut -d ":" -f4 | cut -d " " -f2` +USER=`$SNMPGET $fnVPNSslStatsLoginUsers | cut -d ":" -f4 | cut -d " " -f2` +WEBS=`$SNMPGET $fnVPNSslStatsActiveWebSessions | cut -d ":" -f4 | cut -d " " -f2` +ATUN=`$SNMPGET $fnVPNSslStatsActiveTunnels | cut -d ":" -f4 | cut -d " " -f2` + + +### Functions ------------------------------------------------------------------ + +autoconf() +{ + if [ $SCPU ]; then + echo yes, OID $FGTcpu can be readed. + else + echo no, one or multiple OID can not be readed. + exit 1 + fi + + if [ $SMEM ]; then + echo yes, OID $fnSysMemUsage can be readed. + else + echo no, one or multiple OID can not be readed. + exit 1 + fi + if [ $SCNT ]; then + echo yes, OID $fnSysSesCount can be readed. + else + echo no, one or multiple OID can not be read. + exit 1 + fi +exit 0 +} + +config() +{ + echo "multigraph fn_cpu" + echo "host_name $SNMPCLIENT" + echo "graph_title $UNIT - CPU usage" + echo 'graph_category system' + echo 'graph_vlabel %' + echo 'graph_info This graph shows current CPU usage.' + echo 'graph_args --base 1000 -r --lower-limit 0 --upper-limit 100' + echo 'forticpu.label CPU' + echo 'forticpu.info CPU usage' + echo 'forticpu.draw AREA' + echo '' + echo "multigraph fn_memory" + echo "host_name $SNMPCLIENT" + echo "graph_title $UNIT - Memory usage" + echo 'graph_category system' + echo 'graph_vlabel %' + echo 'graph_info This graph shows current memory usage.' + echo 'graph_args --base 1000 -r --lower-limit 0 --upper-limit 100' + echo 'fortimemory.label Memory' + echo 'fortimemory.info Memory usage' + echo 'fortimemory.draw AREA' + echo '' + echo "multigraph fn_sessions" + echo "host_name $SNMPCLIENT" + echo "graph_title $UNIT - Sessions" + echo 'graph_category Other' + echo 'graph_vlabel Active Sessions' + echo 'graph_info Active session count on the Fortigate firewall' + echo 'fortisessions.label Sessions' + echo 'fortisessions.info Active session count' + echo 'fortisessions.draw AREA' + echo '' + echo "multigraph fn_vpnsessions" + echo "host_name $SNMPCLIENT" + echo "graph_title $UNIT - SSLvpn Sessions" + echo 'graph_category Other' + echo 'graph_vlabel Sessions/Users' + echo 'graph_info Loged in users with SSLvpn (WebSession or Tunnel-Mode)' + echo 'fortiuser.label Users' + echo 'fortiuser.info Loged in SSLvpn users' + echo 'fortiwebs.label WebSessions' + echo 'fortiwebs.info Active SSLvpn WebSessions' + echo 'fortiatun.label ActiveTunnels' + echo 'fortiatun.info Active SSLvpn Tunnels' + exit 0 +} + +values() +{ +echo "multigraph fn_cpu" +echo "forticpu.value $SCPU" +echo "" +echo "multigraph fn_memory" +echo "fortimemory.value $SMEM" +echo "" +echo "multigraph fn_sessions" +echo "fortisessions.value $SCNT" +echo "" +echo "multigraph fn_vpnsessions" +echo "fortiuser.value $USER" +echo "fortiwebs.value $WEBS" +echo "fortiatun.value $ATUN" +} + +### Main ----------------------------------------------------------------------- + +if [ "$1" = "autoconf" ]; then autoconf +fi +if [ "$1" = "config" ]; then config +fi +values diff --git a/plugins/other/tomcat_ b/plugins/other/tomcat_ new file mode 100644 index 00000000..b4a256a4 --- /dev/null +++ b/plugins/other/tomcat_ @@ -0,0 +1,162 @@ +#!/usr/bin/python + +''' +Wildcard plugin to monitor Apache Tomcat connectors and/or JBoss' JVM. + +To use this plugin: +1. Set site, username and password variables before you do anything else. +2. Run plugin with suggest argument to get all the available options. +3. Copy plugin to munin plugins folder and make it executable. +4. Create symbolic links based on output from step 2. Examples: + tomcat_jvm - monitor JVM usage + tomcat_ajp-127.0.0.1-8009 - monitor ajp connector + tomcat_http-127.0.0.1-8080 - monitor http connector +5. Check links by running them. +6. Restart munin-node. +7. Enjoy graphs. + +Munin's muni-node-configure can be used to do steps 2, 3 and 4 for you. + +Example of using munin-node configuration to configure the plugin: + +[tomcat_jvm] + env.site http://127.0.0.1:8080/status?XML=true + env.username admin + env.password admin + +Magic markers +#%# capabilities=autoconf suggest +#%# family=auto +''' + +import urllib2 +import base64 +import xml.dom.minidom +import sys, os, re + +# Configure me ... +site = 'http://127.0.0.1:8080/status?XML=true' +username = 'admin' +password = 'admin' + +# Or do it with the environment variables in munin-node configuration. +if os.environ.has_key('site'): + site = os.environ['site'] + +if os.environ.has_key('username'): + username = os.environ['username'] + +if os.environ.has_key('password'): + password = os.environ['password'] + +# Timeout for urlopen. +required_version = (2, 6) +current_version = sys.version_info[:2] + +connector_attrs = ( + 'maxThreads', + 'minSpareThreads', + 'maxSpareThreads', + 'currentThreadCount', + 'currentThreadBusy' +) + +jvm_attrs = ( + 'free', + 'total', + 'max' +) + +ctx = sys.argv[0].rstrip('.py').split('_')[1] + +def site_auth(): + # Prepare base64 encoded string + enc_string = base64.encodestring('%s:%s' % (username, password)) + + # Prepare request and add headers + request = urllib2.Request(url=site, headers={"Authorization": "Basic %s" % enc_string}) + try: + if current_version >= required_version: + return (0, urllib2.urlopen(request, timeout=5).read()) + else: + return (0, urllib2.urlopen(request).read()) + except: + return (-1, "Failed to access %s" % site) + +def jvm_data(data): + document = data.documentElement + for sub_document in document.childNodes: + if sub_document.nodeName == 'jvm': + node = sub_document.firstChild + for attr in jvm_attrs: + print "%s.value %s" % (attr, int(node.getAttribute(attr))) + +def connector_data(data, connector_name): + document = data.documentElement + for sub_document in document.childNodes: + if sub_document.nodeName == 'connector' and sub_document.getAttribute('name') == connector_name: + node = sub_document.firstChild + for attr in connector_attrs: + try: + print "%s.value %s" % (attr, int(node.getAttribute(attr))) + except: + pass + +def suggest(data): + document = data.documentElement + for sub_document in document.childNodes: + if sub_document.nodeName == 'jvm': + print "jvm" + elif sub_document.nodeName == 'connector': + print sub_document.getAttribute('name') + else: + pass + +def configure(): + print "graph_title Tomcat status - %s" % ctx + print "graph_category tomcat" + if ctx == 'jvm': + print "graph_args --base 1024 -l 0" + print "graph_scale yes" + print "graph_vlabel JVM in bytes" + print "graph_info This graph shows JVM usage of Tomcat." + for attr in jvm_attrs: + print "%s.label %s" % (attr, attr) + print "%s.type GAUGE" % (attr) + print "%s.min 0" % (attr) + print "%s.draw LINE1" % (attr) + print "%s.info %s %s in bytes" % (attr, ctx, attr) + else: + print "graph_args --base 1000 -l 0" + print "graph_scale no" + print "graph_vlabel Connector threads" + print "graph_info This graph shows connector threads for %s" % ctx + for attr in connector_attrs: + print "%s.label %s" % (attr, attr) + print "%s.type GAUGE" % (attr) + print "%s.min 0" % (attr) + print "%s.draw LINE1" % (attr) + print "%s.info %s %s count" % (attr, ctx, attr) + +if __name__ == "__main__": + status, data = site_auth() + if len(sys.argv) == 2 and sys.argv[1] == 'config': + configure() + sys.exit(0) + + elif len(sys.argv) == 2 and sys.argv[1] == 'suggest': + suggest(xml.dom.minidom.parseString(data)) + sys.exit(0) + + elif len(sys.argv) == 2 and sys.argv[1] == 'autoconf': + if status == 0: + print "yes" + else: + print "no (%s)" % data + sys.exit(0) + + else: + if ctx == 'jvm': + jvm_data(xml.dom.minidom.parseString(data)) + else: + connector_data(xml.dom.minidom.parseString(data), ctx) diff --git a/plugins/other/tor-bandwidth-usage b/plugins/other/tor-bandwidth-usage index 26a5f070..316d57ca 100755 --- a/plugins/other/tor-bandwidth-usage +++ b/plugins/other/tor-bandwidth-usage @@ -1,6 +1,6 @@ #!/usr/bin/perl -w # -# tor_bandwidth_acct - munin plugin to monitor Tor routers traffic +# tor-bandwidth-usage - munin plugin to monitor Tor traffic # # To use this plugin you need the following: # o Enable accounting on torrc configuration file (even if you dont want to limit bandwidth usage, @@ -9,145 +9,144 @@ # AccountingStart day 12:00 # AccountingMax 100 GB # o Enable CookieAuthentication (CookieAuthentication 1 in torrc) or define a HashedControlPassword +# o Add something like the following to /etc/munin/plugin-conf.d/munin-node: +# [tor-bandwidth-usage] +# user debian-tor +# env.cookiefile /var/run/tor/control.authcookie # -# tested with Tor releases: 0.2.1.28, 0.2.1.29 # -# Author: tazoi , based on a plugin by Ævar Arnfjörð Bjarmason , based on a plugin by Ævar Arnfjörð Bjarmason # # Parameters understood (defined in file /etc/munin/plugin-conf.d/munin-node or in environment) -# host - Change which host to graph (default localhost) -# port - Change which port to connect to (default 9051) +# host - Change which host to graph (default localhost) +# port - Change which port to connect to (default 9051) # password - Plain-text control channel password (see torrc -# HashedControlPassword parameter) +# HashedControlPassword parameter) # cookiefile - Name of the file containing the control channel cookie -# (see torrc CookieAuthentication parameter) +# (see torrc CookieAuthentication parameter) # -# Using HashedControlPassword authentication has the problem that you must -# include the plain-text password in the munin config file. To have any -# effect, that file shouldn't be world-readable. -# If you're using CookieAuthentication, you should run this plugin as a user -# which has read access to the tor datafiles. Also note that bugs in versions -# upto and including 0.1.1.20 prevent CookieAuthentication from working. +# Using HashedControlPassword authentication has the problem that you +# must include the plain-text password in the munin config file. To +# have any effect, that file shouldn't be world-readable. # -# Usage: place in /etc/munin/node.d/ or in /etc/munin/plugins (or link it there using ln -s) +# If you're using CookieAuthentication, you should run this plugin as +# a user which has read access to the tor datafiles. Also note that +# bugs in versions upto and including 0.1.1.20 prevent +# CookieAuthentication from working. # -# Parameters understood: -# config (required) -# autoconf (optional - used by munin-config) -# -# todo: -# try using "graph_period" option "to make graph_sums usable" -# -# Magic markers - optional - used by installation scripts and -# munin-config: +# Usage: place in /etc/munin/plugins (or link it there using ln -s) # #%# family=contrib #%# capabilities=autoconf use strict; +use feature ':5.10'; use IO::Socket::INET; +use Munin::Plugin; # Config -our $address = $ENV{host} || "localhost"; # Default: localhost -our $port = $ENV{port} || 9051; # Default: 9051 +my $address = $ENV{host} || "localhost"; +my $port = $ENV{port} || 9051; # Don't edit below this line sub Authenticate { - my ($socket) = @_; - my $authline = "AUTHENTICATE"; - if (defined($ENV{cookiefile})) { - if (open(COOKIE, "<$ENV{cookiefile}")) { - binmode COOKIE; - my $cookie; - $authline .= " "; - while (read(COOKIE, $cookie, 32)) { - foreach my $byte (unpack "C*", $cookie) { - $authline .= sprintf "%02x", $byte; - } - } - close COOKIE; - } - } elsif (defined($ENV{password})) { - $authline .= ' "' . $ENV{password} . '"'; - } - print $socket "$authline\r\n"; - my $replyline = <$socket>; - if (substr($replyline, 0, 1) != '2') { - $replyline =~ s/\s*$//; - return "Failed to authenticate: $replyline"; - } + my ($socket) = @_; + my $authline = "AUTHENTICATE"; + if (defined($ENV{cookiefile})) { + if (open(COOKIE, "<$ENV{cookiefile}")) { + my $cookie; + binmode COOKIE; + read(COOKIE, $cookie, 32); + close COOKIE; + $authline .= ' "' . $cookie . '"'; + } + } elsif (defined($ENV{password})) { + $authline .= ' "' . $ENV{password} . '"'; + } + say $socket "$authline"; + my $replyline = <$socket>; + if (substr($replyline, 0, 1) != '2') { + $replyline =~ s/\s*$//; + return "Failed to authenticate: $replyline"; + } - return; + return; } if ($ARGV[0] and $ARGV[0] eq "autoconf") { - # Try to connect to the daemon - my $socket = IO::Socket::INET->new("$address:$port") - or my $failed = 1; + # Try to connect to the daemon + my $socket = IO::Socket::INET->new("$address:$port") or my $failed = 1; - if ($failed) { - print "no (failed to connect to $address port $port)\n"; - exit 1; - } + if ($failed) { + say "no (failed to connect to $address port $port)"; + exit 1; + } - my $msg = Authenticate($socket); - if (defined($msg)) { - print $socket "QUIT\r\n"; - close($socket); - print "no ($msg)\n"; - exit 1; - } + my $msg = Authenticate($socket); + if (defined($msg)) { + say $socket "QUIT"; + close($socket); + say "no ($msg)"; + exit 1; + } - print $socket "QUIT\r\n"; - close($socket); - print "yes\n"; - exit 0; + say $socket "QUIT"; + close($socket); + say "yes"; + exit 0; } if ($ARGV[0] and $ARGV[0] eq "config") { - print "graph_title Tor bandwidth usage (in/out)\n"; - print "graph_args --base 1000\n"; - print "graph_vlabel bytes/sec\n"; - print "graph_category Tor\n"; - print "graph_info This graph shows the flowing incoming/outgoing bytes on a Tor node\n"; - print "down.label Download\n"; - print "down.type DERIVE\n"; - print "down.min 0\n"; - print "up.label Upload\n"; - print "up.type DERIVE\n"; - print "up.min 0\n"; + say "graph_order down up"; + say "graph_title Tor traffic"; + say "graph_args --base 1000"; + say "graph_vlabel bits in (-) / out (+) per \${graph_period}"; + say "graph_category network"; + say "graph_info This graph shows the traffic through this Tor node."; + say "down.label received"; + say "down.type DERIVE"; + say 'down.graph no'; + say "down.cdef down,8,*"; + say "down.min 0"; + say "up.label b/s"; + say "up.type DERIVE"; + say "up.negative down"; + say "up.cdef up,8,*"; + say "up.min 0"; - exit 0; + exit 0; } my $socket = IO::Socket::INET->new("$address:$port") - or die("Couldn't connect to $address port $port: $!"); + or die("Couldn't connect to $address port $port: $!"); my $msg = Authenticate($socket); if (defined($msg)) { - print $socket "QUIT\r\n"; - close($socket); - die "$msg\n"; + say $socket "QUIT"; + close($socket); + die "$msg\n"; } -print $socket "GETINFO accounting/bytes\r\n"; +say $socket "GETINFO accounting/bytes"; my $down = 0; my $up = 0; my $replyline = <$socket>; chomp($replyline); -if ( $replyline =~ /^250-accounting\/bytes=(\d+)\s(\d+)\r$/ ) { - $down = $1; - $up = $2; +if ($replyline =~ /^250-accounting\/bytes=(\d+)\s(\d+)/) { + $down = $1; + $up = $2; } else { - die "Failed to get accounting info: $replyline\n"; + die "Failed to get accounting info: $replyline\n"; } -print $socket "QUIT\r\n"; +say $socket "QUIT"; close($socket); -print "down.value $down\n"; -print "up.value $up\n"; +say "down.value $down"; +say "up.value $up"; exit 0;