pax_global_header00006660000000000000000000000064116053237460014521gustar00rootroot0000000000000052 comment=3ed094e30660cbeda828b545674137787eeee3c4 mon-contrib-1.0+dfsg/000077500000000000000000000000001160532374600145275ustar00rootroot00000000000000mon-contrib-1.0+dfsg/HOWTO/000077500000000000000000000000001160532374600154275ustar00rootroot00000000000000mon-contrib-1.0+dfsg/HOWTO/mon-PAM-mini-HOWTO000066400000000000000000000307741160532374600204210ustar00rootroot00000000000000Setting Up PAM Authentication With mon mini-HOWTO Andrew Ryan, andrewr@nam-shub.com $Id: mon-PAM-mini-HOWTO,v 1.1.1.1 2005/02/18 17:52:13 trockij Exp $ This document describes how to use PAM authentication with the network monitoring software mon, gives some specific configuration examples, and points out some gotchas with PAM authentication in mon. ------------------------------------------------------------ Contents 1.0 Introduction 2.0 Caveats and Risks 3.0 Setting Up PAM Support For mon in Your OS 3.1 Setting Up PAM Support For Solaris Using Solaris PAM 3.2 Setting Up PAM Support Using Linux-PAM (for Linux, FreeBSD, Solaris, SunOS and HP-UX 9.0 too!) 3.3 Notes on Shadow Password Support with mon and PAM 4.0 Setting up PAM Authentication in mon 5.0 Examples 5.1 Setting Up LDAP+SSL PAM Authentication in mon 5.2 Stacking PAM Modules 5.3 Other Cool-Looking PAM Services (which haven't been tested with mon) ------------------------------------------------------------ 1.0 Introduction PAM (Pluggable Authentication Module) is an architecture for providing one or more of the following four services: authentication, account management, session management, and password management. PAM allows applications to share these functions, and for these functions to be maintained separately from the applications themselves. Thus, not every application developer has to write routines to perform authentication within their applications. You can use PAM as an authentication mechanism for mon, and in the process gain support for cool login methods like shadow passwords, LDAP, and NT domains into your mon server. In addition, PAM modules can be "stacked," which allows you to require authentication against more than one PAM module. ------------------------------------------------------------ 2.0 Caveats and Risks It is important to understand what you are getting yourself into when you use PAM with mon. Using PAM with mon should increase your security, not decrease it. Perhaps the biggest risk involved is that your passwords are going to stay around in the memory of the mon program. When a C program is done using a password, it can release the memory and the password is more or less gone. Unfortunately, in perl, we can't do our own memory management (fortunately, we don't have to!). Even an 'undef' does not guarantee that memory is going to be released or that values will be forgotten. If you're really really paranoid about certain passwords, don't use PAM authentication for mon, at least for these passwords. There is also some risk inherent in some of the third party free PAM modules that are out there. Some of them might not work with mon, or they might not work well at your site. This is something of a fact of life with free software, but at least it doesn't cost you anything to try. Of course it's also an issue with non-free software as well :) ------------------------------------------------------------ 3.0 Setting Up PAM Support For mon in Your OS Before you set up mon to use PAM for authentication, you first need to set up PAM for mon in your operating system. We discuss the two major PAM implementations here, Solaris and Linux PAM. Linux PAM has been ported to FreeBSD, Solaris, SunOS and HP-UX 9.0, so it's not just for Linux, but the instructions are the same. If you aren't running Linux, and you use Linux-PAM, however, you have to expect to be on your own as far as support goes, both with Linux-PAM and your vendor. ------------------------------------------------------------ 3.1 Setting Up PAM Support For Solaris Using Solaris PAM PAM on Solaris is configured in the file /etc/pam.conf. You should reference the man page for pam.conf(4) for syntax details. What I suggest is adding a new PAM service for mon, with the following 4 lines (you may choose to use a different PAM module): # Solaris PAM configuration for mon and www.padl.com's pam_ldap mon auth required /usr/lib/security/pam_ldap.so.1 mon account required /usr/lib/security/pam_ldap.so.1 mon session required /usr/lib/security/pam_ldap.so.1 mon password required /usr/lib/security/pam_ldap.so.1 Or, use shadow passwords with this configuration (see the section on notes for shadow passwords later in this document): # Solaris PAM configuration for shadow passwords mon auth required /usr/lib/security/pam_unix.so.1 mon account required /usr/lib/security/pam_unix.so.1 mon session required /usr/lib/security/pam_unix.so.1 mon password required /usr/lib/security/pam_unix.so.1 Be really careful about the syntax in the pam.conf file, and I highly recommend that you keep a root shell open while you're editing this file, especially when you first begin experimenting with PAM. If you mangle the pam.conf file, NO PAM AUTHENTICATION WILL WORK AND YOU WILL BE UNABLE TO LOG IN TO THE SYSTEM. Don't worry about defining PAM services (like account) that you won't use. It doesn't hurt, and it makes a good placeholder. ------------------------------------------------------------ 3.2 Setting Up PAM Support Using Linux PAM (for Linux, FreeBSD, Solaris, SunOS and HP-UX 9.0 too!) Linux PAM has a different syntax but it's just as easy to set up. You can reference the pam(8) man page or the Linux PAM page at http://www.kernel.org/pub/linux/libs/pam/ for more information. Instead of one configuration file for all of PAM, like Solaris uses, Linux uses a directory, /etc/pam.d/, which contains one file per PAM service. The contents of each file look very much like the Solaris pam.conf file, except that there's no service name. To duplicate what we did above, and set up a "mon" PAM service which used pam_ldap for authentication, we would create a file called /etc/pam.d/mon with the following lines: #%PAM-1.0 auth required /lib/security/pam_ldap.so.1 account required /lib/security/pam_ldap.so.1 session required /lib/security/pam_ldap.so.1 password required /lib/security/pam_ldap.so.1 Or for shadow passwords: #%PAM-1.0 auth required /lib/security/pam_pwdb.so.1 shadow nullok account required /lib/security/pam_pwdb.so.1 session required /lib/security/pam_pwdb.so.1 password required /lib/security/pam_pwdb.so.1 Again, don't worry about defining PAM services (like account) that you won't use. It doesn't hurt, and it makes a good placeholder. ------------------------------------------------------------ 3.3 Notes on Shadow Password Support with mon and PAM Shadow password authentication is far and away the most commonly used and best-supported PAM service (Sun supports Solaris', and RedHat supports the Linux version). You can use it with mon, although there is an important fact to note. By default, in order to read the shadow password file, you must be root, because /etc/shadow is 0400 and owned by root. That means that either the mon server must run as root, or that your password file must have less restrictive permissions. You could make it 0444, but that's like having no shadow password support at all. An intermediate approach is to create a new group, say "mon", and then 'chgrp mon /etc/shadow ; chmod 0440 /etc/shadow'. Now put the user which mon runs at, preferably a dedicated user who does nothing else, into the "mon" group and now the shadow password file will be readable only by root and the mon user, which hopefully is a locked account used only to run mon and nothing else. ------------------------------------------------------------ 4.0 Setting up PAM Authentication in mon Configuring PAM support in the OS is the hard part, the mon portion is quite easy. You need to add/change 2 lines in your mon.cf file, for example: # Use userfile authentication, followed by PAM authentication authtype = userfile pam # Use the "mon" PAM service pamservice = mon Note that in the above example, we're still using userfile authentication as the first check. If mon authenticates a user via userfile authentication, PAM is not consulted. But if userfile authentication fails, PAM is checked and the user is either authenticated or rejected. I like to keep userfile authentication for my default mon.cgi user, since it has a password and username that may be sent in the clear and I don't really want to have users in my password database with clear/known passwords. ------------------------------------------------------------ 5.0 Examples We will discuss some examples of other interesting PAM services which mon users might find interesting. Please contribute your own examples and success stories to this section! ------------------------------------------------------------ 5.1 Setting Up LDAP+SSL PAM Authentication in mon The original reason I wanted PAM support in mon was to use LDAP authentication for our organization. It is a really cool application of LDAP and PAM which will allow you to implement secure, distributed authentication for mon in conjunction with the mon.cgi GUI. It will also spare you from having to maintain a separate mon password file. Because there are a lot of different ways in which LDAP can be set up, I won't cover all possibilities here. We got this working using essentially the following method, connecting to a Netscape 4.1 Directory Server. OpenLDAP may also work but I've never tried it. The basic outline: 1. Download and install the Netscape LDAP SDK from http://www.iplanet.com/ 2. Download the latest pam_ldap from http://www.padl.com/ 3. Presumably you have a LDAP server, either Netscape or OpenLDAP, which is working and has the correct entries in it to allow authentication. I'm not sure if OpenLDAP works with SSL (it definitely works without SSL), you should check the latest release notes for pam_ldap. 4. Compile and install pam_ldap.so into /lib/security. Make sure to configure and build with ssl support. 5. Set your /etc/ldap.conf file to point to your LDAP server, and change the base name to match your organization. 6. Put a copy of cert7.db (which ships with Netscape Communicator) in the path that you specified in the ldap.conf file under sslpath. 7. Change the authtype config parameter to include "pam" in your mon.cf, and also change the pamservice variable to be the PAM service that you just set up (in the above example, we used "mon"). 8. Reset mon. 9. Test mon authentication with a user that you know doesn't exist in a local password file (assuming you're using one of the files authentication types in conjunction with PAM). A minimal ldap.conf file could look like this (with the names changed, this is what we use): host 1.2.3.4 base o=your_org.name ldap_version 3 port 636 ssl yes sslpath /etc/cert7.db ------------------------------------------------------------ 5.2 Stacking PAM Modules As mentioned previously, PAM modules can be stacked to require one or more forms of authentication. Using different keywords, authentication can be controlled to a very fine degree. Here are Solaris and Linux examples of stacking modules to require that the mon password a user submits is found both on an LDAP server and on the local machine's shadow password file: # Solaris /etc/pam.conf example of stacking modules to require # both LDAP authentication and shadow password authentication for # the 'mon' service mon auth required /usr/lib/security/pam_ldap.so.1 mon auth required /usr/lib/security/pam_unix.so.1 try_first_pass # Linux /etc/pam.d/mon example of stacking modules to require # both LDAP authentication and shadow password authentication for # the 'mon' service auth required /lib/security/pam_ldap.so.1 auth required /lib/security/pam_pwdb.so.1 shadow nullok try_first_pass This example just scratches the surface of what you can do by stacking PAM authentication modules. Please reference your PAM documentation for more examples and syntax. ------------------------------------------------------------ 5.3 Other Cool-Looking PAM Services (which haven't been tested with mon) See this page for more PAM modules: http://www.kernel.org/pub/linux/libs/pam/modules.html Some cool modules that stand out: * pam_ntdom - Authenticate against an NT PDC. From the Samba project. * pam_securid (static passwds only) - Using static passwords, you can authenticate against an ACE server (2-factor would work as well but would be of very limited usefulness, better to implement 2-factor authentication at the web server layer, e.g. mod_securid for Apache). * Netware - Authenticate against a Netware server * kerberos, S/Key, Radius, TACACS+ - Self-explanatory. mon-contrib-1.0+dfsg/README000066400000000000000000000001541160532374600154070ustar00rootroot00000000000000This directory contains user-submitted contributions. Please see the file index.html for more information. mon-contrib-1.0+dfsg/alerts/000077500000000000000000000000001160532374600160215ustar00rootroot00000000000000mon-contrib-1.0+dfsg/alerts/aim/000077500000000000000000000000001160532374600165675ustar00rootroot00000000000000mon-contrib-1.0+dfsg/alerts/aim/aim.alert000077500000000000000000000115241160532374600203740ustar00rootroot00000000000000#!/usr/bin/perl # # aim.alert - AIM alert for mon # # The first line from STDIN is summary information # # Don Harper, duck@duckland.org # # $Id: aim.alert,v 1.1.1.1 2005/02/18 17:52:13 trockij Exp $ # # Copyright (C) 2002, Don Harper # # 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; either version 2 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA # use AOL::TOC; use Getopt::Std; use Text::Wrap; $screen_name = "A SCREEN NAME HERE"; $password = "$screen_name's PASSWORD HERE"; $master = "WHO TO ALERT?"; $toc_server = "toc.oscar.aol.com"; $login_server = "login.oscar.aol.com"; $port = "9993"; getopts ("S:s:g:h:t:l:u"); $summary=; chomp $summary; $summary = $opt_S if (defined $opt_S); $mailaddrs = join (',', @ARGV); $ALERT = $opt_u ? "UPALERT" : "ALERT"; $t = localtime($opt_t); ($wday,$mon,$day,$tm) = split (/\s+/, $t); # Create the TOC object $toc = AOL::TOC::new($toc_server, $login_server, $port, $screen_name, $password); # register callbacks $toc->register_callback("SIGN_ON", \&client_signon); $toc->register_callback("ERROR", \&client_error); # Informs our master we are operational sub client_signon { $toc->add_buddy($screen_name); print "We are online and ready!\n"; sleep 1; $toc->send_im($master, " Warning: $screen_name now operation!"); } # connect to aim server if (! ( $toc->connect() ) ) { abort(); } $toc->dispatch(); sleep 1; $str = "Subject: $ALERT $opt_g/$opt_s: $summary ($wday $mon $day $tm)\n"; $str .= wrap ("", "", "Summary output : $summary"), "\n"; $str .= "\nGroup : $opt_g\n"; $str .= "Service : $opt_s\n"; $str .= "Time noticed : $t\n"; $str .= "Secs until next alert : $opt_l\n"; $str .= wrap ("", "", "Members : $opt_h"), "\n"; $str .= "\nDetailed text (if any) follows:\n"; $str .= "-------------------------------\n"; while () { $str .= $_; } print "sending: $str to $master\n"; $toc->send_im($master,$str); sleep 1; exit; sub client_error { my ($self, $code) = @_; print "ERROR: " . aim_errstr($code, $previous_target) . "\n"; } sub aim_errstr() { my ($code, $target, %_error_name); ($code, $target) = @_; %_error_name = ( # AIM Errors 901 => "$target not currently available", 902 => "Warning of $target not currently available", 903 => 'A message has been dropped, you are exceeding the server speed limit', # * Chat Errors *', 950 => 'Chat in $target is unavailable.', # * IM & Info Errors *', 960 => 'You are sending message too fast to $target', 961 => 'You missed an im from $target because it was too big.', 962 => 'You missed an im from $target because it was sent too fast.', # * Dir Errors *', 970 => 'Failure', 971 => 'Too many matches', 972 => 'Need more qualifiers', 973 => 'Dir service temporarily unavailable', 974 => 'Email lookup restricted', 975 => 'Keyword Ignored', 976 => 'No Keywords', 977 => 'Language not supported', 978 => 'Country not supported', 979 => 'Failure unknown $target', # * Auth errors *', 980 => 'Incorrect nickname or password.', 981 => 'The service is temporarily unavailable.', 982 => 'Your warning level is currently too high to sign on.', 983 => 'You have been connecting and disconnecting too fre quently. Wait 10 minutes and try again. If you continue to try, you will need to wait even longer.', 989 => 'An unknown signon error has occurred $target' ); # fatal signon errors, we should abort! if ($code eq '980' || $code eq '981' || $code eq '982' || $code eq '983' || $code eq '989') { print "Aborting...\n$_error_name{$code}\n"; abort(); } return $_error_name{$code}; } mon-contrib-1.0+dfsg/alerts/aim/aim.alert.README000066400000000000000000000021111160532374600213150ustar00rootroot00000000000000Subject: a new alert: aim.alert From: "Don 'Duck' Harper" To: mon@linux.kernel.org Date: 02 Nov 2002 11:28:14 -0600 Jim, Thanks for working on mon....it has saved my butt a few times, and keeps me looking good at the office. :) Anyway, here is a new alert for the contrib bin: aim.alert Based off mail.alert, this alert will send the same information to an AIM user who is logged in. To use, simple place in your alert.d dir, making sure it is executable by your mon user. Make user you have the perl modules AOL::TOC installed (perl -MCPAN -e "install AOL::TOC"), then just use like this in your monrc file: watch servers-prod-solaris service ping description ping servers in ADC. interval 1m monitor fping.monitor # Generic Alert Block period p1: wd {Sun-Sat} alert mail.alert hostmaster@mydom.com alert aim.alert upalert aim.alert upalert mail.alert hostmaster@mydom.com alert netpage.alert page@mydom.com upalert netpage.alert page@mydom.com alertevery 60m alertafter 2 30m mon-contrib-1.0+dfsg/alerts/bugzilla/000077500000000000000000000000001160532374600176325ustar00rootroot00000000000000mon-contrib-1.0+dfsg/alerts/bugzilla/bugzilla.alert000077500000000000000000000077111160532374600225050ustar00rootroot00000000000000#!/usr/bin/perl -w # -*-CPerl-*- # # $Id: bugzilla.alert,v 1.1.1.1 2005/02/18 17:52:13 trockij Exp $ # # bugzilla.alert - Mon alert to log a bug in Bugzilla database # # USAGE # # bugzilla.alert [--priority=priority] [--severity=severity] # [--assignee=assignee-email] [--cc=cc-email] # [--reported-url=reported-url] # [--http-userid=userid --http-password=password] # bugzilla-url userid password product-name component-name # reporter # # bugzilla.alert will take the first line of STDIN and use it for the # summary; the remaining lines of STDIN will be used for the long # description. # # AUTHOR # # Michael S. Fischer, # # Copyright (C) 2000 AuctionWatch.com. # # 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; either version 2 # of the License, or (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. # # NOTES # # URL for posting: bugzilla-url/post_bug.cgi # # CGI Parameters: # Name Default Value # ================================================================== # reporter "monitor" # product product-name (required) # component component-name (required) # assigned_to assignee (optional, defaults to "opsalert") # cc cc (optional) # bug_file_loc url (optional) # short_desc first line of STDIN # comment 1-N lines of STDIN # form_name "enter_bug" # Bugzilla_login userid (required) # Bugzilla_password password (required) use strict; use Getopt::Long; use LWP::UserAgent; use HTTP::Request::Common qw (POST); my ($rurl, $pri, $severity, $ccmail, $amail, $comment, $httpuser, $httppass); # Handle command-line args GetOptions("priority=s" => \$pri, "severity=s" => \$severity, "cc=s" => \$ccmail, "assignee=s" => \$amail, "reported-url=s" => \$rurl, "http-userid=s" => \$httpuser, "http-password=s" => \$httppass); @ARGV == 6 || usage(); usage() if $httpuser && ! $httppass; my $burl = shift; my $buser = shift; my $bpass = shift; my $prod = shift; my $comp = shift; my $rmail = shift; my $short_desc = ; # Read first line $comment .= $_ while ; # Read rest # Set up LWP user agent my $ua = new LWP::UserAgent; $ua->agent('bugzilla.alert' . $ua->agent); # Set up HTTP request my $req = POST $burl . "/post_bug.cgi", ["reporter" => $rmail, "product" => $prod, "component" => $comp, "assigned_to" => $amail, "cc" => $ccmail, "bug_file_loc" => $rurl, "short_desc" => $short_desc, "comment" => $comment, "form_name" => "enter_bug", "Bugzilla_login" => $buser, "Bugzilla_password" => $bpass]; $req->authorization_basic($httpuser, $httppass) if $httpuser; # Post it! my $resp = $ua->request($req); if ($resp->is_success()) { exit 0; } else { die $resp->error_as_HTML(); } sub usage { print < To: "'mon@linux.kernel.org'" Attached is the first release of bugzilla.alert. As its name suggests, it is used to file alerts in bugzilla. We've found that using bugzilla is a much better method of dispatching outage notices and tracking outage data (and fixes!) than the standard mon tools offer. In conjunction with internal per-service monitoring mechanisms (which are proprietary to us, but called by mon) this works wonderfully for large scale system administration. If you have any questions or comments regarding, or patches to this script, please send them to me. # $Id: bugzilla.alert.README,v 1.1.1.1 2005/02/18 17:52:13 trockij Exp $ # # bugzilla.alert - Mon alert to log a bug in Bugzilla database # # USAGE # # bugzilla.alert [--priority=priority] [--severity=severity] # [--assignee=assignee-email] [--cc=cc-email] # [--reported-url=reported-url] # [--http-userid=userid --http-password=password] # bugzilla-url userid password product-name component-name # reporter # # bugzilla.alert will take the first line of STDIN and use it for the # summary; the remaining lines of STDIN will be used for the long # description. # # AUTHOR # # Michael S. Fischer, # # Copyright (C) 2000 AuctionWatch.com. # # 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; either version 2 # of the License, or (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. # # NOTES # # URL for posting: bugzilla-url/post_bug.cgi # # CGI Parameters: # Name Default Value # ================================================================== # reporter "monitor" # product product-name (required) # component component-name (required) # assigned_to assignee (optional, defaults to "opsalert") # cc cc (optional) # bug_file_loc url (optional) # short_desc first line of STDIN # comment 1-N lines of STDIN # form_name "enter_bug" # Bugzilla_login userid (required) # Bugzilla_password password (required) mon-contrib-1.0+dfsg/alerts/gnats/000077500000000000000000000000001160532374600171355ustar00rootroot00000000000000mon-contrib-1.0+dfsg/alerts/gnats/gnats.alert000077500000000000000000000060441160532374600213110ustar00rootroot00000000000000#!/usr/bin/perl # # gnats.alert - gnats alert for mon to open tickets in gnats # # version 0.1 # # todo: # how to close tickets with an up.alert? # # Ted Serreyn, ted@serreyn.com # # Copyright (C) 2002, Ted Serreyn # # 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; either version 2 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA # # gnats.alert -S summary -c category gnatsmailaddress # # we duplicate what send-pr does, filling in appropriate fields # # need submitter id (from your gnats config) and category (send-pr -L to see list) # # # CHANGE THESE for your site # # see manpage for send-pr for what these values are for # default submitter id $SubmitterId = "mysubmitterid"; # originator $Originator = "Mon Network Monitor"; $Organization = "My Organization"; $Class = "support"; # email from backslash escape @ symbol $FromAddress = "mon\@mydomain.com"; use Getopt::Std; use Text::Wrap; getopts ("S:s:c:p:g:h:t:l:u"); $summary=; chomp $summary; $summary = $opt_S if (defined $opt_S); if (defined $opt_c) { $category = $opt_c; } else { # use this as default category $category = "test"; } if (defined $opt_p) { $priority = $opt_p; } else { # use this as default priority low,medium,high are options $priority = "low"; } $ALERT = $opt_u ? "UPALERT" : "ALERT"; $ToAddress = join (',', @ARGV); $t = localtime($opt_t); ($wday,$mon,$day,$tm) = split (/\s+/, $t); open (MAIL, "| /usr/lib/sendmail -oi -t") || die "could not open pipe to mail: $!\n"; print MAIL <Submitter-Id: $SubmitterId >Originator: $Originator >Organization: $Organization >Confidential: no >Synopsis: $summary >Severity: serious >Priority: $priority >Category: $category >Class: support >Release: unknown-1.0 >System: >Architechture: >Description: Group : $opt_g Service : $opt_s Time noticed : $t Secs until next alert : $opt_l EOF print MAIL wrap ("", "\t\t\t", "Members : $opt_h"), "\n"; print MAIL <) { print MAIL; } print MAIL <How-To-Repeat: >Fix: EOF close (MAIL); mon-contrib-1.0+dfsg/alerts/gnats/gnats.alert.README000066400000000000000000000006141160532374600222370ustar00rootroot00000000000000Subject: gnats.alert v0.1 To: mon@linux.kernel.org Attached you will find my humble contribution for the mon user community, a gnats alert. It may also be downloaded from http://www.serreyn.com/software/gnats.alert/ The idea is to open a gnats ticket if there is a network problem. My intent is to update this as gnats 4 comes out of beta. Please report any problems to ted@serreyn.com. mon-contrib-1.0+dfsg/alerts/hpov/000077500000000000000000000000001160532374600167755ustar00rootroot00000000000000mon-contrib-1.0+dfsg/alerts/hpov/hpov.alert000077500000000000000000000106031160532374600210050ustar00rootroot00000000000000#!/usr/local/bin/perl # # hpov.alert - generate event in HP OpenView # # Arguments: # -c: severity of condition (Critical, Major, Minor, etc.) # Default is "Major". # -C: Category of event. Default is "Error Alarms". # -m: address of HP OpenView manager. Default is "localhost". # -o: Event OID. REQUIRED. If event OID does not start with # a ".", default prefix is .1.3.6.1.4.1.11.2.17.1.0 for # event OID and info is passed in the MIB branch # .1.3.6.1.4.1.11.2.17.2.x.0 # # Sends alert with hostgroup name as address of snmp agent that originated the # alarm. This means that hostgroups that use this alert type must be valid # IPs or domain names. # # Upalerts are sent with severity "Normal". Should be used with rearm event # OIDs in HP Open View. # # See the section "Configuration" below to change defaults. # # Scott Prater, sprater@servicom2000.com, 2001. Based on file.alert by # Jim Trocki, trockij@transmeta.com # # $Id: hpov.alert,v 1.1.1.1 2005/02/18 17:52:13 trockij Exp $ # # Copyright (C) 1998, Jim Trocki # # 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; either version 2 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA # $RCSID='$Id: hpov.alert,v 1.1.1.1 2005/02/18 17:52:13 trockij Exp $' ; use strict; use vars qw($opt_d $opt_S $opt_s $opt_g $opt_h $opt_t $opt_l $opt_c $opt_C $opt_m $opt_o $opt_u $opt_T $opt_O); use Getopt::Std; getopts ("d:S:s:g:h:t:l:c:C:m:o:uOT"); #---------------------------------------------------------# # Configuration (edit as needed to suit your environment) # #---------------------------------------------------------# if (!$opt_o) { die "Could not generate HPOV event: no Event OID\n"; } my $OV_BIN = "/opt/OV/bin"; # Path to HP OpenView bin directory my $OV_EVENT = "ovevent"; # Name of HP OpenView program to generate alarms my $SEVERITY = $opt_c || "Major"; my $CATEGORY = $opt_C || "Error Alarms"; my $MANAGER = $opt_m || "localhost"; my $OID = $opt_o; my $DEFAULT_MIB_BRANCH = ".1.3.6.1.4.1.11.2.17"; my $DEFAULT_MIB_SUFFIX = ".0"; my $UPALERT_SEVERITY = "Normal"; #---------------------------------------------------------# # End Configuration # #---------------------------------------------------------# my $counter = 1; my ($event_oid, $event_oid_branch, $event_oid_suffix); my $summary=; chomp $summary; my $summary = $opt_S if ($opt_S); if ($OID !~ /^\./) { $event_oid = $DEFAULT_MIB_BRANCH . ".1.0." . $OID; $event_oid_branch = $DEFAULT_MIB_BRANCH . ".2"; $event_oid_suffix = $DEFAULT_MIB_SUFFIX; } else { $event_oid = $OID; $event_oid_branch = $OID; $event_oid_suffix = ""; } my $ALERT = $ENV{"MON_ALERTTYPE"} || "UNKNOWN ALERT"; my $RETVAL = $ENV{"MON_RETVAL"} || 0; # If this is an upalert, send rearm event OID to HPOV with proper severity if ($opt_u) { $SEVERITY = $UPALERT_SEVERITY; } my $t = localtime($opt_t); my ($wday,$mon,$day,$tm) = split (/\s+/, $t); # MIB tree structure # First Var: integer (for return code) # Second var: summary line # Following vars: detailed output, line by line my $first_var = "$event_oid_branch.$counter$event_oid_suffix Integer $RETVAL"; $counter++; my $second_var = "$event_oid_branch.$counter$event_oid_suffix OctetString \'$ALERT $opt_g $opt_s $opt_t --$wday $mon $day $tm-- $summary\'"; $counter++; my $cmd = "$OV_BIN/$OV_EVENT -s $SEVERITY -c \"$CATEGORY\" -a $opt_g \"$MANAGER\" $event_oid $first_var $second_var"; # # The remaining lines contain more detailed information: # add them to the MIB branch. # while () { chomp; $cmd .= " $event_oid_branch.$counter$event_oid_suffix OctetString \'$_\'"; $counter++; } # Send the alarm my $exit_status = system($cmd); if ($exit_status != 0) { die ("Cannot send event to HPOV: !$\n"); } exit; mon-contrib-1.0+dfsg/alerts/hpov/hpov.alert.README000066400000000000000000000026221160532374600217400ustar00rootroot00000000000000Subject: hpov.alert: Alert script to generate events in HP Open View Date: Wed, 14 Feb 2001 10:36:25 +0100 From: "Scott Prater" To: Below is a perl script I wrote to send alarms to HP OpenView, our network management system. Mon and this script solved the problem we faced of integrating monitorization of services and systems without SNMP support into our overall monitor structure (which is built around HP Open View, an SNMP-based network management system). I imagine that the alert script could be easily adapted to other such SNMP-based management systems, such as Tivoli. A brief description of the alert script (parameters, defaults, etc.) is included in comments at the head of the script. I assume knowledge of HP OpenView, MIBs, OIDs, events, etc.. One caveat: the script sends the alarm with the hostgroup as the originating pseudo snmp agent. This means that the hostgroup must be a single valid IP or domain name in your network, in order for HP OpenView to correctly associate it with the appropriate node. I'm not familiar enough with mon to know if there's a way to extract the specific machine that raised an alarm from the hostgroup list passed to the alert scripts. This would be a good thing. As always, comments, suggestions, constructive criticisms gratefully accepted. Scott Prater mon-contrib-1.0+dfsg/alerts/lvs/000077500000000000000000000000001160532374600166255ustar00rootroot00000000000000mon-contrib-1.0+dfsg/alerts/lvs/ipvs.alert000077500000000000000000000074501160532374600206500ustar00rootroot00000000000000#!/usr/bin/perl # ipvs.alert - Linux Virtual Server alert for mon # Bring a realserver up or down, or remove the entire virtual server. # # Invocation: # To remove a realserver from a virtual service: # ipvs.alert -P -V -R # To add a realserver to an existing virtual service: # ipvs.alert -u -P -V -R -W -F # To remove a virtual service along with any associated realservers: # ipvs.alert -D -P -V # To create a virtual service with the given realserver: # ipvs.alert -u -B -P -V -S -R -W -F # # Options: # -P protocol (tcp|udp) # -V virtual server # -R realserver # -W weight # -F forwarding type (nat|tun|dr) # -S scheduler (rr|wrr|lc|wlc|lblc|lblcr|dh|sh|sed|nq) # -D delete the entire virtual server # -B rebuild the virtual server # # Notes: # - -u is added automatically when ipvs.alert is part of an # ``upalert''. You can leave it out or append a dozen, this does not # matter. # - You can't build (-B) a virtual service without giving a # realserver, but you *can* add a realserver without building a # virtual service. # - the comments are almost double the volume of the script itself. # Good, bad or just plain ugly? # - Since it uses ipvsadm, this script (and therefore Mon) must # unfortunately run as root :( use Getopt::Std; getopts ("uDBs:g:h:t:l:P:V:R:W:F:S:"); $ipvsadm = "/sbin/ipvsadm"; $virtual_service = "$opt_V"; $realserver = "-r $opt_R"; $scheduler = "-s $opt_S"; %proto = ( "tcp" => "-t", "udp" => "-u", ); %type = ( "nat" => "-m", "tun" => "-i", "dr" => "-g", ); if ($opt_u) { # bring up the realserver if ($opt_B) { # build the virtual service first system("$ipvsadm -A $proto{$opt_P} $virtual_service $scheduler"); } $weight = "-w $opt_W"; system("$ipvsadm -a $proto{$opt_P} $virtual_service $realserver $weight $type{$opt_F}"); } elsif ($opt_D) { # tear down the entire virtual server system("$ipvsadm -D $proto{$opt_P} $virtual_service"); } else { # delete the realserver system("$ipvsadm -d $proto{$opt_P} $virtual_service $realserver"); }; # # ## ### ##### ######## ############# ##################### # CHANGELOG # Mon Jul 12 14:12:49 MYT 2004 # Initial [messy] version # Christopher DeMarco # Thu Jul 15 11:02:06 MYT 2004 # Added -D to delete the entire virtual server # Bringing up a service also adds the virtual server # General code overhaul # Christopher DeMarco # Mon Jul 26 10:09:34 MYT 2004 # Renamed "lvs" to "ipvs" # Christopher DeMarco # Wed Oct 1 18:34:27 CEST 2008 # fixed inline documentation # fixed whitespace/tab # Richard Hartmann # # ## ### ##### ######## ############# ##################### # Copyright (C) 2004, Christopher DeMarco # Copyright (C) 2008, Richard Hartmann # # 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; either version 2 of the # License, or (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU # General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA # 02111-1307 USA mon-contrib-1.0+dfsg/alerts/sms/000077500000000000000000000000001160532374600166235ustar00rootroot00000000000000mon-contrib-1.0+dfsg/alerts/sms/bulksms/000077500000000000000000000000001160532374600203035ustar00rootroot00000000000000mon-contrib-1.0+dfsg/alerts/sms/bulksms/README000066400000000000000000000014141160532374600211630ustar00rootroot00000000000000Date: Thu, 15 Sep 2005 14:41:09 +0100 From: Aled Treharne To: mon@linux.kernel.org Subject: New alert for sending sms alerts through www.bulksms.co.uk Hi. To get around a problem we have here, I've written an alert script which uses bulksms.co.uk to send sms messages to preconfigured mobiles phones for alerting. It's attached, however a few caveats: 1) I'm a python geek, not a perl geek, so it's written in python. Sorry. :) 2) It requires the BulkSMS API as found on their site as well as a few other python bits. 3) It uses FreeBSD assumptions for file locations. Any problems, please let me know. Thanks, Aled. _______________________________________________ mon mailing list mon@linux.kernel.org http://linux.kernel.org/mailman/listinfo/mon mon-contrib-1.0+dfsg/alerts/sms/bulksms/bulksms.alert.py000066400000000000000000000115121160532374600234430ustar00rootroot00000000000000#!/usr/local/bin/python ''' bulksms.alert - Alert script for mon to pass SMS messages to the www.bulksms.co.uk system. ''' import BulkSMS # API for Bulksms.co.uk - see import ConfigParser import os import getopt import sys import string import time # Keep the main settings in a config file so that we can share them # Look in /usr/local/etc/mon/bulksms.conf and ./bulksms.conf def get_config(): # Set all of our default config options # NB: During testing, pretend is default settings = ConfigParser.ConfigParser() settings.read(['/usr/local/etc/mon/bulksms.conf','./bulksms.conf']) config = { 'userid' : settings.get('BulkSMS','username'), 'password' : settings.get('BulkSMS','password'), 'cost' : settings.get('BulkSMS','default_cost_route'), 'from' : settings.get('BulkSMS','source'), 'recipients' : string.split(settings.get('BulkSMS','recipients'),','), 'LAST_SUMMARY' : os.getenv('MON_LAST_SUMMARY'), 'LAST_OUTPUT' : os.getenv('MON_LAST_OUTPUT'), 'LAST_FAILURE' : os.getenv('MON_LAST_FAILURE'), 'FIRST_FAILURE' : os.getenv('MON_FIRST_FAILURE'), 'LAST_SUCCESS' : os.getenv('MON_LAST_SUCCESS'), 'DESCRIPTION' : os.getenv('MON_DESCRIPTION'), 'GROUP' : os.getenv('MON_GROUP'), 'SERVICE' : os.getenv('MON_SERVICE'), 'RETVAL' : os.getenv('MON_RETVAL'), 'OPSTATUS' : os.getenv('MON_OPSTATUS'), 'ALERTTYPE' : os.getenv('MON_ALERTTYPE'), 'TRAP_INTENDED' : os.getenv('MON_TRAP_INTENDED'), 'LOGDIR' : os.getenv('MON_LOGDIR'), 'STATEDIR' : os.getenv('MON_STATEDIR'), 'subject' : sys.stdin.readline(), 'hosts' : '', 'alertevery' : '', 'trap_timeout' : 0, 'time' : '', 'trap_triggered': 0, 'upalert': 0 } short_opt = 's:g:h:l:Ot:Tu?' try: (opts, extras) = getopt.getopt(sys.argv[1:], short_opt) except getopt.GetoptError, ex: raise UsageError, ex debug(opts) debug(extras) debug(sys.argv) for item in opts: if item[0] == '-s': config['SERVICE'] = item[1] elif item[0] == '-g': config['GROUP'] = item[1] elif item[0] == '-h': config['hosts'] = item[1] elif item[0] == '-l': config['alertevery'] = item[1] elif item[0] == '-O': config['trap_timeout'] = 1 elif item[0] == '-t': if item[1].isdigit(): config['time'] = time.ctime(float(item[1])) else: raise RuntimeError, 'Type mismatch on time parameter: not float' elif item[0] == '-T': config['trap_triggered'] = 1 elif item[0] == '-u': config['upalert'] = 1 elif item[0] == '-?': raise UsageError, 'Help requested' else: raise RuntimeError, 'Error in parameters' return config def debug(message): debug=1 errlog = open('/tmp/bulksms.log','a') if debug: errlog.write('%s\n' % message) errlog.close() def usage(ex): if str(ex) == 'Help requested': print __doc__ elif str(ex) == 'Version information requested': version_info() else: sys.stderr.write("\n%s\n" % __doc__) sys.stderr.write("Error: %s\n" % str(ex)) def version_info(): version = "%s v%s" % (os.path.basename(sys.argv[0]), __version__) print version class UsageError(Exception): pass # Here endeth the standard lesson...er...section. ################################################ # Ok, up until this point it's all been stuff about making this pretty. # Here's where the actual guts of the thing starts. # The main bit. def main(): #Get the config sorted debug('started') config=get_config() debug('Got config.') debug(config) #Set up our BulkSMS interface sms = BulkSMS.BulkSMS(config['userid'],config['password']) sms.cost_route = config['cost'] if config['upalert']: message = 'UPALERT %s/%s: %s is now showing OK' % ( config['GROUP'], config['SERVICE'], config['hosts'] ) else: message = 'ALERT %s/%s: %s (Last tested OK %s)' % ( config['GROUP'], config['SERVICE'], config['hosts'], config['LAST_SUCCESS']) debug(message) ## fd = open('/tmp/output.test','w') ## debug(fd) msgid = sms.send_sms(config['recipients'], message, sender = config['from']) debug(msgid) ## fd.write(message) ## fd.write('%s' % msgid) ## fd.close # EOG (End of Guts - the end of the guts of the application) # This is the main application. It does nothing except pump us back up # into where we should be and raise a usage exception if something screwed up. if __name__ == '__main__': try: main() except UsageError, ex: usage(ex) mon-contrib-1.0+dfsg/alerts/sms/bulksms/bulksms.conf000066400000000000000000000006201160532374600226300ustar00rootroot00000000000000[BulkSMS] # Defaults for all BulkSMS operations # Your BulkSMS user details username: boxuk password: 0ffice # Which is your preferred cost route - see http://www.bulksms.co.uk/w/pricing.htm default_cost_route: 1 # From address # Not necessarily honoured, see BulkSMS documentation # ' delimited string source: '447956548902' # Recipients, specified as a python list recipients: ['447956548902'] mon-contrib-1.0+dfsg/alerts/sms/sendsms/000077500000000000000000000000001160532374600202775ustar00rootroot00000000000000mon-contrib-1.0+dfsg/alerts/sms/sendsms/sendsms000077500000000000000000000233431160532374600217060ustar00rootroot00000000000000#!/usr/bin/perl # ############################################################################ ## ## ## sendsms Version 1.5.0 ## ## 2005-02-01 ## ## Copyright (C) 1999-2005 ## ## Peter Holzleitner (peter@holzleitner.com) ## ## ## ############################################################################ # # This script sends an SMS message to a GSM phone using a GSM # modem connected to the local host. This is independent of the # GSM provider in question and does not rely on any infrastructure # except the GSM network itself and the local host and modem. # # Arguments: # # --number=+436641234567 # [--modem=ttyS3] specify without /dev/ prefix # [--pin=9999] # [--text="message text"] supply message text as cmdline arg # [--subject] extract subject from mail msg on stdin # [--qpage=pagerid@server] if SMS fails, send message via QPAGE # [--verbose] show interaction with modem step by step # [--debug] set Expect debug level # # The message text is expected on standard input unless --text is present. # # Requirements: # # Perl modules Expect, IO::Stty and IO::Tty, # available from CPAN (http://www.cpan.org) # # 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; either version 2 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software Foundation, # Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA # # History: # # 1.5.0 on error, register on home network (Erik B.) # 1.3.0 added fallback to qpage # 1.2.3 added delays for compatibility with Siemens modem # 1.2.2 locking converted to sysopen(); syslog() added # 1.2.1 message corrections # 1.2.0 device locking added # 1.1.0 addition of --subject option # 1.0.0 initial release; tested with FALCOM A2 # use English; use Getopt::Long; use Fcntl qw(:DEFAULT :flock); use IO::Handle; use Expect; use Sys::Syslog qw(:DEFAULT setlogsock); # ################# user configurable parameters ###################### $stdpin = "9999"; $stddev = "ttyS0"; # without /dev/ $ttymodes = 'raw -echo 9600 cs8 -parenb -cstopb'; # raw, 9600/8N1 $lockretry = 20; # number of retries $locksleep = 5; # number of seconds between retries $lockrand = 5; # max number of seconds added to above randomly $qpagebin = '/usr/bin/qpage'; # ############## end of user configurable parameters ################## ($^O eq "linux" || $^O eq "openbsd") && setlogsock ('unix'); openlog('sendsms', '', 'user'); GetOptions(\%opt, "modem=s", "number=s", "pin=s", "text=s", "qpage=s", "debug:i", "subject", "verbose"); $pin = $opt{"PIN"} || $stdpin; $device = $opt{"modem"} || $stddev; $verbose = $opt{"verbose"}; $qpage = $opt{"qpage"}; ($qpserver, $qpager) = ($2, $1) if $qpage =~ /(.+)@(.+)/; $lock = "/var/lock/LCK.." . $device; $device = "/dev/" . $device; $name = getpwent(); $expectpin = 0; $Expect::Debug = $opt{"debug"}; # default 0 assigned by getopt ":i" $Expect::Manual_Stty = 1; $Expect::Log_Stdout = 1; $number = $opt{"number"} or die "usage: sendsms --number=destination-number [--modem=/dev/modem] [--pin=9999] [--text=\"message\"] [--verbose] < message\n"; $number = '"' . $number . '"'; if($opt{"text"}) { $message = $opt{"text"}; } elsif($opt{"subject"}) { $message = '(no subject)'; while(<>) { $message = $1 if /^Subject: (.*)$/i; } print STDERR "MAIL mode: message=$message\n" if $verbose; } else { @message = <>; $message = join '', @message; } syslog('debug', "sending \"$message\" to $number"); eval { print STDERR "SENDSMS: sending \"$message\" to $number\n\n" if $verbose; print STDERR "Checking for Lock $lock ...\n" if $verbose; $retry = $lockretry; while($retry > 0 && -e $lock) { open(LOCK, "<$lock"); $line = ; close(LOCK); $pid = ""; $pid = $1 if $line =~ /([0-9]+)/; $ERRNO = 0; $prio = getpriority(PRIO_PROCESS, $pid); if(($pid eq "") || ($ERRNO != 0)) { # process doesn't exist anymore syslog('warning', "Lock $lock by PID $pid is stale, removing"); print STDERR "Lock $lock by PID $pid is stale, removing ...\n" if $verbose; unlink($lock); next; } # valid lock, wait for removal $secs = $locksleep + int(rand($lockrand)); syslog('warning', "Lock $lock held by PID $pid, waiting $secs s ($retry)"); print STDERR "Lock $lock held by PID $pid, waiting $secs s ($retry) ...\n" if $verbose; sleep($secs); $retry--; } if ( -e $lock ) { syslog('error', "cannot get lock $lock"); die "cannot get lock $lock"; } print STDERR "Obtaining Lock $lock ... " if $verbose; sysopen(LOCK, $lock, O_WRONLY|O_CREAT|O_EXCL) or die "cannot create lock $lock"; syswrite(LOCK, "$PID $PROGRAM_NAME $name\n"); print STDERR "done\n" if $verbose; print STDERR "Opening $device ... " if $verbose; open(DEVICE, "+>$device") || die "Couldn't open $device, $!\n"; $modem = Expect->exp_init(\*DEVICE); # 'objectify' device for Expect module print STDERR "OK\nSetting device mode ..." if $verbose; $res = $modem->exp_stty($ttymodes) or die "error setting tty mode"; # throw residual input characters away $modem->expect(0); print $modem "\r"; select(undef, undef, undef, 0.2); print $modem "AT\r"; select(undef, undef, undef, 0.5); print STDERR "OK\n" if $verbose; print $modem "ATS18=1\r"; select(undef, undef, undef, 0.5); print STDERR "testing PIN ... " if $verbose; print $modem "AT+CPIN?\r"; $res = $modem->expect(10, 'CPIN: READY', 'CPIN: SIM') || die "AT+CPIN?: no response!\n"; if($res == 2) # expects SIM PIN { $expectpin = 1; print STDERR "sending PIN ...\n" if $verbose; print $modem "AT+CPIN=$pin\r"; ($res, $err, $match, $before, $after) = $modem->expect(10, 'OK', '+CME ERROR') || die "AT+CPIN=****: no response!\n"; die "error sending PIN code: $after" if $res != 1; print STDERR "PIN sent, waiting for network ...\n" if $verbose; sleep(30); # let modem register on SMS network after setting PIN } else { print STDERR "PIN OK\n" if $verbose; } print STDERR "checking network ... " if $verbose; print $modem "AT+CREG?\r"; $res = $modem->expect(10, '+CREG: 0,1', '+CREG: 0,2', '+CREG: 0,0', '+CME ERROR') || die "AT+CREG?: no response!\n"; if($res != 1) { print STDERR "error from AT+CREG" if $verbose; if($expectpin == 1) { print STDERR "re-setting PIN\n" if $verbose; print $modem "AT+CPIN=$pin\r"; print STDERR "delaying ...\n" if $verbose; sleep(20); } print STDERR "trying to register on home network\n" if $verbose; print $modem "AT+COPS=0\r"; $res = $modem->expect(10, 'OK', '+CME ERROR') || die "AT+COPS=0: no response!\n"; print STDERR "delaying ...\n" if $verbose; sleep(6); print STDERR "re-checking network ... " if $verbose; print $modem "AT+CREG?\r"; $res = $modem->expect(10, '+CREG: 0,1', '+CREG: 0,2', '+CREG: 0,0', '+CME ERROR') || die "AT+CREG?: no response!\n"; die "error from AT+CREG?: $after" if $res == 3 || res == 4; die "GSM modem not registered on network" if $res != 1; } print STDERR "OK, online\n" if $verbose; print STDERR "checking SMS status ... " if $verbose; print $modem "AT+CSMS?\r"; $res = $modem->expect(10, '+CSMS: 0,1,1', '+CME ERROR') || die "AT+CSMS?: no response!\n"; die "error from AT+CSMS?: $after" if $res != 1; print STDERR "OK, SMS active\n" if $verbose; print STDERR "setting SMS text mode ... " if $verbose; print $modem "AT+CMGF=1\r"; $res = $modem->expect(10, 'OK', 'ERROR') || die "AT+CMGF=1: no response!\n"; die "error from AT+CMGF=1: $after" if $res != 1; print STDERR "OK\n" if $verbose; select(undef, undef, undef, 1.0); print STDERR "sending message ... " if $verbose; #$modem->debug(2); print $modem "AT+CMGS=$number\r"; $res = $modem->expect(60, '> ') || die "AT+CMGS=...: no prompt!\n"; select(undef, undef, undef, 0.5); print $modem "$message\032"; # \032 = 0x1A = ^Z $res = $modem->expect(60, '-re', '\+CMGS: [0-9]+', 'ERROR') || die "AT+CMGS=...: no response!\n"; die "error from AT+CMGS=..." if $res != 1; #$modem->debug(0); $match = $modem->exp_match(); $match =~ /CMGS: ([0-9]+)/; # extract sent message number print STDERR "OK, Message #$1 sent\n" if $verbose; syslog('info', "Message sent successfully to $number: \"$message\""); print STDERR "Closing\n" if $verbose; $modem->expect(0); # throw rest of output away $modem->hard_close(); # bye. print STDERR "Removing Lock $lock ... " if $verbose; close(LOCK); unlink($lock); }; # end eval{} if($@) { syslog('warning', "SENDSMS to $number failed"); if( $qpager ) { syslog('warning', "forwarding message to QPAGE"); print STDERR "\nSENDSMS failed, forwarding message to QPAGE\n" if $verbose; system("$qpagebin -s $qpserver -p $qpager '$message'"); } } print STDERR "$@" if $verbose; print STDERR "done.\n" if $verbose; exit 0; mon-contrib-1.0+dfsg/alerts/sms/sms.alert000077500000000000000000000007041160532374600204620ustar00rootroot00000000000000#!/usr/bin/perl use Getopt::Std; getopts ("s:g:h:t:l:u"); $summary=; chomp $summary; $rest=""; while () { $rest .= $_; } foreach $number (@ARGV) { # system("echo `date` `id` $number $summary >> /tmp/sms.alert.log"); open (SMS, "| /usr/bin/gnokii --sendsms $number") || die "could not open pipe to sms: $!\n"; print SMS $summary; print SMS "\n"; print SMS $rest; close (SMS); } mon-contrib-1.0+dfsg/alerts/sms/sms.alert.README000066400000000000000000000010331160532374600214070ustar00rootroot00000000000000Date: Thu, 28 Jun 2001 13:15:09 +0200 From: Robert Sander To: trockij@transmeta.com Subject: sms alert with gnokii Hi Jim! I have attached an alert script for mon that we use to send SMS messages via gnokii and a Nokia phone. Feel free to do anything with it. Greetings -- Robert Sander Computer Scientist Epigenomics AG Bioinformatics R&D www.epigenomics.com Kastanienallee 24 +493024345330 10435 Berlin mon-contrib-1.0+dfsg/alerts/sms/sms/000077500000000000000000000000001160532374600174255ustar00rootroot00000000000000mon-contrib-1.0+dfsg/alerts/sms/sms/sms.alert000077500000000000000000000044321160532374600212660ustar00rootroot00000000000000#!/usr/bin/perl # # sms.alert - send an alert via SMS (sendsms) v1.5 2003-04-07 # # This will accept multiple phone numbers in @ARGV and call # sendsms for each one of them. # # sendsms-specific options: # -n destination number # -t "message" # host # # Peter Holzleitner, P.Holzleitner@computer.org # Jim Trocki, trockij@transmeta.com # # Copyright (C) 1998, Peter Holzleitner # Copyright (C) 1998, Jim Trocki # # 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; either version 2 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA # # History: # # 1.5 filter single quotes (Erik Bolso) # 1.4 fix loop break bug (Geta Andualem) # 1.0 original release (P.Holzleitner) # use Getopt::Std; use Sys::Syslog; openlog('sms.alert', '', 'user'); getopts ("s:g:h:t:c:f:l:q:u"); # # the first line is summary information, adequate to send to a pager # or email subject line # # the following lines normally contain more detailed information, # but this is monitor-dependent # @MSG=; $summary = shift @MSG; chomp $summary; $detail = join(' ', @MSG); $detail =~ tr/\r\n\'/ /s; $detail = substr($detail, 0, 130); # real cutoff to 160 total done in sendsms $t = localtime($opt_t); ($wday,$mon,$day,$tm) = split (/\s+/, $t); ($hr,$min,$sec) = split(':', $tm); $ALERT = $opt_u ? "UPALERT" : "ALERT"; foreach $pagedest (@ARGV) { syslog('notice', "sendsms calling $pagedest"); SMS: for($retry = 1; $retry < 4; $retry++) { $res = system("/usr/sbin/sendsms -n '$pagedest' -t '$ALERT $opt_g/$opt_s: $summary ($hr:$min) $detail' &"); last SMS if $res == 0; syslog('warning', "sendsms to $pagedest failed, retrying($retry) after delay"); sleep 15; } sleep 5; } mon-contrib-1.0+dfsg/alerts/snapshot/000077500000000000000000000000001160532374600176605ustar00rootroot00000000000000mon-contrib-1.0+dfsg/alerts/snapshot/snapdelete.alert000077500000000000000000000075701160532374600230510ustar00rootroot00000000000000#!/usr/bin/perl # # NetApp Snapshot deletion alert script # By: Theo Van Dinter (tvd@colltech.com, felicity@kluge.net) (c) 1998-2001 # # Revision Info: $Id: snapdelete.alert,v 1.1.1.1 2005/02/18 17:52:13 trockij Exp $ # # first line of STDIN (summary) is hosts seperated by whitespace. # rest of lines are in the format "#.#GB free on host:/vol/volume/.snapshot". # # assumes you're using my netappfree.monitor script as well (need more # verbose error reporting than the standard netappfree.monitor provides.) # assumes rsh access to the filer. (there's no other way to do a snap delete.) # # 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; either version 2 of the License, or (at your # option) any later version. # # This program is distributed in the hope that it will be useful, but # WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU # General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. # use strict; use Getopt::Std; use vars qw/$opt_m $opt_M $opt_o $opt_v/; getopts ("m:Mo:v:"); my(@delorder) = (); # names to delete, in order. my(@delvalid) = qw/ weekly nightly hourly /; # valid snaps to delete. @delorder = split(/,/,$opt_o) if ( defined $opt_o ); @delvalid = split(/,/,$opt_v) if ( defined $opt_v ); my($delregex) = '^(' . join("|",@delvalid) . ')\.\d+$'; my(@hosts) = split(/\s+/, scalar ); die "Need at least 1 hostname to handle!" unless (@hosts); $ENV{'PATH'} = "/bin:/usr/bin"; # secured path while ( chomp($_=) ) { next unless /\S/; # skip blank lines next unless /\.snapshot$/; # only care about snapshots # Split the enhanced netappfree.monitor detailed output. # requires an OnTap version that understands volumes (/vol/...) my($host,$volume) = (m!^.+?free on ([^:]+):/vol/([^/]+)!); die "Couldn't get host and volume from \"$_\"!" unless ( $host && $volume ); open (RSH,"rsh $host -l root snap list $volume|") || die "Can't run rsh:$!"; # skip the useless working .... crap ... 1 until ( ($_=) =~ /^\s*$/ ); # figure out which snapshots are around, order oldest first. my(%snaps,@snapinfo); my($todel) = ""; while ( chomp($_=) ) { # parse the listing push(@snapinfo,$_); next unless /^\s*\d/; # skip non-snapshot line if ( @delorder ) { my($snaptype,$snapnum) = /\s(\S+)\.(\d+)\s*$/; unshift(@{$snaps{$snaptype}}, "$snaptype.$snapnum"); } else { # which are valid? my($snapname) = /\s(\S+\.\d+)\s*$/; next unless ( $snapname ); $todel = $snapname if ( $snapname =~ /$delregex/o ); } } close (RSH); # pick the best one to use if we specify which to delete... if ( @delorder ) { foreach ( @delorder ) { $todel = shift @{$snaps{$_}}; last if ( $todel ); } } if ( $todel ) { # delete the snapshot ... system("rsh $host -l root snap delete $volume $todel"); &Mailsomething($opt_m, "removed $host volume $volume snapshot \"$todel\"") if ( $opt_m ); } elsif ( $opt_M && $opt_m ) { # no snapshots to delete, wants mail. &Mailsomething($opt_m, "alert! $host volume $volume", "No snapshots were found eligible for removal, please do something!\n", "\nResults of \"snap list $volume\":\n\n", join("\n",@snapinfo)); } } # Sends out mail using sendmail ... Should really change this to # Mail::Internet or something ... # sub Mailsomething { my($to,$subject,@body) = @_; die "To not given!" unless ( $to ); die "Subject not given!" unless ( $subject ); open(MAIL,"|/usr/lib/sendmail -t"); print MAIL "To: $to\nFrom: nobody\nSubject: $subject\n\n",@body,"\n"; close(MAIL); return; } mon-contrib-1.0+dfsg/alerts/snapshot/snapdelete.alert.README000066400000000000000000000060261160532374600237750ustar00rootroot00000000000000snapdelete.alert is an alert script for mon that will automatically delete the oldest snapshot off of a NetApp filer volume. This is useful in the situation where the snapshots are kept around for convenience and regularly fill up enough to cause problems using the volume. It requires Theo Van Dinter's enhanced netappfree.monitor script, and rsh-like access to the filer to execute the necessary snapshot commands. (rsh is available from the filer by default ("options rsh.enable" and etc/hosts.equiv), but SSH may be available if the filer has SecureAdmin enabled. YMMV.) Tested against OnTap 5.2.x, should work on later versions as well. To install, simply place the alert script in the mon alerts directory. The alert can be added to the mon config like any other alert, but it has a few optional parameters that you may want to use: -M This specifies that if a valid snapshot isn't available for deletion (they're all gone already, etc.), a mail should be sent out saying as much with a list of currently available snapshots. -m This is a comma-seperated list of email addresses which should be contacted when a snapshot is deleted or (using -M) if no snapshot is eligible for deletion. -o This is a comma-seperated list of snapshot types (weekly, nightly, hourly) which specifies an order of deletion. ie: if "-o weekly,nightly,hourly" is specified, weekly snapshots are all removed first, then nightly snapshots, then hourly snapshots. The default, if "-o" isn't specified, is to delete the oldest valid snapshot available. -r The default command for use against the NetApps is rsh (since it's available by default). If you need to change the path or parameters ("/usr/bin/rsh -l root" by default), use "-r". For instance, on HPUX, the command is "remsh" instead of "rsh". -v This is a comma-seperated list of snapshot types which are allowed to be removed. For instance, if the configuration has "-v weekly,nightly", only weekly and nightly snapshots are considered for removal. The default, if "-v" isn't specified is "weekly,nightly,hourly". When configured, the mon configuration will look like: watch toasters service snapfreespace description Check snapshot space on toasters interval 5m monitor netappfree.monitor -community=sysmon \ -config=/usr/lib/mon/etc/netappsnapfree.cf period wd {Sun-Sat} alert snapdelete.alert -m it-alert@company.com This will run netappfree.monitor every 5 minutes and check on the snapshot space-only (per the netappsnapfree.cf file). If any snapshot areas are running low on space, snapdelete.alert is called and will mail it-alert@company.com when a snapshot is deleted. If there are no snapshots to delete, we'll assume that another service (not shown) to check volume space will alert if the snapshots get too large. FYI: I haven't tested it, but the alert should handle a single netappfree.monitor run for the volumes and snapshots. The alert script will ignore non-snapshot details from the monitor. mon-contrib-1.0+dfsg/alerts/winpopup/000077500000000000000000000000001160532374600177025ustar00rootroot00000000000000mon-contrib-1.0+dfsg/alerts/winpopup/winpopup.alert000077500000000000000000000050241160532374600226200ustar00rootroot00000000000000#!/usr/bin/perl # # popup.alert - SMB popup (winpopup) alerts for mon # version .03 # Copyright (C) 2001, Matthew Rechs - rechsm@hotmail.com # # popup.alert is based on the alert.template distributed by mon, which is # Copyright (C) 1998, Jim Trocki # # 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; either version 2 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA # # example alert line in mon.cf: # # alert popup.alert netbios-name # # where netbios-name is the name of the workstation (not the user) # that you want to send the popup to # use Getopt::Std; use Text::Wrap; use Cwd; getopts ("S:s:g:h:t:l:u"); @checkdirs = ('/usr/local/samba/bin/', '/usr/local/bin/', '/usr/bin/'); # Set this if you don't want popup.alert to find your smbclient for you #$smbclient = '/path/to/smbclient'; while ($checkpath = shift @checkdirs && ! $smbclient) { $check = $checkpath . 'smbclient'; if (-x $check) { $smbclient = $check; last ; } } # # Last ditch attempt to find smbclient # if (! $smbclient ) { $smbclient = `which smbclient`; chomp $smbclient; } die("Couldn't find $smbclient - tried " . join(@checkdirs, ',') . ' and which') unless $smbclient; $summary=; chomp $summary; while () { $details .= $_; } $summary = $opt_S if (defined $opt_S); $ALERT = $opt_u ? "UPALERT" : "ALERT"; $t = localtime($opt_t); ($wday,$mon,$day,$tm) = split (/\s+/, $t); $alerttext = " ALERT $opt_g/$opt_s: $summary ($wday $mon $day $tm) Group : $opt_g Service : $opt_s Time noticed : $t Secs until next alert : $opt_l Members : $opt_h ------------------------------- $details "; local $SIG{PIPE} = sub { die "pipe to smbclient was broken - $! $?"}; foreach $dest (@ARGV) { open(POPUP, "| $smbclient -M $dest > /dev/null") || die("Couldn't open pipe to $smbclient - $!"); print POPUP $alerttext; close POPUP || die "broken pipe to $smbclient - $! $?"; } mon-contrib-1.0+dfsg/alerts/winpopup/winpopup.alert.README000066400000000000000000000011341160532374600235470ustar00rootroot00000000000000From: Matthew Rechs To: "'mon@linux.kernel.org'" Subject: Release Early, Often: Mon Popup Alert Module Date: Tue, 3 Jul 2001 11:50:32 -0700 Thanks for everyone's input on popup/audible alerts. I've pasted in my first crack at an SMB popup alert module. It works here, more or less. Certain of my desktops intermittently refuse to accept SMB messages from the client, generating a "session request failed" error from smbclient. I'm going to take these problems to the samba mailing list at some point, let me know if you have any info on this. mon-contrib-1.0+dfsg/contrib-guidelines.html000066400000000000000000000045441160532374600212120ustar00rootroot00000000000000 mon /contrib -- guidelines

mon /contrib -- guidelines


We encourage mon users to submit their own monitors, graphical front-ends, patches, and other utilities back into the mon community. These utilities are collected here.

This page describes the procedure for getting your contributions in the /contrib tree. We want to encourage submissions, but at the same time, we would like to keep the quality reasonable and have everything reasonably well-documented.

If you are submitting new material to the /contrib tree, you must include the following with each submission:

  1. A brief (one paragraph) description of what your submission does.
  2. A file containing your submission. If there is only one file (e.g. a self-documented monitor script), then send that. If there are multiple files in your distribution, these must be sent in a compressed tar (.tar.gz) archive.
  3. A README file, describing in more detail what your submission does, how to install it, who might find it useful, etc. See sample README files in the /contrib tree for examples of what is needed. In general, the better your README file, the more chance other people will use your software.

If you are submitting a patch to another contrib'ed item, please note the following:

  1. Your patch should fix a bug, or add a new piece of functionality, preferably by being backwards compatible. If you need or want to significantly change the way a monitor works, you might consider making a new monitor.
  2. Send patches as attached context diffs, noting what is fixed and how.
  3. There is absolutely no rule that limits the number of monitors for a particular service, for example, just because there are already 5 different HTTP monitors doesn't mean another one isn't necessary or useful.

Send your submissions via email to trockij@linux.kernel.org.

Submissions not meeting these guidelines may not be accepted.


Last modified: Tue May 22 21:47:42 PDT 2001 mon-contrib-1.0+dfsg/index.html000066400000000000000000000037611160532374600165330ustar00rootroot00000000000000 mon /contrib -- index

mon /contrib -- index

This is the mon /contrib archive. It contains user-submitted add-ons to mon, which are not included in the main mon distribution. Most submissions are not checked by the archive maintainers for quality and some may not work, or work how you expect them to (most are quite good, though).

If you have something to contribute, either a new submission or a patch to another contrib'ed item, great! Please read the contrib guidelines to speed up the inclusion of your submission in the archives.

Monitors. mon ships with a few basic monitors, extend your collection here. Browse the available monitors or download the whole collection of contrib'ed monitors.

Alerts. mon ships with a few basic alerts, extend your collection here. Browse the available alerts or download the whole collection of contrib'ed alerts.

CGI interfaces. mon ships with a basic CGI interface, monshow, but for those who want a different, less minimalist interface, you can download alternatives here. Browse the available cgi interfaces or download the whole cgi-bin collection here.

Utilities. Various utilities that help you manage and report on your mon configuration. Browse the utilities collection or download the whole collection of contrib'ed utilities here.

HOWTO documents. User-contributed documentation on mon.


Last modified: Tue May 22 21:46:29 PDT 2001 mon-contrib-1.0+dfsg/monitors/000077500000000000000000000000001160532374600164015ustar00rootroot00000000000000mon-contrib-1.0+dfsg/monitors/bgp/000077500000000000000000000000001160532374600171515ustar00rootroot00000000000000mon-contrib-1.0+dfsg/monitors/bgp/bgp/000077500000000000000000000000001160532374600177215ustar00rootroot00000000000000mon-contrib-1.0+dfsg/monitors/bgp/bgp/bgp.monitor000077500000000000000000000154671160532374600221220ustar00rootroot00000000000000#!/usr/bin/perl # # Router bgp (Border Gateway Protocol v4 ) monitor # look at each router and get the status of all is BGP neigbor # # Version 1.1 (7 april 2005) # # Copyright 2002, Marc Hauswirth, Safe Host SA # # License: GNU GPL v2, see http://www.gnu.org/copyleft/gpl.html # # Some inspiration is taked from others mon monitors and from # routerinfo.pl by Ben Buxton (bb@zipworld.net), also under GPL, see http://www.zipworld.com.au/~bb/linux/ # and from routerint.monitor by P. Strauss (philou@philou.ch) and me self (marc@safehostnet.com). # # This script works nice for me with Cisco routers (7xxx) and Cisco L3 switchs (65xx). # # Fell free to send me your comments to marc@safehostnet.com # # This script need the SNMP Session module from Simon Leinen # Wich you could found under http://www.switch.ch/misc/leinen/snmp/perl/ # It is also part of MRTG (http://people.ee.ethz.ch/~oetiker/webtools/mrtg/) # updated 7 April 2005 by Ed Ravin, # use normal Mon summary / detail reporting # accept SNMP community via environment var COMMUNITY # detect SNMP errors use SNMP; use SNMP_Session; use strict; ## -- should be a command-line option, but this is sufficient (and safer, ## since the community won't be displayed in the Mon interface to users) my $community = $ENV{'COMMUNITY'} || "public"; ## -- my @failures; my @details; $ENV{'MIBS'}= ""; # all OIDs needed are specified in script # OID's to the SNMP elements that I want to show... # From Cisco's MIB and RFC's # http://sunsite.cnlab-switch.ch/ftp/doc/standard/rfc/16xx/1657 # http://www.telecomm.uh.edu/stats/rfc/BGP4-MIB.html my %oids = ( "SysUptime" => "1.3.6.1.2.1.1.3.0", "bgpVersion" => "1.3.6.1.2.1.15.1.0", "bgpLocalAs" => "1.3.6.1.2.1.15.2.0", # "bgpPeerTable" => "1.3.6.1.2.1.15.3", "bgpPeerEntry" => "1.3.6.1.2.1.15.3.1", "bgpPeerIdentifier" => "1.3.6.1.2.1.15.3.1.1", "bgpPeerState" => "1.3.6.1.2.1.15.3.1.2", "bgpPeerAdminStatus" => "1.3.6.1.2.1.15.3.1.3", "bgpPeerNegotiatedVersion" => "1.3.6.1.2.1.15.3.1.4", "bgpPeerLocalAddr" => "1.3.6.1.2.1.15.3.1.5", "bgpPeerLocalPort" => "1.3.6.1.2.1.15.3.1.6", "bgpPeerRemoteAddr" => "1.3.6.1.2.1.15.3.1.7", "bgpPeerRemotePort" => "1.3.6.1.2.1.15.3.1.8", "bgpPeerRemoteAs" => "1.3.6.1.2.1.15.3.1.9", "bgpPeerInUpdates" => "1.3.6.1.2.1.15.3.1.10", "bgpPeerOutUpdates" => "1.3.6.1.2.1.15.3.1.11", "bgpPeerInTotalMessages" => "1.3.6.1.2.1.15.3.1.12", "bgpPeerOutTotalMessages" => "1.3.6.1.2.1.15.3.1.13", "bgpPeerLastError" => "1.3.6.1.2.1.15.3.1.14", "bgpPeerFsmEstablishedTransitions" => "1.3.6.1.2.1.15.3.1.15", "bgpPeerFsmEstablishedTime" => "1.3.6.1.2.1.15.3.1.16", "bgpPeerConnectRetryInterval" => "1.3.6.1.2.1.15.3.1.17", "bgpPeerHoldTime" => "1.3.6.1.2.1.15.3.1.18", "bgpPeerKeepAlive" => "1.3.6.1.2.1.15.3.1.19", "bgpPeerHoldTimeConfigured" => "1.3.6.1.2.1.15.3.1.20", "bgpPeerKeepAliveConfigured" => "1.3.6.1.2.1.15.3.1.21", "bgpPeerMinASOriginationInterval" => "1.3.6.1.2.1.15.3.1.22", "bgpPeerMinRouteAdvertisementInterval" => "1.3.6.1.2.1.15.3.1.23", "bgpPeerInUpdateElapsedTime" => "1.3.6.1.2.1.15.3.1.24", "bgpIdentifier" => "1.3.6.1.2.1.15.4", "bgpRcvdPathAttrTable" => "1.3.6.1.2.1.15.5", "bgp4PathAttrTable" => "1.3.6.1.2.1.15.6", "bgpPathAttrEntry" => "1.3.6.1.2.1.15.5.1", "bgpPathAttrPeer" => "1.3.6.1.2.1.15.5.1.1", "bgpPathAttrDestNetwork" => "1.3.6.1.2.1.15.5.1.2", "bgpPathAttrOrigin" => "1.3.6.1.2.1.15.5.1.3", "bgpPathAttrASPath" => "1.3.6.1.2.1.15.5.1.4", "bgpPathAttrNextHop" => "1.3.6.1.2.1.15.5.1.5", "bgpPathAttrInterASMetric" => "1.3.6.1.2.1.15.5.1.6", "bgp4PathAttrEntry" => "1.3.6.1.2.1.15.6.1", "bgp4PathAttrPeer" => "1.3.6.1.2.1.15.6.1.1", "bgp4PathAttrIpAddrPrefixLen" => "1.3.6.1.2.1.15.6.1.2", "bgp4PathAttrIpAddrPrefix" => "1.3.6.1.2.1.15.6.1.3", "bgp4PathAttrOrigin" => "1.3.6.1.2.1.15.6.1.4", "bgp4PathAttrASPathSegment" => "1.3.6.1.2.1.15.6.1.5", "bgp4PathAttrNextHop" => "1.3.6.1.2.1.15.6.1.6", "bgp4PathAttrMultiExitDisc" => "1.3.6.1.2.1.15.6.1.7", "bgp4PathAttrLocalPref" => "1.3.6.1.2.1.15.6.1.8", "bgp4PathAttrAtomicAggregate" => "1.3.6.1.2.1.15.6.1.9", "bgp4PathAttrAggregatorAS" => "1.3.6.1.2.1.15.6.1.10", "bgp4PathAttrAggregatorAddr" => "1.3.6.1.2.1.15.6.1.11", "bgp4PathAttrCalcLocalPref" => "1.3.6.1.2.1.15.6.1.12", "bgp4PathAttrBest" => "1.3.6.1.2.1.15.6.1.13", "bgp4PathAttrUnknown" => "1.3.6.1.2.1.15.6.1.14", ); my %BgpPeerState = ( 1 => "idle", 2 => "connect", 3 => "active", 4 => "opensnet", 5 => "openconfirm", 6 => "established" ); my %BgpAdminStatus = ( 1 => "stop", 2 => "start", ); my %state; foreach my $router (@ARGV) { # Get some infos about this router my $sess = new SNMP::Session ( DestHost => $router, Community => $community ); if (!defined($sess)) { push @failures, $router; push @details, "$router: cannot create SNMP session"; next; } my $bgpLocalAs = $sess->get("\." . $oids{bgpLocalAs}); if ($sess->{ErrorNum}) { push @failures, $router; push @details, "$router: error on initial SNMP get: $sess->{ErrorStr}"; next; } my $bgpIdentifier = $sess->get("\." . $oids{bgpIdentifier} . ".0"); if ($sess->{ErrorNum}) { push @failures, $router; push @details, "$router: error on subsequent SNMP get: $sess->{ErrorStr}"; next; } push @details, "$router (AS $bgpLocalAs) Id : $bgpIdentifier"; # Get through the SNMP tree to fetch all peer infos my $vars = new SNMP::VarList([$oids{bgpPeerIdentifier}],[$oids{bgpPeerRemoteAs}],[$oids{bgpPeerState}],[$oids{bgpPeerFsmEstablishedTime}],[$oids{bgpPeerAdminStatus}], [$oids{bgpPeerRemoteAddr}]); for (my @vals = $sess->getnext($vars); $vars->[0]->tag =~ /15\.3\.1\.1/ # still in table (Did you have a cleaner solutions ?) and not $sess->{ErrorStr}; # and not end of mib or other error @vals = $sess->getnext($vars)) { my $textState = $BgpPeerState{$vals[2]}; my $texttime = sectotime($vals[3]); push @details, sprintf("$router: Neighbor %-16s AS %-5u status : %-15s since : %-16s",$vals[5], $vals[1], $textState, $texttime); # if bgpPeerState != established and bgpPeerAdminStatus == start if ($vals[2] != 6 and $vals[4] == 2) { push @failures, $router; push @details, "$router: Neighbor relation: $vals[5] (AS $vals[1]) is in state $textState "; }; } } if (@failures) { print join(' ', @failures), "\n"; }; if (@details) { print "\n"; print join("\n", @details), "\n"; } if (@failures) { # Error state exit exit 1; } else { # Correct exit exit 0; }; # Transform secondes into a readable format (NNNdNNhNNm). sub sectotime { my($sec) = @_; my $texttime = ""; if ($sec >= 86400) { $texttime = int($sec/86400) . "d"; $sec -= int($sec/86400)*86400; }; if ($sec >= 3600) { $texttime .= int($sec/3600) ."h"; $sec -= int($sec/3600)*3600; } else { $texttime .= "0h"; } $texttime .= int($sec/60) . "min"; return ($texttime); }; mon-contrib-1.0+dfsg/monitors/bgp/bgp/bgp.monitor.README000066400000000000000000000033211160532374600230350ustar00rootroot00000000000000# NAME # bgp.monitor # # SYNOPSIS # bgp.monitor list_of_routers # # DESCRIPTION # This monitor look to all routers via SNMP and get the BGP (Border Gateway Protocol) # neighbor status for each bgp session. # This is most usefull for a bgp multihomed network (or ISP) to verify that # all is upstream provider or peer are alive. # This script worked fine for me over Cisco 75xx an 65xx routers. # # For use with "mon". # # INSTALATION # This script need the SNMP Session module from Simon Leinen # Wich you could found under http://www.switch.ch/misc/leinen/snmp/perl/ # They are alsopart of MRTG (http://people.ee.ethz.ch/~oetiker/webtools/mrtg/) # # # EXAMPLES # ./bgp.monitor routerIP_or_name [...] # # OUTPUT # Displays a list of all peer sessions and status. Exit status will be # non-zero if a router cannot be contacted or if a BGP session that should # be established isn't. # # OPTIONS # To use an SNMP community other than "public", set the COMMUNITY environment # variable in mon.cf in the stanza that invokes bgp.monitor. The same # community name will be tried for all the routers specified on the command # line. # # COPYRIGHT # Version 1.0, Marc Hauswirth, Safe Host SA # Some inspiration is taked from others mon monitors (www.kernel.org/pub/admin/mon/ and from # routerinfo.pl by Ben Buxton (bb@zipworld.net), also under GPL, see http://www.zipworld.com.au/~bb/linux/ # and from routerint.monitor by Philippe Strauss (philou@philou.ch) and me. # # # LICENSE # License: GNU GPL v2, see http://www.gnu.org/copyleft/gpl.html # # COMMENTS # Fell free to send me your comments to marc@safehostnet.com # # Version 1.00 -- 5 april 2002 # Version 1.1 -- 7 april 2005 mon-contrib-1.0+dfsg/monitors/cisco/000077500000000000000000000000001160532374600175015ustar00rootroot00000000000000mon-contrib-1.0+dfsg/monitors/cisco/cisco-env.monitor000077500000000000000000000161321160532374600230060ustar00rootroot00000000000000#!/usr/bin/perl # # Monitor Cisco device for certain environmental conditions via snmp # On devices that export this data, this script will detect and report: # - power supply failures # - fan blade failures # - temperature alarms # - chassis minor/major alarms # # Can parse monitor-auth.cf for snmp community string, or read from command line # # Arguments are: # # [-C monitor-auth.cf] [-c community] host [host ...] # # # cisco-env.monitor written by # Carnegie Mellon University, Computing Services # # # Copyright (c) 2004 Carnegie Mellon University. All rights reserved. # # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions are met: # # 1. Redistributions of source code must retain the above copyright notice, # this list of conditions and the following disclaimer. # # 2. Redistributions in binary form must reproduce the above copyright notice, # this list of conditions and the following disclaimer in the # documentation and/or other materials provided with the distribution. # # 3. The name "Carnegie Mellon University" must not be used to endorse or # promote products derived from this software without prior written # permission. For permission or any legal details, please contact: # Office of Technology Transfer # Carnegie Mellon University # 5000 Forbes Avenue # Pittsburgh, PA 15213-3890 # (412) 268-4387, fax: (412) 268-7395 # tech-transfer@andrew.cmu.edu # # 4. Redistributions of any form whatsoever must retain the following # acknowledgment: "This product includes software developed by Computing # Services at Carnegie Mellon University (http://www.cmu.edu/computing/)." # # CARNEGIE MELLON UNIVERSITY DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS # SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, # IN NO EVENT SHALL CARNEGIE MELLON UNIVERSITY BE LIABLE FOR ANY SPECIAL, # INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM # LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE # OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR # PERFORMANCE OF THIS SOFTWARE. # # $Id: cisco-env.monitor,v 1.1 2005/08/20 18:14:32 vitroth Exp $ # use SNMP; use Getopt::Std; use IO::File; use strict; my ($community, $timeout, %failures, %opts); getopts("c:t:C:", \%opts); $community = $opts{'c'}; $timeout = ($opts{'t'} || 3) * 1000 * 1000; my $RETVAL = 0; my %communities; my $group=$ENV{MON_GROUP}; my $service=$ENV{MON_SERVICE}; my $file = $ENV{MON_CFBASEDIR}."/monitor-auth.cf"; my $cf; if ($cf = new IO::File "<$file") { while (<$cf>) { chomp; if (/^(\S+):readcommunity\s*=\s*(\S+)$/) { $communities{$1}=$2; } } $community ||= $communities{"$group:$service"}; $community ||= $communities{"$group:*"}; $community ||= $communities{"*:$service"}; $community ||= $communities{"*:*"}; } $community ||= 'public'; foreach my $host (@ARGV) { my $session = new SNMP::Session(DestHost => $host, Community => $community, Timeout => $timeout, Retries => 2, UseNumeric => 1, UseLongNames => 2); if (!defined ($session)) { $RETVAL = ($RETVAL == 1) ? 1 : 2; $failures{$host} = "$host: could not get SNMP session"; next; } my $desc = $session->get([".1.3.6.1.2.1.1.1.0"]); if (!$desc) { $RETVAL = 1; $failures{$host} = "$host: cannot contact snmpd"; next; } my %Capture = ('ps1status' => {'oid' => '.1.3.6.1.4.1.9.5.1.2.4.0', 'desc' => 'Power Supply 1', 'res' => {'1' => 'ok', '2' => 'ok', '3' => 'minor fault', '4' => 'major fault'}, }, 'ps2status' => {'oid' =>'.1.3.6.1.4.1.9.5.1.2.7.0', 'desc' => 'Power Supply 2', 'res' => {'1' => 'ok', '2' => 'ok', '3' => 'minor fault', '4' => 'major fault'}, }, 'fanstatus' => {'oid' => '.1.3.6.1.4.1.9.5.1.2.9.0', 'desc' => 'Fan Tray', 'res' => {'1' => 'ok', '2' => 'ok', '3' => 'minor fault', '4' => 'major fault'}, }, 'tempstatus' => {'oid' => '.1.3.6.1.4.1.9.5.1.2.13.0', 'desc' => 'Temperature Status', 'res' => {'1' => 'ok', '2' => 'ok', '3' => 'minor fault', '4' => 'major fault'}, }, 'minoralarm' => {'oid' => '.1.3.6.1.4.1.9.5.1.2.11.0', 'desc' => 'Chassis Minor Alarm', 'res' => {'1' => 'ok', '2' => 'activated'}, }, 'majoralarm' => {'oid' => '.1.3.6.1.4.1.9.5.1.2.12.0', 'desc' => 'Chassis Major Alarm', 'res' => {'1' => 'ok', '2' => 'activated'}, }, # 1- normal, 5- notPresent 'env-tempstatus' => {'oid' => '.1.3.6.1.4.1.9.9.13.1.3.1.6', 'desc' => 'Temperature State', 'res' => {'1' => 'ok', '2' => 'warning', '3' => 'critical', '4' => 'shutdown', '5' => 'ok', '6' => 'notFunctioning'}, 'type' => 'walk', }, 'env-fanstate' => {'oid' => '.1.3.6.1.4.1.9.9.13.1.4.1.3', 'desc' => 'Fan State', 'res' => {'1' => 'ok', '2' => 'warning', '3' => 'critical', '4' => 'shutdown', '5' => 'ok', '6' => 'notFunctioning'}, 'type' => 'walk', }, 'env-psstate' => {'oid' => '.1.3.6.1.4.1.9.9.13.1.5.1.3', 'desc' => 'Power Supply State', 'res' => {'1' => 'ok', '2' => 'warning', '3' => 'critical', '4' => 'shutdown', '5' => 'ok', '6' => 'notFunctioning'}, 'type' => 'walk', }, ); foreach my $K (keys %Capture) { my @Results; if ($Capture{$K}->{'type'} eq 'walk') { @Results = l_snmpwalk_values($session, $Capture{$K}->{'oid'}); }else{ push(@Results, $session->get($Capture{$K}->{'oid'})); } foreach my $Res (@Results) { if (defined $Capture{$K}->{'res'}->{$Res}) { if ($Capture{$K}->{'res'}->{$Res} ne 'ok') { $RETVAL = 1; $failures{$host} .= '; ' unless ($failures{$host} eq ''); $failures{$host} .= $Capture{$K}->{'desc'}." ". $Capture{$K}->{'res'}->{$Res}; } } } } } print join (" ", sort keys %failures), "\n\n" if (scalar keys %failures); foreach my $host (sort keys %failures) { print $host.': '.$failures{$host}, "\n"; } exit $RETVAL; sub l_snmpwalk_values { my ($session, $oid) = @_; my $rootlen = length($oid); $session->{ErrorStr} = ''; my $var = new SNMP::Varbind(["$oid"]); my $val = $session->getnext($var); my $name = $var->[$SNMP::Varbind::tag_f].".".$var->[$SNMP::Varbind::iid_f]; my %walk; while (!$session->{ErrorStr} && substr($name, 0, $rootlen) eq $oid){ my $value=$var->[$SNMP::Varbind::val_f]; $walk{"$name"} = $value; $val = $session->getnext($var); $name=$var->[$SNMP::Varbind::tag_f]; $name.=".$var->[$SNMP::Varbind::iid_f]" if $var->[$SNMP::Varbind::iid_f]; } #while return values %walk; } mon-contrib-1.0+dfsg/monitors/cisco/snmp_interface/000077500000000000000000000000001160532374600224765ustar00rootroot00000000000000mon-contrib-1.0+dfsg/monitors/cisco/snmp_interface/snmp_interface.monitor000077500000000000000000000123061160532374600271110ustar00rootroot00000000000000#!/usr/bin/perl # # Monitor snmp processes # # Arguments are: # # [options] --host hostname interface [interface ...] # # This script will exit with value 1 if the named interface ('Serial0' # or 'Serial1.2' or whatever on a Cisco) on the specified host is down. # The summary output line will be the host names that failed # and the name of the port. # # Since interface names are looked up by their Cisco interface name, # you don't need to worry about SNMP indices getting renumbered when # interfaces are added or deleted. A local cache of the interface # names is maintained in the mon state directory. # # Copyright (C) 1998, Brian Moore # # 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; either version 2 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA # modified July 2000 by Ed Ravin # * added cache for ifDescr names so we don't need to dump the router's # table every time (very slow for routers with lots of interfaces) # * switched to long-name options # * added timeout option # * created --host option for host so hostname can go at end # sample entry in mon.cf: # # watch main-router.yourcompany.com # service interfaces # description SNMP status of router # interval 5m # monitor snmp_interface.mon Serial0/1 Serial0/3 --host # bugs: unlike most mon scripts, this one only accepts one hostname, # and there's no easy way for the script to detect that you're calling # it improperly. Caveat emptor. use strict; use SNMP; use DB_File; use Getopt::Long; # let's not load the whole mib.... $ENV{'MIBS'} = ''; # just fake what we want my $ifDescr = '.1.3.6.1.2.1.2.2.1.2'; my $ifOperStatus = '.1.3.6.1.2.1.2.2.1.8'; my $ifAdminStatus = '.1.3.6.1.2.1.2.2.1.7'; my $ifXEntry = '.1.3.6.1.2.1.31.1.1.1.18'; my %opt; my @failures= (); my %ifindices; my ($community, $timeout, $dir, $file, $statefile, $maxindex, $debug, $host); my $myname="snmp_interface.mon"; my $usage="usage: $myname [--community=xxx] [--timeout=sec] [--dir=statefile-dir] [--statefile=statefile-basename] [--maxindex=nn] --host ifname ...\n"; GetOptions(\%opt, "community=s", "timeout=i", "dir=s", "statefile=s", "maxindex=i", "host=s", "debug"); $host = $opt{'host'} || die $usage; $community = $opt{'community'} || 'public'; $timeout= ($opt{'timeout'} || 5) * 1000 * 1000; $dir= $ENV{"MON_STATEDIR"} || $opt{'dir'} || "/usr/lib/mon/state.d"; $file= $opt{'statefile'} || "$host.interfaces.state"; $maxindex= $opt{'maxindex'} || 0; $debug= $opt{'debug'} || 0; $statefile= $dir . "/" . $file; tie %ifindices, "DB_File", $statefile, O_RDWR|O_CREAT, 0644, $DB_HASH or die "$myname: cannot tie to $statefile: $!\n"; $SNMP::use_long_names = 1; my $session = new SNMP::Session(DestHost => $host, Community => $community, Timeout => $timeout) || die "$host (cannot initialize SNMP session)\n"; foreach my $interface (@ARGV) { if (defined($ifindices{$interface})) # already in cache? { # yes, see if the index still matches my $var = new SNMP::Varbind([$ifDescr, $ifindices{$interface}]); my $desc= $session->get($var); if ( ($session->{ErrorNum}) || ($interface !~ /^$desc/i) ) { print "removing stale entry: $interface\n" if $debug; delete $ifindices{$interface}; # cache no good, try again. } } # if the interface name is not already cached, rebuild the cache if (!defined($ifindices{$interface})) { my $var = new SNMP::Varbind([$ifDescr, 0]); print "name $interface not in cache, rebuilding..." if $debug; %ifindices= {}; while (1) { # search for the interface name, caching along the way my $desc = $session->getnext($var); last if ( $var->[$SNMP::Varbind::tag_f] !~ /^$ifDescr/ ); # no response is bad community or dead daemon or other failure... if ( $session->{ErrorNum} ) { push @failures, "$host $session->{ErrorStr}"; last; } my ($part_number) = ($var->[$SNMP::Varbind::tag_f] =~ /\.(\d+)$/); print "adding $desc to cache as index $part_number\n" if $debug; $ifindices{$desc}= $part_number; # cache this entry last if $maxindex and $part_number >= $maxindex; } } if (defined($ifindices{$interface})) { my $state= $session->get([$ifOperStatus, $ifindices{$interface}]); my $admin= $session->get([$ifAdminStatus, $ifindices{$interface}]); if ( $state ne 1 and $admin eq 1) { my $description = $session->get([$ifXEntry, $ifindices{$interface}]); push (@failures, "$host $interface $description"); } } else { push (@failures, "$host $interface cannot find matching ifDescr"); } } if (@failures) { print join (", ", @failures), "\n"; exit 1; } exit 0; mon-contrib-1.0+dfsg/monitors/cisco/snmp_interface/snmp_interface.monitor.README000066400000000000000000000040271160532374600300430ustar00rootroot00000000000000# Monitor snmp processes # # Arguments are: # # [options] --host hostname interface [interface ...] # # This script will exit with value 1 if the named interface ('Serial0' # or 'Serial1.2' or whatever on a Cisco) on the specified host is down. # The summary output line will be the host names that failed # and the name of the port. # # Since interface names are looked up by their Cisco interface name, # you don't need to worry about SNMP indices getting renumbered when # interfaces are added or deleted. A local cache of the interface # names is maintained in the mon state directory. # # Copyright (C) 1998, Brian Moore # # 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; either version 2 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA # modified July 2000 by Ed Ravin # * added cache for ifDescr names so we don't need to dump the router's # table every time (very slow for routers with lots of interfaces) # * switched to long-name options # * added timeout option # * created --host option for host so hostname can go at end # sample entry in mon.cf: # # watch main-router.yourcompany.com # service interfaces # description SNMP status of router # interval 5m # monitor snmp_interface.mon Serial0/1 Serial0/3 --host # bugs: unlike most mon scripts, this one only accepts one hostname, # and there's no easy way for the script to detect that you're calling # it improperly. Caveat emptor. mon-contrib-1.0+dfsg/monitors/citrix/000077500000000000000000000000001160532374600177035ustar00rootroot00000000000000mon-contrib-1.0+dfsg/monitors/citrix/citrix.monitor000077500000000000000000000046721160532374600226320ustar00rootroot00000000000000#!/usr/bin/perl -w # # try to connect to a citrix server and wait for the ica prompt. # # Arguments are "host [host...]" # # Jeroen Moors, Jeroen.Moors@Cegeka.be # # Copyright (C) 2005, Jeroen Moors # # 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; either version 2 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA # use Getopt::Std; use Socket; my %opt; getopts ("t:", \%opt); my $PORT = 1494; my $TIMEOUT = $opt{"t"} || 10; my @failures = (); my @detail = (); my $ALARM = 0; foreach my $host (@ARGV) { my $pro = getprotobyname ('tcp'); if (!defined $pro) { die "could not getprotobyname\n"; } if (!defined socket (S, PF_INET, SOCK_STREAM, $pro)) { die "could not create socket: $!\n"; } my $a = inet_aton ($host); if (!defined $a) { push @failures, $host; push @detail, "$host could not inet_aton"; close (S); next; } my $sin = sockaddr_in ($PORT, $a); if (!defined $sin) { push @failures, $host; push @detail, "$host could not sockaddr_in"; close (S); next; } my $r; eval { local $SIG{"ALRM"} = sub { die "alarm\n" }; alarm $TIMEOUT; $r = connect (S, $sin); my $return_string; while (my $char = getc(S)) { $return_string .= $char; if ( $return_string =~ /ICA/) { alarm 0; last; } } }; if ($@) { push @failures, $host; if ($@ eq "alarm\n") { push @detail, "$host timeout"; } else { push @detail, "$host interrupted syscall: $!"; } close (S); next; } if (!defined $r) { push @failures, $host; push @detail, "$host could not connect: $!"; close (S); next; } if (!defined close (S)) { push @failures, $host; push @detail, "$host could not close socket: $!"; next; } } if (@failures == 0) { exit 0; } print join (" ", sort @failures), "\n"; print "\n", join ("\n", @detail), "\n"; exit 1; mon-contrib-1.0+dfsg/monitors/cyrus/000077500000000000000000000000001160532374600175465ustar00rootroot00000000000000mon-contrib-1.0+dfsg/monitors/cyrus/imsp.monitor000077500000000000000000000070451160532374600221400ustar00rootroot00000000000000#!/usr/bin/perl # # Use try to connect to an IMSP server, and # wait for the right output. # # For use with "mon". # # Arguments are "-p port -t timeout host [host...]" # # Adapted from "imap.monitor" by # David Nolan, vitroth+mon@cmu.edu # # Which was adapted from "http.monitor" by # Jim Trocki, trockij@transmeta.com # # http.monitor written by # # Jon Meek # American Cyanamid Company # Princeton, NJ # # $Id: imsp.monitor,v 1.1 2005/08/20 15:24:50 vitroth Exp $ # # Copyright (C) 1998, Jim Trocki # # 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; either version 2 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA # use Getopt::Std; use English; getopts ("p:t:"); $PORT = $opt_p || 406; $TIMEOUT = $opt_t || 30; @failures = (); %details; foreach $host (@ARGV) { if (! &imspGET($host, $PORT)) { push (@failures, $host); } } if (@failures == 0) { exit 0; } print join (" ", sort @failures), "\n"; foreach (sort @failures) { if (exists $details{$_}) { print "$_: $details{$_}\n"; } } exit scalar @failures; sub imspGET { use Socket; use Sys::Hostname; my($Server, $Port) = @_; my($ServerOK, $TheContent); $ServerOK = 0; $TheContent = ''; $Path = '/'; ############################################################### eval { local $SIG{ALRM} = sub { die "Timeout Alarm" }; alarm $TIMEOUT; $result = &OpenSocket($Server, $Port); # Open a connection to the server if ($result == 0) { # Failure to open the socket alarm 0; $details{$Server} = "Connection refused"; return 0; } $in = ; if ($in !~ /^\* (OK|PREAUTH|BYE)/) { alarm 0; $details{$Server} = "No IMSP banner. Not an IMSP server?"; return 0; } print S "A1 LOGOUT\r\n"; while (defined($in=)) { if ($in =~ /^A1 OK/) { last; } } $ServerOK = 1; close(S); alarm 0; # Cancel the alarm }; if ($EVAL_ERROR and ($EVAL_ERROR =~ /^Timeout Alarm/)) { $details{$Server} = "Connection timed out after $TIMEOUT seconds\n"; return 0; } return $ServerOK; } sub OpenSocket { # # Make a Berkeley socket connection between this program and a TCP port # on another (or this) host. Port can be a number or a named service # local($OtherHostname, $Port) = @_; local($OurHostname, $sockaddr, $name, $aliases, $proto, $type, $len, $ThisAddr, $that); $OurHostname = &hostname; ($name, $aliases, $proto) = getprotobyname('tcp'); ($name, $aliases, $Port) = getservbyname($Port, 'tcp') unless $Port =~ /^\d+$/; ($name, $aliases, $type, $len, $ThisAddr) = gethostbyname($OurHostname); ($name, $aliases, $type, $len, $OtherHostAddr) = gethostbyname($OtherHostname); my $that = sockaddr_in ($Port, $OtherHostAddr); $result = socket(S, &PF_INET, &SOCK_STREAM, $proto) || return undef; $result = connect(S, $that) || return undef; select(S); $| = 1; select(STDOUT); # set S to be un-buffered return 1; # success } mon-contrib-1.0+dfsg/monitors/cyrus/lmtp.monitor000077500000000000000000000073751160532374600221520ustar00rootroot00000000000000#!/usr/bin/perl # # Use try to connect to a LMTP server (part of a Cyrus IMAP delivery # infrastucture, among others), and wait for the right output. # # For use with "mon". # # Arguments are "-p port -t timeout host [host...]" # # Adapted from "smtp.monitor" by # Chaskiel Grundman, cg2v@andrew.cmu.edu # Adapted from "http.monitor" by # Jim Trocki, trockij@transmeta.com # # http.monitor written by # # Jon Meek # American Cyanamid Company # Princeton, NJ # # $Id: lmtp.monitor,v 1.1 2005/08/20 18:06:36 vitroth Exp $ # # Copyright (C) 1998, Jim Trocki # # 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; either version 2 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA # use Getopt::Std; use English; getopts ("p:t:"); $PORT = $opt_p || 2003; $TIMEOUT = $opt_t || 30; @failures = (); foreach $host (@ARGV) { if (! &smtpGET($host, $PORT)) { push (@failures, $host); } } if (@failures == 0) { exit 0; } print join (" ", sort @failures), "\n"; foreach $msg (@details) { print "$msg\n"; } exit 1; sub smtpGET { use Socket; use Sys::Hostname; my($Server, $Port) = @_; my($ServerOK, $TheContent); my ($OurHostname); $ServerOK = 0; $TheContent = ''; $Path = '/'; ############################################################### eval { local $SIG{ALRM} = sub { die "Timeout Alarm" }; alarm $TIMEOUT; $result = &OpenSocket($Server, $Port); # Open a connection to the server if ($result == 0) { # Failure to open the socket push(@details, "${Server}: Unable to create SMTP connection to port $Port"); return ''; } $in = ; $in = while $in =~ /^220-/; if ($in !~ /^220 /) { alarm 0; push(@details, "${Server}: $in"); return 0; } $OurHostname = &hostname; print S "LHLO $OurHostname\r\n"; $in = ; $in = while $in =~ /^250-/; if ($in !~ /^250 /) { alarm 0; push(@details, "${Server}: $in"); return 0; } print S "quit\r\n"; $in = ; if ($in !~ /^221 /) { alarm 0; push(@details, "${Server}: $in"); return 0; } $ServerOK = 1; close(S); alarm 0; # Cancel the alarm }; if ($EVAL_ERROR and ($EVAL_ERROR =~ /^Timeout Alarm/)) { push(@details, "${Server}: Connection timed out"); return 0; } return $ServerOK; } sub OpenSocket { # # Make a Berkeley socket connection between this program and a TCP port # on another (or this) host. Port can be a number or a named service # local($OtherHostname, $Port) = @_; local($OurHostname, $sockaddr, $name, $aliases, $proto, $type, $len, $ThisAddr, $that); $OurHostname = &hostname; ($name, $aliases, $proto) = getprotobyname('tcp'); ($name, $aliases, $Port) = getservbyname($Port, 'tcp') unless $Port =~ /^\d+$/; ($name, $aliases, $type, $len, $ThisAddr) = gethostbyname($OurHostname); ($name, $aliases, $type, $len, $OtherHostAddr) = gethostbyname($OtherHostname); my $that = sockaddr_in ($Port, $OtherHostAddr); $result = socket(S, &PF_INET, &SOCK_STREAM, $proto) || return undef; $result = connect(S, $that) || return undef; select(S); $| = 1; select(STDOUT); # set S to be un-buffered return 1; # success } mon-contrib-1.0+dfsg/monitors/cyrus/mupdate.monitor000077500000000000000000000074211160532374600226250ustar00rootroot00000000000000#!/usr/bin/perl # # Use try to connect to an MUPDATE server, and # wait for the right output. (MUPDATE is a core part # of a distributed Cyrus IMAP server infrastructure.) # # For use with "mon". # # Arguments are "-p port -t timeout host [host...]" # # Adapted from "imap.monitor" by # David Nolan, vitroth+mon@cmu.edu # # Which was dapted from "http.monitor" by # Jim Trocki, trockij@transmeta.com # # http.monitor written by # # Jon Meek # American Cyanamid Company # Princeton, NJ # # $Id: mupdate.monitor,v 1.1 2005/08/20 15:24:50 vitroth Exp $ # # Copyright (C) 1998, Jim Trocki # # 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; either version 2 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA # use Getopt::Std; use English; getopts ("p:t:"); $PORT = $opt_p || 3905; $TIMEOUT = $opt_t || 30; @failures = (); foreach $host (@ARGV) { if (! &mupdateGET($host, $PORT)) { push (@failures, $host); } } if (@failures == 0) { exit 0; } print join (" ", sort @failures), "\n\n", join ("\n", @longerr), "\n"; exit 1; sub mupdateGET { use Socket; use Sys::Hostname; my($Server, $Port) = @_; my($ServerOK, $TheContent); $ServerOK = 0; $TheContent = ''; $Path = '/'; ############################################################### eval { local $SIG{ALRM} = sub { die "Timeout Alarm" }; alarm $TIMEOUT; $result = &OpenSocket($Server, $Port); # Open a connection to the server if ($result == 0) { # Failure to open the socket push @longerr, "$Server: Unable to connect"; return ''; } my $error = 0; $in = ; if ($in !~ /^\* AUTH/) { $error = 1; } else { $in = ; while ($in !~ /^\* OK MUPDATE/) { $in = ; } } if($error) { alarm 0; push @longerr, "$Server: No MUPDATE banner received"; return 0; } print S "L LOGOUT\r\n"; while (defined($in=)) { if ($in =~ /^L OK/) { $ServerOK = 1; last; } } if (!$ServerOK) { push @longerr, "$Server: No response to logout"; } close(S); alarm 0; # Cancel the alarm }; if ($EVAL_ERROR and ($EVAL_ERROR =~ /^Timeout Alarm/)) { push @longerr, "$Server: **** Time Out\n"; return 0; } elsif ($EVAL_ERROR) { push @longerr, "$Server: $EVAL_ERROR"; return 0; } return $ServerOK; } sub OpenSocket { # # Make a Berkeley socket connection between this program and a TCP port # on another (or this) host. Port can be a number or a named service # local($OtherHostname, $Port) = @_; local($OurHostname, $sockaddr, $name, $aliases, $proto, $type, $len, $ThisAddr, $that); $OurHostname = &hostname; ($name, $aliases, $proto) = getprotobyname('tcp'); ($name, $aliases, $Port) = getservbyname($Port, 'tcp') unless $Port =~ /^\d+$/; ($name, $aliases, $type, $len, $ThisAddr) = gethostbyname($OurHostname); ($name, $aliases, $type, $len, $OtherHostAddr) = gethostbyname($OtherHostname); my $that = sockaddr_in ($Port, $OtherHostAddr); $result = socket(S, &PF_INET, &SOCK_STREAM, $proto) || return undef; $result = connect(S, $that) || return undef; select(S); $| = 1; select(STDOUT); # set S to be un-buffered return 1; # success } mon-contrib-1.0+dfsg/monitors/dhcp/000077500000000000000000000000001160532374600173175ustar00rootroot00000000000000mon-contrib-1.0+dfsg/monitors/dhcp/dhcp.monitor000066400000000000000000000066031160532374600216530ustar00rootroot00000000000000#!/usr/bin/perl -w # verify that a DHCP server is operating. # # usage: dhcp.monitor [host ...] # # Uses Net::DHCP::Watch to send a DHCP inform message to each of the servers # listed on the command line, and then waits up to 30 seconds for a response. # # The script will determine your mon server's mac address and IP by parsing the # output of 'ifconfig eth0'. You may need to modify that logic for your # operating system. # # Depending on your OS, you may need to have your mon server *not* be using DHCP # for its own interface management, as some DHCP implementations will bind the # DHCP port and refuse to allow Net::DHCP:Watch to generate and receive its own # requests. # Copyright (c) 2002 Carnegie Mellon University. All rights reserved. # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions are met: # # 1. Redistributions of source code must retain the above copyright notice, # this list of conditions and the following disclaimer. # # 2. Redistributions in binary form must reproduce the above copyright notice, # this list of conditions and the following disclaimer in the # documentation and/or other materials provided with the distribution. # # 3. The name "Carnegie Mellon University" must not be used to endorse or # promote products derived from this software without prior written # permission. For permission or any legal details, please contact: # Office of Technology Transfer # Carnegie Mellon University # 5000 Forbes Avenue # Pittsburgh, PA 15213-3890 # (412) 268-4387, fax: (412) 268-7395 # tech-transfer@andrew.cmu.edu # # 4. Redistributions of any form whatsoever must retain the following # acknowledgment: "This product includes software developed by Computing # Services at Carnegie Mellon University (http://www.cmu.edu/computing/)." # # CARNEGIE MELLON UNIVERSITY DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS # SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, # IN NO EVENT SHALL CARNEGIE MELLON UNIVERSITY BE LIABLE FOR ANY SPECIAL, # INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM # LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE # OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR # PERFORMANCE OF THIS SOFTWARE. use Net::DHCP::Watch; $Client = qx[ /sbin/ifconfig eth0 | /bin/sed 's/:/ /' | /bin/grep "inet addr" | /bin/awk '{print \$3}' ]; chomp($Client); $Ether = qx[ /sbin/ifconfig eth0 | /bin/grep HWaddr | /bin/awk '{print \$5}']; chomp($Ether); foreach $host (@ARGV) { eval { my $dhcpw = new Net::DHCP::Watch({ client => $Client, server => $host, ether => $Ether, timeout => 30, }); my $success = 0; foreach (1..3) { $dhcpw->watch(); my $s = $dhcpw->status(); if ($s->{Ok}) { $success = 1; last; } $dhcpw->unwatch(); } if (!$success) { push @failures, $host; push @longerr, "$host: DHCP INFORM request failed"; } }; if ($EVAL_ERROR && ($EVAL_ERROR =~ /Timeout/ )) { push @failures, $host; push @longerr, "$host: Request timed out."; } elsif ($EVAL_ERROR) { push @longerr, "$host: $EVAL_ERROR"; push @failures, $host; } } if (!@failures) { exit 0; } print join(" ", @failures),"\n"; print join("\n", @longerr), "\n"; exit scalar @failures; mon-contrib-1.0+dfsg/monitors/dhcp/dhcp.monitor.README000077500000000000000000000012511160532374600226040ustar00rootroot00000000000000# This script will verify that a DHCP server is operating. # # usage: dhcp.monitor [host ...] # # Uses Net::DHCP::Watch to send a DHCP inform message to each of the servers # listed on the command line, and then waits up to 30 seconds for a response. # # The script will determine your mon server's mac address and IP by parsing the # output of 'ifconfig eth0'. You may need to modify that logic for your # operating system. # # Depending on your OS, you may need to have your mon server *not* be using DHCP # for its own interface management, as some DHCP implementations will bind the # DHCP port and refuse to allow Net::DHCP:Watch to generate and receive its own # requests. mon-contrib-1.0+dfsg/monitors/diskspace/000077500000000000000000000000001160532374600203475ustar00rootroot00000000000000mon-contrib-1.0+dfsg/monitors/diskspace/netsnmp-freespace/000077500000000000000000000000001160532374600237665ustar00rootroot00000000000000mon-contrib-1.0+dfsg/monitors/diskspace/netsnmp-freespace/netsnmp-freespace.monitor000077500000000000000000000062101160532374600310200ustar00rootroot00000000000000#!/usr/bin/perl # # Monitor diskspace via SNMP # (based on process.monitor by Brian Moore) # # Arguments are: # # [-c community] host [host ...] # # This script will exit with value 1 if host:community has dskErrorFlag # set. The summary output line will be the host names that failed # and the disk information. The detail lines are what UCD snmp returns # for an dskErrMessage. ('/filesystem: less than WATERMARK free (= CURRENT)'). # If there is an SNMP error (either a problem with the SNMP libraries, # or a problem communicating via SNMP with the destination host), # this script will exit with a warning value of 2. # # There probably should be a better way to specify a given filesystem to # watch instead of everything-ucd-snmp-is-watching. # # $Id: netsnmp-freespace.monitor,v 1.2 2005/03/18 19:25:27 trockij Exp $ # # # Copyright (C) 2001 SATOH Fumiyasu # # 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; either version 2 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA # use SNMP; use Getopt::Std; $ENV{'MIBS'} = "UCD-SNMP-MIB"; getopts("c:"); $community = $opt_c || $ENV{'COMMUNITY'} || 'public'; $RETVAL = 0; foreach $host (@ARGV) { $session = new SNMP::Session(DestHost => $host, Community => $community); if (!defined ($session)) { $RETVAL = ($RETVAL == 1) ? 1 : 2; push @failures, "$host session error"; push @longerr, "$host could not get SNMP session"; next; } my $v = new SNMP::Varbind (["dskIndex"]); $session->getnext ($v); while (!$session->{"ErrorStr"} && $v->tag eq "dskIndex") { my @q = $session->get ([ ["dskPath", $v->iid], # 0 ["dskDevice", $v->iid], # 1 ["dskMinimum", $v->iid], # 2 ["dskMinPercent", $v->iid], # 3 ["dskTotal", $v->iid], # 4 ["dskAvail", $v->iid], # 5 ["dskUsed", $v->iid], # 6 ["dskPercent", $v->iid], # 7 ["dskPercentNode", $v->iid],# 8 ["dskErrorFlag", $v->iid], # 9 ["dskErrorMsg", $v->iid], # 10 ]); last if ($session->{"ErrorStr"}); if ($q[9] > 0) { $RETVAL = 1; my ($t, $u, $a) = map { int($_/1024) } @q[4, 6, 5]; push (@failures, $host); push (@longerr, "$host:$q[0]($q[1]) total=$t used=$u($q[7]%) free=$a err=$q[10]"); } $session->getnext ($v); } if ($session->{"ErrorStr"}) { push (@failures, $host); push (@longerr, "$host returned an SNMP error: " . $session->{"ErrorStr"}); } } if (@failures) { print join (", ", @failures), "\n", "\n"; print join ("\n", @longerr), "\n"; } exit $RETVAL; mon-contrib-1.0+dfsg/monitors/diskspace/netsnmp-freespace/netsnmp-freespace.monitor.README000066400000000000000000000014551160532374600317570ustar00rootroot00000000000000Date: Thu, 21 Jun 2001 05:46:47 +0900 From: SATOH Fumiyasu To: trockij@transmeta.com Subject: freespace-snmp.monitor Hi, ``mon'' developper. I wrote freespace-snmp.monitor based on process.monitor for mon. This monitors disk space via SNMP (NET-SNMP, aka UCD-SNMP). I want to commit this monitor to mon archive. Any comments? If you think that ``freespace-snmp'' is not suitable name, please name this monitor as you wish :-). -- SATOH Fumiyasu - fumiya @net-thrust.com, @samba.gr.jp, @namazu.org or ... THRUST Co., Ltd. @ Fujisawa, Kanagawa, Japan - http://www.net-thrust.com Samba-JP, aka `Samba Users Group Japan' - http://www.samba.gr.jp Apache-JP(?), aka `Japan Apache Users Group' - http://www.apache.or.jp Namazu, a full-text search engine - http://www.namazu.org mon-contrib-1.0+dfsg/monitors/diskspace/storage.monitor-1.0.0/000077500000000000000000000000001160532374600241335ustar00rootroot00000000000000mon-contrib-1.0+dfsg/monitors/diskspace/storage.monitor-1.0.0/storage.cf000066400000000000000000000015721160532374600261160ustar00rootroot00000000000000# # storage.cf - configuration file for storage.monitor # # format: # # host fsname free # # host hostname to be queried, should correspond with # a host defined in the host group # # fsname The name of the file system to check, e.g. "/var" # Use + instead of space (e.g. Swap+Space) # # free The amount of free space which will trigger a failure, # expressed as "10kb", "10MB", or "10GB" # hermes / 50MB hermes /boot 5MB hermes /usr 100MB hermes /home 200MB hermes /opt 100MB hermes /var 200MB hermes /var/opt/openmail/data 200MB hermes Swap+Space 10MB xns1 / 50MB xns1 /home 100MB xns1 /usr 100MB xns1 /var 100MB xns1 /var/spool 200MB xns1 Swap+Space 10MB ns01 / 50MB ns01 /home 100MB ns01 /var 100MB ns01 Swap+Space 10MB ns02 / 50MB ns02 /home 100MB ns02 /var 100MB ns02 Swap+Space 10MB mon-contrib-1.0+dfsg/monitors/diskspace/storage.monitor-1.0.0/storage.monitor000077500000000000000000000112461160532374600272170ustar00rootroot00000000000000#!/usr/bin/perl # # storage.monitor # # Use SNMP to get free disk space from a machine that implements HOSTMIB. # # Exits with value of 1 if free space on any host drops below # the configured value, or exits with the value of 2 if # there is a "soft" error (SNMP library error, or could not get a # response from the server). # # Requirements: # # Requires the UCD SNMP library and G.S. Marzot's Perl SNMP module. # (Avoid UCSD SNMP 3.6.1, it will cause segfaults. Use 3.6.2+) # # Written by Peter Holzleitner # based heavily on netappfree.monitor by Jim Trocki # # Copyright (C) 2000, Peter Holzleitner # Copyright (C) 1998, Jim Trocki # # 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; either version 2 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA # # Version 1.0.0 # # use SNMP; use Getopt::Long; sub readcf; sub toKB; # load only the necessary MIBs: $ENV{"MIBS"} = 'RFC1213-MIB:HOST-RESOURCES-MIB'; GetOptions (\%opt, "community=s", "timeout=i", "retries=i", "config=s", "list"); die "no host arguments\n" if (@ARGV == 0); $RET = 0; @ERRS = (); @HOSTS = (); $COMM = $opt{"community"} || "public"; $TIMEOUT = $opt{"timeout"} * 1000 * 1000 || 5000000; $RETRIES = $opt{"retries"} || 8; $CONFIG = $opt{"config"} || (-d "/etc/mon" ? "/etc/mon" : "/usr/lib/mon/etc") . "/storage.cf"; $list = $opt{"list"}; ($stDescr, $stUnit, $stSize, $stUsed) = (0..3); $host = ''; $fsname = ''; $sizeK = 0; $freeK = 0; $OK = 0; readcf ($CONFIG) || die "could not read config: $!\n"; foreach $host (@ARGV) { next if (!defined $FREE{$host}); if (!defined($s = new SNMP::Session (DestHost => $host, Timeout => $TIMEOUT, Community => $COMM, Retries => $RETRIES))) { $RET = ($RET == 1) ? 1 : 2; push (@HOSTS, $host); push (@ERRS, "could not create session to $host: " . $SNMP::Session::ErrorStr); next; } $v = new SNMP::VarList ( ['hrStorageDescr'], # ['hrStorageAllocationUnits'], # ['hrStorageSize'], # ['hrStorageUsed'], ); while (defined $s->getnext($v)) { last if ($v->[$stDescr]->tag !~ /hrStorageDescr/); #($stDescr, $stUnit, $stSize, $stUsed) = (0..3); $fsname = $v->[$stDescr]->val; $unit = $v->[$stUnit]->val; $size = $v->[$stSize]->val; $used = $v->[$stUsed]->val; $freeK = ($size - $used) * $unit / 1024; $OK = "(n/conf)"; $needfreeK = $FREE{$host}{$fsname}; if ( $needfreeK ) { $OK = "OK"; if ( $freeK < $needfreeK ) { push (@HOSTS, $host); push (@ERRS, sprintf ("%s:%s: %1.1fMB free", $host, $fsname, $freeK)); $OK = "LOW"; $RET = 1; } } if($list) { $sizeK = $size * $unit / 1024; write; } } # while(getnext()) if ($s->{ErrorNum}) { push (@HOSTS, $host); push (@ERRS, "could not get hrStorageDescr for $host: " . $s->{ErrorStr}); $RET = ($RET == 1) ? 1 : 2; } } if(!$list) { if ($RET) { print "@HOSTS\n"; print "\n"; print join("\n", @ERRS), "\n"; } } # foreach(host) exit $RET; # # read configuration file # sub readcf { my ($f) = @_; my ($l, $host, $filesys, $free); open (CF, $f) || return undef; while () { next if (/^\s*#/ || /^\s*$/); chomp; ($host, $filesys, $free) = split; $filesys =~ tr/+/ /; # + replaces space in config files if (!defined ($FREE{$host}{$filesys} = toKB ($free))) { die "error free specification, config $f, line $.\n"; } } close (CF); } sub toKB { my ($free) = @_; my ($n, $u); if ($free =~ /^(\d+\.\d+)(kb|mb|gb)$/i) { ($n, $u) = ($1, "\L$2"); } elsif ($free =~ /^(\d+)(kb|mb|gb)$/i) { ($n, $u) = ($1, "\L$2"); } else { return undef; } return (int ($n * 1024)) if ($u eq "mb"); return (int ($n * 1024 * 1024)) if ($u eq "gb"); int ($n); } format STDOUT_TOP = Host File System KB total KB free OK ---------------------------------------------------------------------------- . format STDOUT = @<<<<<<<<<<<<<< @<<<<<<<<<<<<<<<<<<<< @>>>>>>>>>> @>>>>>>>>>> @<<<<<<< $host, $fsname, $sizeK, $freeK, $OK . mon-contrib-1.0+dfsg/monitors/diskspace/storage.monitor-1.0.0/storage.monitor-1.0.0.tar.README000066400000000000000000000011011160532374600313540ustar00rootroot00000000000000Subject: CONTRIB: storage monitor for HOSTMIB Date: Tue, 13 Jun 2000 19:08:59 +0200 From: P.Holzleitner@unido.org (Peter HOLZLEITNER) To: mon@linux.kernel.org The attached storage.monitor will work with anything that implements hrStorageTable (Host Resources MIB), e.g. the UCSD snmpd. Sample configuration file included. Start by making at least one entry in storage.cf for every host you want to monitor, then run it manually with the list option to see what it does, e.g. ./storage.monitor -l ns01 ns02 mon-contrib-1.0+dfsg/monitors/dnsbl/000077500000000000000000000000001160532374600175035ustar00rootroot00000000000000mon-contrib-1.0+dfsg/monitors/dnsbl/rbl.monitor000077500000000000000000000063451160532374600217060ustar00rootroot00000000000000#!/usr/bin/perl # # rbl.monitor - check RBL blacklists for an IP address. Uses asynch I/O # to send all the requests simultaneously # # Based on original work by Tim Haynes, re-written by Ed Ravin to # use asynchronous I/O. # # $Id: rbl.monitor,v 1.3 2010/05/22 12:35:23 trockij Exp $ # my $usage="\ Usage: rbl.monitor [options] hostname [...] Options [and default values]: --listfile [preset list, see script] --rbllist --timeout [60 seconds] --debug [off] "; use strict; use Net::DNS; use IO::Select; use Getopt::Long; my %opt; GetOptions(\%opt, "listfile=s", "rbllist=s", "timeout=i", "debug", ) or die $usage; my $listfile= $opt{listfile} || ""; my $rbllist= $opt{rbllist} || ""; my $selecttimeout = 5; my $timeout= ($opt{timeout} || 60) + ($selecttimeout * 2); my $debug= $opt{debug} || 0; # Default RBLs to check - just a few of the lists most likely to block mail # Sites with specific needs should customize via the command line my @rbls2check=( "bl.spamcop.net", "relays.mail-abuse.org", "zen.spamhaus.org", "dnsbl.sorbs.net", "dnsbl-1.uceprotect.net", ); if ($listfile) { open(LIST, "< $listfile") || die "$0: cannot open list file \"$listfile\": $!\n"; @rbls2check= grep !/^\s*#/, ; @rbls2check= grep !/^\s*$/, @rbls2check; map {chomp} @rbls2check; close LIST; die "$0: no RBL names found in \"$listfile\"\n" unless @rbls2check; } if ($rbllist) { @rbls2check= split(',', $rbllist); } print "*** checking these RBLs:\n " . join("\n ", @rbls2check) . "\n" if $debug; my (@summary, @detail); my @sockets; my $res = Net::DNS::Resolver->new; my $sel = IO::Select->new(); my $starttime= time; my %hostpart2host; # gethostbyname is non-reentrant, so do all the queries up front foreach my $host (@ARGV) { my $hostdata= gethostbyname($host); if (!defined($hostdata)) { push @summary, $host; push @detail, "$host: bad hostname"; next; } my $hostpart= join(".", reverse(unpack("C4", $hostdata))); $hostpart2host{$hostpart}= $host; } # start all the queries foreach my $hostpart (keys %hostpart2host) { foreach my $rbl (@rbls2check) { my $dnssock= $res->bgsend(join(".", $hostpart, $rbl)); push @sockets, $dnssock; $sel->add($dnssock); } } MAINLOOP: while ($sel->handles > 0) { my @ready = $sel->can_read($selecttimeout); if ( (time - $starttime) > $timeout) { # waited too long? push @detail, "TIMEOUT: " . scalar($sel->handles) . " responses still pending"; last MAINLOOP; } foreach my $sock (@ready) { my ($authority, $ipaddress, $hostpart, $host); my $packet = $res->bgread($sock); foreach my $rr ($packet->answer) { if ($rr->type eq "A") { $ipaddress= $rr->address; $authority= $rr->name; if ($authority=~ /^(\d+\.\d+\.\d+\.\d+)\./) { $hostpart= $1; $host= $hostpart2host{$hostpart}; } else { $host= "???" } push @summary, $host unless grep /^$host$/, @summary; push @detail, "$host: $authority: " . $rr->address; } } $sel->remove($sock); } } print join(" ", (sort @summary)) if (@summary); print "\n"; print join("\n", (sort @detail)), "\n" if @detail; exit 1 if @summary; exit 0; mon-contrib-1.0+dfsg/monitors/file/000077500000000000000000000000001160532374600173205ustar00rootroot00000000000000mon-contrib-1.0+dfsg/monitors/file/dir_file_age/000077500000000000000000000000001160532374600217115ustar00rootroot00000000000000mon-contrib-1.0+dfsg/monitors/file/dir_file_age/dir_file_age.monitor000077500000000000000000000031231160532374600257150ustar00rootroot00000000000000#!/usr/local/bin/perl # # mon monitor to watch for "old" files in one or more directories # original use was to monitor DNS zone transfers, # but there is nothing DNS specific here except that the directory # is removed from the failure list leaving only the file (zone) name # # Jon Meek, originally 25-Dec-2000 $RCSid = q{$Id: dir_file_age.monitor,v 1.1.1.1 2005/02/18 17:52:22 trockij Exp $}; use Getopt::Long; use File::Find; GetOptions( "d" => \$opt_d, # Debug/test flag "T=f" => \$MaxAge, # Maximum age in days, default is one day ); @Failures = (); @Dirs = @ARGV; # Directory names are left on the command line after Getopt $MaxAge = 1 unless $MaxAge; foreach $d (@Dirs) { $CurrentDir = $d; print "Directory: $d\n" if $opt_d; find(\&wanted, $d); foreach $f (sort {$Age{$b} <=> $Age{$a}} keys %Age) { print "dbg: $f $Age{$f}\n" if $opt_d; if ($Age{$f} > $MaxAge) { push(@Failures, $f); } } undef %Size; # Initialize for next directory in list } if (@Failures == 0) { # No "old" files, all is OK exit 0; } print "@Failures\n"; foreach $f (@Failures) { printf "%s %0.1fd\n", $f, $Age{$f}; } print "\n"; exit 1; sub wanted { my ($rdfile); $rdfile = $File::Find::name; return if (-d $rdfile); # Skip directories return if (-l $rdfile); # Skip symbolic links, for now $age = -M $rdfile; $size = -s $rdfile; $rdfile =~ s/^$CurrentDir\///; # Remove base directory, may need to be optional $Age{$rdfile} = $age; $Size{$rdfile} = $size; # Used to track the files, will be undef'ed between dirs # $FileCount++; } mon-contrib-1.0+dfsg/monitors/file/dir_file_age/dir_file_age.monitor.README000077500000000000000000000014711160532374600266550ustar00rootroot00000000000000Date: Wed, 17 Oct 2001 12:40:37 -0400 (EDT) From: Jon Meek To: xxxxxxxxx cc: Subject: Re: Monitoring file changes at certain times of the day Well, this is still not exactly what you want, but I can send it if you wish. I think that I did not release it yet due to the sparse documentation. dir_file_age.monitor # mon monitor to watch for "old" files in one or more directories # original use was to monitor DNS zone transfers, # but there is nothing DNS specific here except that the directory # is removed from the failure list leaving only the file (zone) name "d" => \$opt_d, # Debug/test flag "T=f" => \$MaxAge, # Maximum age in days, default is one day # Fractional days ok What the heck, it's small, so I am attaching it. Jon mon-contrib-1.0+dfsg/monitors/flexlm/000077500000000000000000000000001160532374600176705ustar00rootroot00000000000000mon-contrib-1.0+dfsg/monitors/flexlm/flexlm.monitor000066400000000000000000000047521160532374600226000ustar00rootroot00000000000000#!/usr/bin/perl # # Use try to connect to a http server. # For use with "mon". # # Arguments are "port@host [port@host...]" # # Requires lmstat (you can get it from http://www.flexlm.com/) # # Adapted from "nis.monitor" by # Juha Ylitalo # # nis.monitor written by me # # Copyright (C) 1999, Juha Ylitalo # # 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; either version 2 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA # use Getopt::Std; use English; getopts ("t:"); $LMSTAT = "/usr/local/bin/lmstat -a -c "; $TIMEOUT = $opt_t || 30; @failures = (); @report = (); foreach $lmfile ( @ARGV ) { &flexlm_poll( $lmfile ); } if (@failures == 0) { exit 0; } print "@failures\n"; print "@report"; exit 1; sub flexlm_poll { my ( $lmfile ) = @_; my( $ServerOK ); ############################################################### eval { local $SIG{ALRM} = sub { die "Timeout Alarm" }; alarm $TIMEOUT; $ServerOK = -1; @lines = `$LMSTAT $lmfile`; foreach $line ( @lines ) { # print "$line\n"; if ( $line =~ /: UP/ && $ServerOK == -1 ) { $ServerOK = 1; } elsif ( $line =~ /: DOWN/ || $line =~ /\(Total of 0 licenses available\)/ || $line =~ /daemon is down/ || $line =~ /unsupported by licensed server/ ) { $ServerOK = 0; $line =~ s/[ \t]+/ /g; push @report , "$line"; } } if ( $ServerOK == -1 ) { push @report , "No response from server."; $ServerOK = 0; } if ( $ServerOK == 0 ) { push @failures , $lmfile; } alarm 0; # Cancel the alarm }; if ($EVAL_ERROR and ($EVAL_ERROR eq 'Timeout Alarm')) { push @failures , "**** Time Out\n"; } return @failures; }mon-contrib-1.0+dfsg/monitors/flexlm/flexlm.monitor.README000066400000000000000000000003601160532374600235230ustar00rootroot00000000000000# # Use try to connect to a http server. # For use with "mon". # # Arguments are "port@host [port@host...]" # # Requires lmstat (you can get it from http://www.flexlm.com/) # # Adapted from "nis.monitor" by # Juha Ylitalo mon-contrib-1.0+dfsg/monitors/ftp/000077500000000000000000000000001160532374600171725ustar00rootroot00000000000000mon-contrib-1.0+dfsg/monitors/ftp/ftps/000077500000000000000000000000001160532374600201465ustar00rootroot00000000000000mon-contrib-1.0+dfsg/monitors/ftp/ftps/ftps.monitor000066400000000000000000000050171160532374600225360ustar00rootroot00000000000000#!/usr/bin/perl # # Use try to connect to a FTP/SSL server, and # wait for the right output. # # For use with "mon". # # Arguments are "[-p port] [-u user] [-s password] [-e I|E] [-t timeout] host [host...]" # # -p port TCP port to connect to (defaults to 21) # -u user user to login (defaults to ftp) # -s password password to login (defaults to ftpssl@mon.invalid) # -e I|E is for Implicit or Explicit encryption # -t secs timeout, defaults to 30 # # Adapted from "ftp.monitor" by Pierre-Emmanuel Andre # # Copyright (C) 2008, Pierre-Emmanuel Andre # # 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; either version 2 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA # # $Id: ftps.monitor,v 1.1 2008/08/01 17:02:19 aschwer Exp $ use Getopt::Std; use Net::FTPSSL; #Get arguments getopts ("p:u:s:e:t:"); $PORT = $opt_p || 21; $USER = $opt_u || 'ftp' ; $PASSWORD = $opt_s || 'ftpssl@mon.invalid' ; $ENCRYPTION = $opt_e || 'E' ; $TIMEOUT = $opt_t || 30; my %good; my %bad; # Start loop foreach my $host (@ARGV) { my $result = ftpGET ($host, $PORT); if (!$result->{"ok"}) { $bad{$host} = $result; } else { $good{$host} = $result; } } # No bad -> exit with success if (keys %bad == 0) { exit 0; } # Else print errors print join (" ", sort keys %bad), "\n"; foreach my $h (keys %bad) { print "HOST $h: " . $bad{$h}->{"error"}, "\n"; } exit 1; # Function to connect on FTP/SSL server sub ftpGET { my ($server,$port) = @_ ; #Open connexion my $ftps = Net::FTPSSL->new($server, Port => $port, Encryption => $ENCRYPTION, Timeout => $TIMEOUT, Debug => 0 ) or return { "ok" => 0, "error" => $ftps->last_message, }; #Login $ftps->login($USER,$PASSWORD) or return { "ok" => 0, "error" => $ftps->last_message, }; #Quit $ftps->quit() ; #No error return { "ok" => 1, "error" => undef, }; } mon-contrib-1.0+dfsg/monitors/http/000077500000000000000000000000001160532374600173605ustar00rootroot00000000000000mon-contrib-1.0+dfsg/monitors/http/http_integrity/000077500000000000000000000000001160532374600224355ustar00rootroot00000000000000mon-contrib-1.0+dfsg/monitors/http/http_integrity/http_integrity.monitor000077500000000000000000000144711160532374600271350ustar00rootroot00000000000000#!/usr/local/bin/perl # # NAME # http_integrity.monitor # # # SYNOPSIS # http_integrity.monitor [-u url] [-n num_threads] [-a anchor_tag_types] # [-t link_timeout] [-T page_timeout] host... # # # DESCRIPTION # Use try to connect to a http server and verify the integrity of the # page and objects within that page (e.g. to make sure that there are # no broken images). # # For use with "mon". # # # EXAMPLES # ./http_integrity.monitor -u "/index.html" host1 host2 host3 # # # OPTIONS # -u URL path to retrieve from each host. # # -s Use SSL to connect to the host. # # -n Max number of requests to issue at one time. Defaults to 8. # Increasing this number may produce faster load times, depending # on the performance of the site and the speed of the link. # Decreasing this number may produce slower load times, again, # depending on the performance of the site and the speed of the link. # Experiment to find what works best for you. # # -t Timeout, in seconds, to wait for data when downloading any given # link. Must be an integer. # # -T Timeout, in seconds, to issue an error for if the time to load # the page, plus any associated images/applets/etc., exceeds this # number. Can be a floating point number. # # -a Types of anchor tag items to retrieve, in a space separated quoted # list. Default is "img applet". Case matters. # # # AUTHOR # Andrew Ryan # $Id: http_integrity.monitor,v 1.1.1.1 2005/02/18 17:52:24 trockij Exp $ # # # COPYRIGHT # Copyright (C) 2000, Andrew Ryan # # 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; either version 2 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA # use strict; use English; use LWP::Parallel::UserAgent; use LWP::UserAgent; use HTML::LinkExtor; use URI::URL; use Time::HiRes qw( gettimeofday tv_interval ); use Getopt::Std; use vars qw/$opt_s $opt_u $opt_n $opt_t $opt_a $opt_T/; getopts ("su:n:t:a:t:T:"); my $url_path = $opt_u || "/"; #default URL path to test is "/" my $max_req = $opt_n || 16; #maximum number of requests to issue at one time my $page_timeout = $opt_T || 10; #timeout, in seconds, for whole page my $item_timeout = $opt_t || int($page_timeout/2); #timeout, in seconds, for any given item my $opt_s = "s" if $opt_s ; my @retrieve_anchors = $opt_a ? split(' ', $opt_a) : ("img","applet"); my @failures = (); my @details = (); my ($host, $p, $url, $tag, %attr, %saw, @addl_links, $base, $res, $req, $entries); my ($total_time, $time_begin, $time_end, $t0, $t1); my ($res_bytes, $total_bytes); my $ua = new LWP::UserAgent; $ua->timeout ($item_timeout); # timeout, in seconds, for base page my $pua = LWP::Parallel::UserAgent->new(); $pua->max_req ($max_req); $pua->timeout ($item_timeout); # timeout, in seconds, for any given request my $exit_status = 0; #default exit status is OK foreach $host (@ARGV) { # Set up a callback that collect image links @addl_links = (); $total_time = 0; $url = "http$opt_s://${host}${url_path}"; # Make the parser. Unfortunately, we don't know the base yet # (it might be diffent from $url) $p = HTML::LinkExtor->new(\&callback); # Request document and parse it as it arrives $t0 = [Time::HiRes::gettimeofday]; $res = $ua->request( HTTP::Request->new(GET => $url) ,sub {$p->parse($_[0])}); $t1 = [Time::HiRes::gettimeofday]; $total_time += Time::HiRes::tv_interval($t0, $t1); if ($res->is_error) { push (@failures, $host); if ( $res->code == 408 ) { push(@details, sprintf("ERROR: Timeout [%s seconds] retrieving %s", $item_timeout, $res->request->url ) ) if $res->is_error; } else { push(@details, sprintf("ERROR: %s [%s] retrieving %s", $res->code, $res->message, $res->request->url ) ) if $res->is_error; } $exit_status++; next; } # Expand all image URLs to absolute ones $base = $res->base; @addl_links = map { $_ = url($_, $base)->abs; } @addl_links; $res_bytes = length($res->as_string); $total_bytes += $res_bytes; # uniq the array of addl_links undef %saw; @saw{@addl_links} = (); @addl_links = keys %saw; foreach (@addl_links) { next if /^https/i; #we don't do https here $req = HTTP::Request->new('GET', "$_"); if ( $res = $pua->register ($req) ) { push(@details, sprintf("ERROR: %s", $res->error_as_HTML) ); $exit_status++; } } $t0 = [Time::HiRes::gettimeofday]; $entries = $pua->wait(); #now retrieve everything $t1 = [Time::HiRes::gettimeofday]; $total_time += Time::HiRes::tv_interval($t0, $t1); foreach (keys %$entries) { $res = $entries->{$_}->response; $res_bytes = length($res->content); $total_bytes += $res_bytes; $exit_status++ if $res->is_error; if ( $res->code == 408 ) { push(@details, sprintf("ERROR: Timeout [%s seconds] retrieving %s", $item_timeout, $res->request->url ) ) if $res->is_error; } else { push(@details, sprintf("ERROR: %s [%s] retrieving %s", $res->code, $res->message, $res->request->url ) ) if $res->is_error; } } if ($total_time > $page_timeout) { push (@failures, $host) ; push (@details, sprintf("ERROR: $url took %.2f seconds for complete load (>%.1f seconds)", $total_time, $page_timeout) ); next; } if ($exit_status > 0) { push (@failures, $host) ; push(@details, sprintf("%s total bytes received in %s objects in %.2f seconds (%.2f bytes/sec)",$total_bytes, scalar(@addl_links)+1, $total_time, $total_bytes/$total_time) ) ; } } if (@failures == 0) { exit 0; } print "@failures\n"; print join("\n", @details); exit $exit_status; sub callback { my($tag, %attr) = @_; foreach (@retrieve_anchors) { push(@addl_links, values %attr) if $tag eq $_; } } mon-contrib-1.0+dfsg/monitors/http/http_integrity/http_integrity.monitor.README000066400000000000000000000025441160532374600300640ustar00rootroot00000000000000# # NAME # http_integrity.monitor # # # SYNOPSIS # http_integrity.monitor [-u url] [-n num_threads] [-a anchor_tag_types] # [-t link_timeout] [-T page_timeout] host... # # # DESCRIPTION # Use try to connect to a http server and verify the integrity of the # page and objects within that page (e.g. to make sure that there are # no broken images). # # For use with "mon". # # # EXAMPLES # ./http_integrity.monitor -u "/index.html" host1 host2 host3 # # # OPTIONS # -u URL path to retrieve from each host. # # -s Use SSL to connect to the host. # # -n Max number of requests to issue at one time. Defaults to 8. # Increasing this number may produce faster load times, depending # on the performance of the site and the speed of the link. # Decreasing this number may produce slower load times, again, # depending on the performance of the site and the speed of the link. # Experiment to find what works best for you. # # -t Timeout, in seconds, to wait for data when downloading any given # link. Must be an integer. # # -T Timeout, in seconds, to issue an error for if the time to load # the page, plus any associated images/applets/etc., exceeds this # number. Can be a floating point number. # # -a Types of anchor tag items to retrieve, in a space separated quoted # list. Default is "img applet". Case matters. mon-contrib-1.0+dfsg/monitors/http/lwp-http/000077500000000000000000000000001160532374600211375ustar00rootroot00000000000000mon-contrib-1.0+dfsg/monitors/http/lwp-http/lwp-http.mon000066400000000000000000000066421160532374600234410ustar00rootroot00000000000000#!/usr/local/bin/perl # File: lwp-http.mon # Author: Daniel Hagerty, hag@linnaean.org # Date: Sun Mar 19 22:06:02 2000 # Description: Perform a simple top level HTTP get using LWP. # Lots of options. # # $Id: lwp-http.mon,v 1.1.1.1 2005/02/18 17:52:24 trockij Exp $ use strict; use LWP::UserAgent; use HTTP::Cookies; use HTTP::Request; use Getopt::Std; use File::Basename; use URI; ### use vars qw($opt_h $opt_p $opt_t $opt_z $opt_d $opt_r $opt_s $opt_P $opt_v $opt_c); ## # Configure this. my $maintainer = 'youremailhere@localhost'; ## my $port; my $directory; my $regex; my $proto = "http"; my $timeout = 60; my $version = "0.1"; my $agent = "Yet Another Monitor Bot/$version"; my $u_proto; ### sub main { do_usage() if(@_ == 0); $directory = $opt_d if($opt_d); $port = $opt_p if($opt_p); $timeout = $opt_t if($opt_t); $regex = $opt_r if($opt_r); $proto = "https" if ($opt_s); $proto = $opt_P if($opt_P); $directory =~ s/^\///; # Nuke leading slash $u_proto = $proto; $u_proto =~ tr/[a-z]/[A-Z]/; my $user_agent = LWP::UserAgent->new() || lose("LWP create failure"); $user_agent->agent($agent); $user_agent->from($maintainer); $user_agent->timeout($timeout); my @failed; my %failure; host: foreach my $host (@_) { my $ht_lose = sub { push(@failed, $host); $failure{$host} = join(" ", @_); # This generates a warning. next host; }; if($opt_c) { # Generate new cookies for each host. my $cookies = HTTP::Cookies->new() || &{$ht_lose}("HTTP::Cookies create failure"); $user_agent->cookie_jar($cookies); } # XXX Kludge around some wierness with generating our own # URI interacting with cookies. my $uri_str = "$proto://$host/$directory"; my $request = HTTP::Request->new("GET" => $uri_str) || &{$ht_lose}("HTTP::Request create failure"); my $uri = $request->uri(); $uri->port($port) if(defined($port)); my $response = $user_agent->request($request) || &{$ht_lose}("UserAgent request failure"); unless($response->is_success) { &{$ht_lose}("Request failed:", $response->message); } my $strref = $response->content_ref; if(!$opt_z && length($$strref) == 0) { &{$ht_lose}("Empty document"); } if(defined($regex)) { my $winning; map {$winning++ if(/$regex/);} split("\n", $$strref); if($opt_v) { &{$ht_lose}("Failure regex matches:", $winning) if($winning); } elsif(!$winning) { &{$ht_lose}("Regex not found"); } } } if(@failed) { print "$u_proto Failures: " . join(" ", @failed) . "\n"; foreach my $fail (@failed) { print "$fail: $failure{$fail}\n"; } exit(1); } exit; } sub lose { die join(" ", @_); } sub do_usage { my $extended = shift; my $base = basename $0; print STDERR "Usage: $base [options...] hosts ...\n"; if($extended) { print <<'EOF'; -h Help. You're reading it. -d URL URL to test on the remote host. Default is /. -p PORT Port to connect to. Default is proto specific. -P PROTO Protocol to fetch. Default is http. -s Fetch via https. Equivalent to -P https. -t TIMEOUT Timeout for the fetch. Default is 60 seconds. -r REGEX A regular expression that the retrieved content must match. -v Invert the regular expression. Content must NOT match. -z Supress zero-length check. -c Enable Cookies. EOF } exit 1; } ### getopts("hszvcp:t:d:r:P:") || do_usage(); do_usage($opt_h) if($opt_h); &main(@ARGV); # EOF mon-contrib-1.0+dfsg/monitors/http/lwp-http/lwp-http.mon.README000066400000000000000000000006671160532374600243760ustar00rootroot00000000000000Subject: yet another http/https monitor Date: Mon, 20 Mar 2000 21:39:13 -0500 From: Daniel Hagerty To: None of the http monitors did quite what I needed, and I didn't feel like doing much wheel reinventing. Uses LWP, so it gets lots of features with little work. Tested to be useful for http, https, and ftp. Hope it's useful. mon-contrib-1.0+dfsg/monitors/https/000077500000000000000000000000001160532374600175435ustar00rootroot00000000000000mon-contrib-1.0+dfsg/monitors/https/https/000077500000000000000000000000001160532374600207055ustar00rootroot00000000000000mon-contrib-1.0+dfsg/monitors/https/https/https.monitor000077500000000000000000000065331160532374600234720ustar00rootroot00000000000000#!/usr/bin/perl # # $Id: https.monitor,v 1.1.1.1 2005/02/18 17:52:23 trockij Exp $ # # An extremely simple https monitor for mon. # # Code structure based on Jon Meek & Jim Trocki's http.monitor program. # # https code taken from the get_page.pl function from the # Net::SSLeay distribution by Sampo Kellomaki # # It makes use of the Net::SSLeay library and the OpenSSL package # (www.openssl.org). # # To get around the problem that Net::SSLeay carps to STDERR # uncontrollably about a number of things (e.g. connection refused), # we get around this by running the actual ssl get as an escaped # perl program and dropping the stderr of that instance. Gross, but # strangely effective. # # Use the -v option if you actually want to see the full result and # all headers. You'd never use this from mon, since it provides # non-mon-compliant output, but it can be interesting from the command # line. # # # # Distribution and use of this program is under the same terms # as the OpenSSL package itself (i.e. free, but mandatory # attribution; NO WARRANTY). Please consult COPYRIGHT file in # the root of the SSLeay distribution. # use strict; use Socket; use Net::SSLeay qw(die_now die_if_ssl_error) ; use Getopt::Std; # use English; #Net::SSLeay::load_error_strings(); #Net::SSLeay::SSLeay_add_ssl_algorithms(); # Comment this out since on systems without a /dev/[u]random this # line causes an unneccesary carp which will confuse mon. # If you use Linux or BSD or other OS which supports a random device, # feel free to uncomment this line. #Net::SSLeay::randomize(); use vars qw($opt_p $opt_t $opt_u $opt_v); getopts ("vp:t:u:"); my $PORT = $opt_p || 443; my $TIMEOUT = $opt_t || 30; my $URL = $opt_u || "/"; my $perl = "/usr/bin/perl"; # where you keep perl my $field_delim = "<>"; # html field delimiter my @failures = (); my @detail = (); my ($host, $OK, $default_header, $auth_header, $end_header, $request_header, $msg); my ($dest_ip, $dest_serv, $sockaddr_template, $dest_serv_params, $ctx, $ssl, $res, $reply, $got, $ServerOK); foreach $host (@ARGV) { $OK = &httpsGET($host, $PORT, $URL); if (!defined ($OK) || $OK == 0) { push (@failures, $host); } } if (@failures == 0) { exit 0; } print "@failures\n"; print join(";",@detail); exit 1; # Main function begins here sub httpsGET { my ($site, $port, $path) = (@_); my $total_bytes = 0; #set total bytes transferred to 0 my ($page, $result, %headers); # print "attempting to contact site $site on port $port with path $path\n"; eval { local $SIG{ALRM} = sub { die "Timeout Alarm" }; alarm $TIMEOUT; $result = `$perl -e'use Net::SSLeay ; Net::SSLeay::SSLeay_add_ssl_algorithms() ; print join("$field_delim",Net::SSLeay::get_https("$site", "$port", "$path"))' 2>/dev/null`; alarm 0; #cancel the alarm ($page, $result, %headers) = split ("<>",$result); print "Result was `$result'\n" if $opt_v; foreach my $h (sort keys %headers) { print "Header `$h'\tvalue `$headers{$h}'\n" if $opt_v; } if ($result =~ /^HTTP\/([\d\.]+)\s+200\b/) { $ServerOK = 1; } else { $ServerOK = 0; push(@detail,"$result"); } }; if ($EVAL_ERROR and ($EVAL_ERROR eq 'Timeout Alarm')) { print "**** Time Out\n"; return 0; } return $ServerOK; } mon-contrib-1.0+dfsg/monitors/https/https/https.monitor.README000066400000000000000000000021761160532374600244220ustar00rootroot00000000000000# # $Id: https.monitor.README,v 1.1.1.1 2005/02/18 17:52:23 trockij Exp $ # # An extremely simple https monitor for mon. # # Code structure based on Jon Meek & Jim Trocki's http.monitor program. # # https code taken from the get_page.pl function from the # Net::SSLeay distribution by Sampo Kellomaki # # It makes use of the Net::SSLeay library and the OpenSSL package # (www.openssl.org). # # To get around the problem that Net::SSLeay carps to STDERR # uncontrollably about a number of things (e.g. connection refused), # we get around this by running the actual ssl get as an escaped # perl program and dropping the stderr of that instance. Gross, but # strangely effective. # # Use the -v option if you actually want to see the full result and # all headers. You'd never use this from mon, since it provides # non-mon-compliant output, but it can be interesting from the command # line. # # # # Distribution and use of this program is under the same terms # as the OpenSSL package itself (i.e. free, but mandatory # attribution; NO WARRANTY). Please consult COPYRIGHT file in # the root of the SSLeay distribution. mon-contrib-1.0+dfsg/monitors/icecast/000077500000000000000000000000001160532374600200145ustar00rootroot00000000000000mon-contrib-1.0+dfsg/monitors/icecast/icecast/000077500000000000000000000000001160532374600214275ustar00rootroot00000000000000mon-contrib-1.0+dfsg/monitors/icecast/icecast/icecast.monitor000077500000000000000000000066201160532374600244620ustar00rootroot00000000000000#!/usr/bin/perl # # Try to connect to an Icecast server. # # Optionally, specify stream mountpoints to make sure they're # currently mounted. # # To accomplish this, just pass the mountpoints after the hostname # using a colon after the hostname and a comma to delimit mountpoints. # # Example: neptune:/seattletech,/seattletech-56k,/bdean,/drzzzzz # # Outputs hostname: on failures, or prepends an '*' to the # hostname to indicate an inability to contact the icecast host in # general. # # Example: # # neptune:/seattletech (mountpoint is not mounted on server neptune) # *neptune (icecast server on neptune is not responding) # # # Written by Mark Rushing - rushing@orbislumen.net # # icecast.monitor 0.2 13-Jun-2001 # # Copyright (C) 2001, Mark Rushing # # 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; either version 2 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA use IO::Socket; use Getopt::Std; getopts("p:t:u:P:"); $ICport = "$opt_p" || 8000; $ICtimeout = "$opt_t" || 30; $ICadmin = "$opt_u" || "ADMIN"; $ICpasswd = "$opt_P"; ICHOST: foreach $ICarg (@ARGV) { # Separate hostname from stream mountpoints. ($IChost, $ICstreams) = split /:/, $ICarg, 2; # Create socket connection to hostname. ## Don't bother checking streams if failed. if (!openIcecastSock($IChost)) { push(@failed, "\*$IChost"); next; } # Don't bother checking streams if none given. if (!$ICstreams) { close $ICsock; next; } eval { # Check streams on connected host. ## Log into server. local $SIG{ALRM} = sub { die "Command Timeout" }; alarm $ICtimeout; print $ICsock "$ICadmin $ICpasswd\n\n"; while ( <$ICsock> ) { last if /^OK/; if (/ERROR - Bad Password/) { push(@failed, "$IChost\:Bad Password"); next ICHOST; } } ## Get stream data. @mountedStreams = (); print $ICsock "sources\n"; while (<$ICsock>) { last if /^End of source listing/; if (s/.*\[Mountpoint: (\S+)\].*\n/$1/) { push(@mountedStreams, $_); } } print $ICsock "quit Mon signoff\n"; close $ICsock; alarm 0; }; if ($@) { push(@failed, "$IChost\:$@"); next; } # Figure if monitored streams are actually mounted @checkStream = split /,/, $ICstreams; foreach $stream (@checkStream) { push(@failed, "$IChost\:$stream") if (!grep /^$stream/, @mountedStreams) } } if (scalar(@failed)) { print "@failed\n"; exit 1; } exit 0; sub openIcecastSock { my $IChost = $_[0]; $ICsock = new IO::Socket::INET ( PeerAddr => $IChost , PeerPort => $ICport , Proto => "tcp" , Timeout => $ICtimeout , ); ( return 0 ) unless $ICsock; $ICsock->autoflush(1); return 1; } mon-contrib-1.0+dfsg/monitors/icecast/icecast/icecast.monitor.README000066400000000000000000000022121160532374600254040ustar00rootroot00000000000000To: mon@linux.kernel.org Subject: New Monitor: icecast.monitor Hi.. Thanks, Jim, for your work on mon.. it's saved us so much headache... well, and caused a bit, too, but thankfully so.. :) Anyway, here's a new little monitor. It's for Icecast servers. Icecast is a server for streaming MP3 music out and the latest release due out any day also streams the new Ogg Vorbis format. Info at http://xiph.org . I guess this mon might be a little strange in that you can specify things in your mon.conf hostgroup line *after* each hostname that will cause the monitor to act. You can just put in a hostname, and it'll check to make sure the Icecast server is responding. You can optionally put a ':' after the hostname, and then a comma-separated list of Icecast mountpoints that will be checked for. Every once in a while a given stream dies for any number of reasons, and needs to be restarted. The monitor will report back any fallen mountpoints along with the hostname (format: hostname:mountpoint ) or just *hostname if the whole server is not responding. The source is included inline. Commentary appreciated! Mark -- Mark Rushing mon-contrib-1.0+dfsg/monitors/imap/000077500000000000000000000000001160532374600173275ustar00rootroot00000000000000mon-contrib-1.0+dfsg/monitors/imap/imap-ptp.monitor000077500000000000000000000145321160532374600224770ustar00rootroot00000000000000#!/usr/bin/perl # # This script will attempt to login to an imap server # with a plain-text password. Password can either be specified on the # command line or in the monitor-auth.cf file. # # For use with "mon". # # Arguments are "[-u user] [-p pass] [-P port] [-t timeout] [-m mailbox] host [host...]" # # Adapted from "imap.monitor" by # David Nolan, vitroth+mon@cmu.edu # # Which was adapted from "http.monitor" by # Jim Trocki, trockij@transmeta.com # # http.monitor written by # # Jon Meek # American Cyanamid Company # Princeton, NJ # # $Id: imap-ptp.monitor,v 1.1 2005/08/20 15:20:57 vitroth Exp $ # # Copyright (C) 1998, Jim Trocki # # 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; either version 2 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA # use strict; use Getopt::Std; use English; use IO::File; use Socket; use vars qw($opt_p $opt_t $opt_u $opt_c $opt_P $opt_m $PASS $PORT $USER $TIMEOUT $MAILBOX $MONAUTHFILE @failures @longerr); getopts ("p:t:u:c:P:m:"); $PASS = $opt_p || ""; $USER = $opt_u || ""; $TIMEOUT = $opt_t || 30; $MAILBOX = $opt_m || "INBOX"; $PORT = $opt_P || 143; $MONAUTHFILE = $opt_c || $ENV{MON_CFBASEDIR}."/monitor-auth.cf"; @failures = (); @longerr = (); if (my $cf=new IO::File "<$MONAUTHFILE") { my (%users, %passwords); my $g=$ENV{MON_GROUP}; my $s=$ENV{MON_SERVICE}; while (<$cf>) { chomp; if (/^(\S+):user\s*=\s*(\S+)$/) { $users{$1}=$2; } if (/^(\S+):password\s*=\s*(\S+)$/) { $passwords{$1}=$2; } } $USER ||= $users{"$g:$s"}; $PASS ||= $passwords{"$g:$s"}; $USER ||= $users{"$g:*"}; $PASS ||= $passwords{"$g:*"}; $USER ||= $users{"*:$s"}; $PASS ||= $passwords{"*:$s"}; $USER ||= $users{"*:*"}; $PASS ||= $passwords{"*:*"}; } foreach my $host (@ARGV) { if (! &imapGET($host, $PORT)) { push (@failures, $host); } } if (@failures == 0) { exit 0; } print join (" ", sort @failures), "\n\n", join ("\n", @longerr), "\n"; exit 1; sub imapGET { use Sys::Hostname; my($Server, $Port) = @_; my($ServerOK, $TheContent, $Path, $result, $cmd, $in, $errmsg); $ServerOK = 0; $TheContent = ''; $Path = '/'; ############################################################### # $ServerOK = eval { # local $SIG{ALRM} = sub { die "Timeout Alarm" }; # alarm $TIMEOUT; # $c = Cyrus::IMAP->new("$Server"); # if (!$c) { # alarm 0; # push @longerr, "$Server: Unable to connect"; # return 0; # } # if ($USER && $PASS # && !$c->send('', '', 'LOGIN %s %s', $USER, $PASS)) { # alarm 0; # push @longerr, "$Server: Unable to login as $USER: $@"; # return 0; # } # if (!$c->send('', '', 'EXAMINE %s', $MAILBOX)) { # alarm 0; # push @longerr, "$Server: Unable to examine $MAILBOX as $USER: $@"; # return 0; # } # if (!$c->send('', '', 'LOGOUT')) { # alarm 0; # push @longerr, "$Server: Unable to logout: $@"; # return 0; # } # alarm 0; # return 1; # }; eval { local $SIG{ALRM} = sub { die "Timeout Alarm" }; alarm $TIMEOUT; $result = &OpenSocket($Server, $Port); # Open a connection to the server if ($result == 0) { # Failure to open the socket push @longerr, "$Server: Unable to connect"; return ''; } $in = ; if ($in !~ /^\* (OK|PREAUTH|BYE)/) { alarm 0; push @longerr, "$Server: No IMAP banner received"; return 0; } $cmd="login"; print S "A1 LOGIN $USER $PASS\r\n"; while (defined($in=)) { if ($in =~ /^A1 (\w+) (.*)/) { if ($1 eq "OK") { $ServerOK = 1; } else { $errmsg="$1 $2"; } last; } } if ($ServerOK && $MAILBOX) { $cmd="examine"; $ServerOK=0; print S "A2 EXAMINE $MAILBOX\r\n"; while (defined($in=)) { if ($in =~ /^A2 (\w+) (.*)/) { if ($1 eq "OK") { $ServerOK = 1; } else { $errmsg="$1 $2"; } last; } } } if ($ServerOK) { $cmd="logout"; $ServerOK=0; print S "A3 LOGOUT\r\n"; while (defined($in=)) { if ($in =~ /^A3 (\w+) (.*)/) { if ($1 eq "OK") { $ServerOK = 1; } else { $errmsg="$1 $2"; } last; } } } if (!$ServerOK) { if ($errmsg) { push @longerr, "$Server: bad response to $cmd: $errmsg"; } else { push @longerr, "$Server: No response to $cmd"; } } close(S); alarm 0; # Cancel the alarm }; if ($EVAL_ERROR and ($EVAL_ERROR =~ /^Timeout Alarm/)) { push @longerr, "$Server: **** Time Out"; return 0; } elsif ($EVAL_ERROR) { push @longerr, "$Server: $EVAL_ERROR"; return 0; } return $ServerOK; } sub OpenSocket { # # Make a Berkeley socket connection between this program and a TCP port # on another (or this) host. Port can be a number or a named service # my ($OtherHostname, $Port) = @_; my ($OurHostname, $sockaddr, $name, $aliases, $proto, $type, $len, $ThisAddr, $that, $OtherHostAddr, $result); $OurHostname = &hostname; ($name, $aliases, $proto) = getprotobyname('tcp'); ($name, $aliases, $Port) = getservbyname($Port, 'tcp') unless $Port =~ /^\d+$/; ($name, $aliases, $type, $len, $ThisAddr) = gethostbyname($OurHostname); ($name, $aliases, $type, $len, $OtherHostAddr) = gethostbyname($OtherHostname); my $that = sockaddr_in ($Port, $OtherHostAddr); $result = socket(S, &PF_INET, &SOCK_STREAM, $proto) || return undef; $result = connect(S, $that) || return undef; select(S); $| = 1; select(STDOUT); # set S to be un-buffered return 1; # success } mon-contrib-1.0+dfsg/monitors/imap/imap-ssl.monitor000077500000000000000000000121461160532374600224740ustar00rootroot00000000000000#!/usr/bin/perl # # Try to connect to an IMAP server, over SSL, and # wait for the right output. # # For use with "mon". # # Arguments are "[-p port] [-t timeout] [-w cert-expiration-warning-window ] host [host...]" # # Adapted from "imap.monitor" by # David Nolan, vitroth@cmu.edu # # Which in turn was adapted from 'http.monitor' by # Jim Trocki, trockij@transmeta.com # # http.monitor was written by # # Jon Meek # American Cyanamid Company # Princeton, NJ # # $Id: imap-ssl.monitor,v 1.1 2005/08/20 15:20:57 vitroth Exp $ # # Copyright (C) 1998, Jim Trocki # # 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; either version 2 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA # use Getopt::Std; use Net::SSLeay::Handle qw/shutdown/; use English; use Time::ParseDate; getopts ("p:t:w:"); $PORT = $opt_p || 993; $TIMEOUT = $opt_t || 30; $EXPIREWARN = $opt_w ; # How long in advance to warn about cert expiration. 0 means don't warn $EXPIREWARN = 0 if (!defined $EXPIREWARN); # Don't warn by default @failures = (); foreach $host (@ARGV) { if (! &imapGET($host, $PORT)) { push (@failures, $host); } } if (@failures == 0) { exit 0; } print join (" ", sort @failures), "\n\n", join ("\n", @longerr), "\n"; exit 1; sub imapGET { use Socket; use Sys::Hostname; my($Server, $Port) = @_; my($ServerOK, $TheContent); $ServerOK = 0; $TheContent = ''; $Path = '/'; ############################################################### eval { local $SIG{ALRM} = sub { die "Timeout Alarm" }; alarm $TIMEOUT; tie(*S2, "Net::SSLeay::Handle", $Server, $Port); $in = ; if ($in !~ /^\* (OK|PREAUTH|BYE)/) { alarm 0; push @longerr, "$Server: No IMAP banner received"; shutdown(\*S2, 1); close(S2); return 0; } print S2 "A1 LOGOUT\r\n"; while (defined($in=)) { if ($in =~ /^A1 OK/) { $ServerOK = 1; last; } } if (!$ServerOK) { push @longerr, "$Server: No response to logout"; } alarm 0; # Cancel the alarm if ($EXPIREWARN) { my $ssl = Net::SSLeay::Handle::_get_ssl(\*S2); my $cert = Net::SSLeay::get_peer_certificate($ssl); my $servercertname = Net::SSLeay::X509_NAME_oneline(Net::SSLeay::X509_get_subject_name($cert)); my $signingcertname = Net::SSLeay::X509_NAME_oneline(Net::SSLeay::X509_get_issuer_name($cert)); my $notafter = Net::SSLeay::P_ASN1_UTCTIME_put2string (Net::SSLeay::X509_get_notAfter($cert)); my $notbefore = Net::SSLeay::P_ASN1_UTCTIME_put2string (Net::SSLeay::X509_get_notBefore($cert)); my $na_time = parsedate($notafter); my $nb_time = parsedate($notbefore); my $now = time; my $later = $now + (86400 * $EXPIREWARN); print STDERR "XXXXX\nnotbefore $notbefore\nnotafter $notafter\nna_time $na_time\nnb_time $nb_time\nnow $now\nlater $later\n" if $opt_v; if ( $now < $nb_time ) { push @longerr,"$Server: Certificate not valid until $notbefore\ncertificate: $servercertname\nCA certificate: $signingcertname"; $ServerOK = 0; } if ($now > $na_time) { push @longerr,"$Server: Certificate expired as of $notafter\ncertificate: $servercertname\nCA certificate: $signingcertname"; $ServerOK = 0; } elsif ($later > $na_time ) { push @longerr,"$Server: Certificate will expire at $notafter\ncertificate: $servercertname\nCA certificate: $signingcertname"; $ServerOK = 0; } } shutdown(\*S2, 1); close(S2); }; if ($EVAL_ERROR and ($EVAL_ERROR =~ /^Timeout Alarm/)) { push @longerr, "$Server: **** Time Out\n"; return 0; } elsif ($EVAL_ERROR) { push @longerr, "$Server: $EVAL_ERROR"; return 0; } return $ServerOK; } sub OpenSocket { # # Make a Berkeley socket connection between this program and a TCP port # on another (or this) host. Port can be a number or a named service # local($OtherHostname, $Port) = @_; local($OurHostname, $sockaddr, $name, $aliases, $proto, $type, $len, $ThisAddr, $that); $OurHostname = &hostname; ($name, $aliases, $proto) = getprotobyname('tcp'); ($name, $aliases, $Port) = getservbyname($Port, 'tcp') unless $Port =~ /^\d+$/; ($name, $aliases, $type, $len, $ThisAddr) = gethostbyname($OurHostname); ($name, $aliases, $type, $len, $OtherHostAddr) = gethostbyname($OtherHostname); my $that = sockaddr_in ($Port, $OtherHostAddr); $result = socket(S, &PF_INET, &SOCK_STREAM, $proto) || return undef; $result = connect(S, $that) || return undef; select(S); $| = 1; select(STDOUT); # set S to be un-buffered return 1; # success } mon-contrib-1.0+dfsg/monitors/imap/imap-starttls.monitor000077500000000000000000000102271160532374600235510ustar00rootroot00000000000000#!/usr/bin/perl # # Try to connect to an IMAP server, and issue a STARTTLS command, and # wait for the right output. # # For use with "mon". # # Arguments are "-p port -t timeout host [host...]" # # Adapted from "imap.monitor" by # David Nolan, vitroth@cmu.edu # # Which in turn was adapted from 'http.monitor' by # Jim Trocki, trockij@transmeta.com # # http.monitor was written by # # Jon Meek # American Cyanamid Company # Princeton, NJ # # # $Id: imap-starttls.monitor,v 1.1 2005/08/20 15:20:57 vitroth Exp $ # # Copyright (C) 1998, Jim Trocki # # 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; either version 2 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA # use Getopt::Std; use Net::SSLeay::Handle qw/shutdown/; use English; getopts ("p:t:"); $PORT = $opt_p || 143; $TIMEOUT = $opt_t || 30; @failures = (); foreach $host (@ARGV) { if (! &imapGET($host, $PORT)) { push (@failures, $host); } } if (@failures == 0) { exit 0; } print join (" ", sort @failures), "\n\n", join ("\n", @longerr), "\n"; exit 1; sub imapGET { use Socket; use IO::Socket::INET; use Sys::Hostname; use Symbol; my($Server, $Port) = @_; my($ServerOK, $TheContent); $ServerOK = 0; $TheContent = ''; $Path = '/'; ############################################################### eval { local $SIG{ALRM} = sub { die "Timeout Alarm" }; alarm $TIMEOUT; my $socket = gensym; # Necessary to allow $socket and $sslsocket to be used multiple times for my $sslsocket = gensym; # the Net::SSLeay::Handle tie $result = &OpenSocket($socket, $Server, $Port); # Open a connection to the server if ($result == 0) { # Failure to open the socket push @longerr, "$Server: Unable to connect"; return ''; } $in = <$socket>; if ($in !~ /^\* (OK|PREAUTH|BYE)/) { alarm 0; push @longerr, "$Server: No IMAP banner received"; return 0; } print $socket "A1 STARTTLS\r\n"; $in = <$socket>; if ($in !~ /^A1 OK/) { alarm 0; push @longerr, "$Server: STARTTLS request denied"; return 0; } tie(*$sslsocket, "Net::SSLeay::Handle", $socket); print $sslsocket "A1 LOGOUT\r\n"; while (defined($in=<$sslsocket>)) { if ($in =~ /^A1 OK/) { $ServerOK = 1; last; } } if (!$ServerOK) { push @longerr, "$Server: No response to logout, STARTTLS negotiation failed?"; } close($sslsocket); alarm 0; # Cancel the alarm }; if ($EVAL_ERROR and ($EVAL_ERROR =~ /^Timeout Alarm/)) { push @longerr, "$Server: **** Time Out\n"; return 0; } elsif ($EVAL_ERROR) { push @longerr, "$Server: $EVAL_ERROR"; return 0; } return $ServerOK; } sub OpenSocket { # # Make a Berkeley socket connection between this program and a TCP port # on another (or this) host. Port can be a number or a named service # local($socket, $OtherHostname, $Port) = @_; local($OurHostname, $sockaddr, $name, $aliases, $proto, $type, $len, $ThisAddr, $that); $OurHostname = &hostname; ($name, $aliases, $proto) = getprotobyname('tcp'); ($name, $aliases, $Port) = getservbyname($Port, 'tcp') unless $Port =~ /^\d+$/; ($name, $aliases, $type, $len, $ThisAddr) = gethostbyname($OurHostname); ($name, $aliases, $type, $len, $OtherHostAddr) = gethostbyname($OtherHostname); my $that = sockaddr_in ($Port, $OtherHostAddr); $result = socket($socket, &PF_INET, &SOCK_STREAM, $proto) || return undef; $result = connect($socket, $that) || return undef; select($socket); $| = 1; select(STDOUT); # set S to be un-buffered return 1; # success } mon-contrib-1.0+dfsg/monitors/informix/000077500000000000000000000000001160532374600202345ustar00rootroot00000000000000mon-contrib-1.0+dfsg/monitors/informix/informix/000077500000000000000000000000001160532374600220675ustar00rootroot00000000000000mon-contrib-1.0+dfsg/monitors/informix/informix/informix.monitor000066400000000000000000000041301160532374600253310ustar00rootroot00000000000000From clay@panix.com Mon Aug 23 06:52:13 1999 Date: Thu, 5 Aug 1999 10:55:52 -0400 From: Clay Irving To: mon@linux.kernel.org Subject: Monitor for INFORMIX IDS Database I hacked this monitor together yesterday to monitor online status of several INFORMIX databases at work. I'd like to donate it to the growing collection of monitors... It requires DBI and DBD::Informix. #!/usr/local/bin/perl # # Monitor online status of INFORMIX IDS # # Arguements are "database@server" # # $Id: informix.monitor,v 1.1.1.1 2005/02/18 17:52:24 trockij Exp $ # # Copyright (C) 1999, SKECHERS USA, Inc. # # 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; either version 2 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA # use DBI; chomp($parm = $ARGV[0]); ($database, $server) = split /\@/, $parm; # Set environment variables $ENV{LD_LIBRARY_PATH} = "/usr/informix/prod/lib:/usr/informix/prod/lib/esql"; $ENV{INFORMIXDIR} = "/usr/informix/prod"; $ENV{INFORMIXSERVER} = "$server"; # Attempt to connect to the database and get the database name $dbh = DBI->connect($database, $username, $password, 'Informix'); if (defined $dbh->{Name}) { $dbh->disconnect; exit 0; } else { print "$parm is down\n"; exit 1; } -- Clay Irving Witchcraft always has a hard time, until it becomes respectable and changes its name. - Charles Fort mon-contrib-1.0+dfsg/monitors/informix/informix/informix.monitor.README000066400000000000000000000026151160532374600262730ustar00rootroot00000000000000From clay@panix.com Mon Aug 23 06:52:13 1999 Date: Thu, 5 Aug 1999 10:55:52 -0400 From: Clay Irving To: mon@linux.kernel.org Subject: Monitor for INFORMIX IDS Database I hacked this monitor together yesterday to monitor online status of several INFORMIX databases at work. I'd like to donate it to the growing collection of monitors... It requires DBI and DBD::Informix. #!/usr/local/bin/perl # # Monitor online status of INFORMIX IDS # # Arguements are "database@server" # # $Id: informix.monitor.README,v 1.1.1.1 2005/02/18 17:52:24 trockij Exp $ # # Copyright (C) 1999, SKECHERS USA, Inc. # # 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; either version 2 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA mon-contrib-1.0+dfsg/monitors/informix/informixdbspace/000077500000000000000000000000001160532374600234115ustar00rootroot00000000000000mon-contrib-1.0+dfsg/monitors/informix/informixdbspace/informixdbspace.monitor000066400000000000000000000056551160532374600302120ustar00rootroot00000000000000#!/usr/local/bin/perl -w # # $Id: informixdbspace.monitor,v 1.1.1.1 2005/02/18 17:52:24 trockij Exp $ # Usage: server:KBfree [server:KBfree] # # Copyright (C) 1999, SKECHERS USA, Inc. # # 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; either version 2 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA # # $Log: informixdbspace.monitor,v $ # Revision 1.1.1.1 2005/02/18 17:52:24 trockij # initial # # Revision 1.1 2000/02/02 21:06:02 clay # Initial revision # # use DBI; use strict; # Initialize variables my $server = ""; my $min_avail = ""; my $database = "sysmaster"; my $username = ""; my $password = ""; my @failures; # Get the server name from the first parameter foreach (@ARGV) { if (length($_) !=0) { ($server, $min_avail) = split /:/, $_, 2; # Set environment variables $ENV{LD_LIBRARY_PATH} = "/usr/informix/prod/lib:/usr/informix/prod/lib/esql"; $ENV{INFORMIXDIR} = "/usr/informix/prod"; $ENV{INFORMIXSERVER} = "$server"; # Select free dbspace from sysmaster tables -- Assumes a 2K page size my $sel_stmt = "select name, sum(nfree * 2) \ from sysdbspaces d, syschunks c \ where d.dbsnum = c.dbsnum \ group by 1 \ order by 1"; # Connect to the database my $dbh = DBI->connect($database, $username, $password, 'Informix'); # Prepare the SQL statement (my $sth = $dbh->prepare($sel_stmt)) or die "Failed to prepare '$sel_stmt'\n"; # Execute the SQL statement $sth->execute; # Check free space while (my ($dbspace, $freekb) = $sth->fetchrow) { $dbspace =~ s/\s+//; # Note: In our environment, we set up dbspaces for physical and logical logs # By default, we call them dbplog and dbllog, respectively. We don't want # to check free space in these logs if (!defined ($freekb)) { push (@failures, "dbspace error: $!"); next; } elsif (($freekb < $min_avail) && ($dbspace !~ /log/)) { push (@failures, "$freekb free in $dbspace on $server"); } } # Disconnect $dbh->disconnect; } else { print "No server:KBfree specified!\n"; exit 2; } } if (@failures) { print join (", ", @failures), "\n"; exit 1; } exit 0;mon-contrib-1.0+dfsg/monitors/informix/informixdbspace/informixdbspace.monitor.README000066400000000000000000000016311160532374600311340ustar00rootroot00000000000000# $Id: informixdbspace.monitor.README,v 1.1.1.1 2005/02/18 17:52:24 trockij Exp $ # Usage: server:KBfree [server:KBfree] # # (uses DBI) # # # Copyright (C) 1999, SKECHERS USA, Inc. # # 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; either version 2 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA mon-contrib-1.0+dfsg/monitors/ipsec/000077500000000000000000000000001160532374600175045ustar00rootroot00000000000000mon-contrib-1.0+dfsg/monitors/ipsec/ipsec/000077500000000000000000000000001160532374600206075ustar00rootroot00000000000000mon-contrib-1.0+dfsg/monitors/ipsec/ipsec/ipsec.monitor000077500000000000000000000024111160532374600233240ustar00rootroot00000000000000#!/bin/bash # # Copyright (C) 2001 Wiktor Wodecki # # 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; either version 2 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA # # $Id: ipsec.monitor,v 1.1.1.1 2005/02/18 17:52:24 trockij Exp $ # if [ "$1" == "" ]; then exit 1 fi CONN="`echo $1|sed -e s/[\./]/\\\\\\\\\\\0/g`" IPSECRETURN="`ipsec look|awk '/'"$CONN"'/ {print $5}'`" if [ "$IPSECRETURN" == "%trap" ]; then echo "Connection Inactive: $1" exit 1 elif [ "$IPSECRETURN" == "" ]; then echo "Error, no such connection found" exit 2 elif [ "`echo $IPSECRETURN|awk '/^tun0x/'`" == "$IPSECRETURN" ]; then exit 0 else echo "Unknown error, check manually" exit 254 fi mon-contrib-1.0+dfsg/monitors/ipsec/ipsec/ipsec.monitor.README000066400000000000000000000026021160532374600242570ustar00rootroot00000000000000This monitor works under linux (kernel 2.4.0 upwards) with the freeswan implementation of ipsec. See http://www.freeswan.org for more information about it. The monitor checks if an ipsec tunnel to remote network is established. It does so via the "ipsec look" command. Simply create a hostgroup ipsec in your mon.cf and feed it with networks, for example: hostgroup ipsec 192.168.36.0/24 192.168.126.32/27 This will check if there's a tunnel to the networks 192.168.36.0/24 and 192.168.126.32/27 Notice: ipsec must be in $PATH otherwise nothing will work. # Copyright (C) 2001 Wiktor Wodecki # # 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; either version 2 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA # # $Id: ipsec.monitor.README,v 1.1.1.1 2005/02/18 17:52:24 trockij Exp $ # mon-contrib-1.0+dfsg/monitors/kerberos/000077500000000000000000000000001160532374600202155ustar00rootroot00000000000000mon-contrib-1.0+dfsg/monitors/kerberos/krb5.monitor000077500000000000000000000156131160532374600225020ustar00rootroot00000000000000#!/usr/bin/perl # # This script will attempt to get Kerberos 5 tickets from one or more kerberos # KDCs. Requires Authen::Krb5. # # The user name, password, and realm can all be specified on the # commandline, or they can be read from the monitor-auth.cf file in the mon # config base directory. Matching entries in monitor-auth.cf will look like: # # *:*:user=username # *:*:password=password-string # *:*:realm=EXAMPLE.COM # # (Where *:* can be replaced with group:service, group:* or *:service, which # allows you to define different settings for different hostgroups/services. # # A temporary kerberos config file will need to be written to disk in order # to test the servers independently. The mon state dir will be used, or you # can specify a directory on the command line. # # Arguments: # [--directory dir] [--user user] [--password password] # [--realm realm] hostname [...] # # # Script Author: Carnegie Mellon University, Computing Services # Technical Contact: net-dev@andrew.cmu.edu # Copyright (c) 2002 Carnegie Mellon University. All rights reserved. # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions are met: # # 1. Redistributions of source code must retain the above copyright notice, # this list of conditions and the following disclaimer. # # 2. Redistributions in binary form must reproduce the above copyright notice, # this list of conditions and the following disclaimer in the # documentation and/or other materials provided with the distribution. # # 3. The name "Carnegie Mellon University" must not be used to endorse or # promote products derived from this software without prior written # permission. For permission or any legal details, please contact: # Office of Technology Transfer # Carnegie Mellon University # 5000 Forbes Avenue # Pittsburgh, PA 15213-3890 # (412) 268-4387, fax: (412) 268-7395 # tech-transfer@andrew.cmu.edu # # 4. Redistributions of any form whatsoever must retain the following # acknowledgment: "This product includes software developed by Computing # Services at Carnegie Mellon University (http://www.cmu.edu/computing/)." # # CARNEGIE MELLON UNIVERSITY DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS # SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, # IN NO EVENT SHALL CARNEGIE MELLON UNIVERSITY BE LIABLE FOR ANY SPECIAL, # INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM # LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE # OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR # PERFORMANCE OF THIS SOFTWARE. use IO::File; use Authen::Krb5; use Getopt::Long; use strict 'refs'; use strict 'subs'; $result = GetOptions(\%opt, 'debug', 'dir=s', 'user=s', 'password=s', 'realm=s'); die "Usage: $0 [--directory dir] [--user user] [--password password]\n [--realm realm] hostname [...]\n" if (!$result); @failures = (); @report = (); $user = $opt{user}; $password = $opt{password}; $realm = $opt{realm}; &parse_cf; print STDERR "Using user:$user password:$password realm:$realm\n" if ($opt{debug}); if (!$user || !$password || !$realm) { print "krb5.monitor: user/password/realm were not specified.\n"; exit -1; } foreach $kdc ( @ARGV ) { &krb5_poll( $kdc ); } if (@failures == 0) { exit 0; } print "@failures\n"; print "@report"; exit 1 if ($someok); exit 255; sub parse_cf { my (%users, %passwords, %realms); my $g=$ENV{MON_GROUP} || 'kerberos-servers'; my $s=$ENV{MON_SERVICE} || 'krb5'; my $file = $ENV{MON_CFBASEDIR}."/monitor-auth.cf"; print STDERR "Parsing $file\n" if ($opt{debug}); if ($cf=new IO::File "<$file") { while (<$cf>) { if (/^(\S+):user\s*=\s*(\S+)$/) { $users{$1}=$2; } if (/^(\S+):password\s*=\s*(\S+)$/) { $passwords{$1}=$2; } if (/^(\S+):realm\s*=\s*(\S+)$/) { $realms{$1}=$2; } } $user ||= $users{"$g:$s"}; $user ||= $users{"$g:*"}; $user ||= $users{"*:$s"}; $user ||= $users{"*:*"}; $password ||= $passwords{"$g:$s"}; $password ||= $passwords{"$g:*"}; $password ||= $passwords{"*:$s"}; $password ||= $passwords{"*:*"}; $realm ||= $realms{"$g:$s"}; $realm ||= $realms{"$g:*"}; $realm ||= $realms{"*:$s"}; $realm ||= $realms{"*:*"}; } } sub krb5_poll { my ($kdc)=@_; my $dir= $opt{'dir'} || $ENV{"MON_STATEDIR"} || "/usr/lib/mon/state.d"; my $confdir="$dir/krb5"; my $conffile="$confdir/$kdc/krb5.conf"; my ($cli,$serv,$cc,$ret, $error, $k5c, $constant); mkdir($confdir) unless (-d $confdir); unless (-f $conffile) { $error=1; if ($realm) { mkdir "$confdir/$kdc"; $k5c=new IO::File "> $conffile"; if ($k5c) { print $k5c <<"_EOC_"; [libdefaults] default_realm=$realm default_tgs_enctypes = des-cbc-crc default_tkt_enctypes = des-cbc-crc default_etypes = des-cbc-crc default_etypes_des = des-cbc-crc clockskew = 300 checksum_type = 1 [realms] $realm = { kdc=$kdc } _EOC_ $error=0; close($k5c); } else { print STDERR "Couldn't create $conffile: $!\n" if ($opt{debug}); } } if ($error) { push @failures, $kdc; if ($realm) { push @report, "\n$kdc: MONCONFIGURATION: could not initalize new config file\n"; } else { push @report, "\n$kdc: MONCONFIGURATION: No config file\n"; } return; } } $ENV{KRB5_CONFIG}="$confdir/$kdc/krb5.conf"; Authen::Krb5::init_context(); Authen::Krb5::init_ets(); $cli=Authen::Krb5::parse_name("$user\@$realm"); unless ($cli) { push @failures, $kdc; push @report, "\n$kdc: MONCONFIGURATION: ".Authen::Krb5::error()."\n...while parsing $user\n"; Authen::Krb5::free_context(); return; } $serv=Authen::Krb5::build_principal_ext($cli); unless ($serv) { push @failures, $kdc; push @report, "\n$kdc: MONCONFIGURATION: ".Authen::Krb5::error()."\n...while generating server name\n"; Authen::Krb5::free_context(); return; } $cc=Authen::Krb5::cc_resolve("MEMORY:"); unless ($cc) { push @failures, $kdc; push @report, "\n$kdc: MONCONFIGURATION: ".Authen::Krb5::error()."\n...while getting local credentials cache\n"; Authen::Krb5::free_context(); return; } unless ($cc->initialize($cli)) { push @failures, $kdc; push @report, "\n$kdc: MONCONFIGURATION: " .Authen::Krb5::error() ."\n...while preparing local credentials cache\n"; Authen::Krb5::free_context(); return; } $ret=Authen::Krb5::get_in_tkt_with_password($cli,$serv,$password,$cc); if ($ret) { $someok=1; } else { push @failures, $kdc; $err= Authen::Krb5::error(); if ($err + 0 == Authen::Krb5::KRB5_KDC_UNREACH()) { push @report, "\n$kdc: Timed Out\n"; } elsif ($err + 0 == Authen::Krb5::KRB5_REALM_CANT_RESOLVE()) { push @report, "\n$kdc: Cannot resolve hostname\n"; } else { push @report, "\n$kdc: $err\n"; } } Authen::Krb5::free_context(); } mon-contrib-1.0+dfsg/monitors/kerberos/krb5.monitor.README000066400000000000000000000017261160532374600234330ustar00rootroot00000000000000# This script will attempt to get Kerberos 5 tickets from one or more kerberos # KDCs. Requires Authen::Krb5. # # The user name, password, and realm can all be specified on the # commandline, or they can be read from the monitor-auth.cf file in the mon # config base directory. Matching entries in monitor-auth.cf will look like: # # *:*:user=username # *:*:password=password-string # *:*:realm=EXAMPLE.COM # # (Where *:* can be replaced with group:service, group:* or *:service, which # allows you to define different settings for different hostgroups/services. # # A temporary kerberos config file will need to be written to disk in order # to test the servers independently. The mon state dir will be used, or you # can specify a directory on the command line. # # Arguments: # [--directory dir] [--user user] [--password password] # [--realm realm] hostname [...] # # Script Author: Carnegie Mellon University, Computing Services # Technical Contact: net-dev@andrew.cmu.edu mon-contrib-1.0+dfsg/monitors/lvs/000077500000000000000000000000001160532374600172055ustar00rootroot00000000000000mon-contrib-1.0+dfsg/monitors/lvs/ipvs.monitor000077500000000000000000000043751160532374600216130ustar00rootroot00000000000000#!/usr/bin/perl # ipvs.monitor - Linux Virtual Server monitor for mon # Check whether the specified virtual service is defined, and, # optionally, whether it has any realservers defined. # # Invocation: # ipvs.monitor [options] -V -P # # Options: # -V virtual server # -P protocol (tcp|udp) # -z allows a virtual service to have zero realservers defined # # Notes: # - Since it uses ipvsadm, this script (and therefore mon) must # unfortunately run as root :( # - ipvs.monitor returns 0 on success and 1 on failure use Getopt::Std; getopts ("zV:P:"); %proto = ( "tcp" => "-t", "udp" => "-u", ); $virtual_service = "$opt_V"; @ipvs = `/sbin/ipvsadm -l $proto{$opt_P} $virtual_service 2>&1`; # allow a service with no realservers? defined $opt_z ? ($n = 2) : ($n = 3); # Check the output: # ...two lines of headers # ...one line of virtual service # ...one line for each realserver $#ipvs < $n ? exit 1 : exit 0; # # ## ### ##### ######## ############# ##################### # CHANGELOG # Tue Jul 27 11:17:39 MYT 2004 # Initial version # Christopher DeMarco # Tue Jul 27 14:14:08 MYT 2004 # added -z switch # Christopher DeMarco # Wed Oct 1 18:34:27 CEST 2008 # fixed inline documentation # fixed whitespace/tab # Richard Hartmann # # ## ### ##### ######## ############# ##################### # Copyright (C) 2004, Christopher DeMarco # Copyright (C) 2008, Richard Hartmann # # 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; either version 2 of the # License, or (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU # General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA # 02111-1307 USA mon-contrib-1.0+dfsg/monitors/mon/000077500000000000000000000000001160532374600171725ustar00rootroot00000000000000mon-contrib-1.0+dfsg/monitors/mon/umn_mon/000077500000000000000000000000001160532374600206425ustar00rootroot00000000000000mon-contrib-1.0+dfsg/monitors/mon/umn_mon/umn_mon.monitor000066400000000000000000000077071160532374600237360ustar00rootroot00000000000000#!/usr/bin/perl # # Try to connect to a mon server. # # For use with "mon". # # Arguments are "-p port -t timeout host [host...]" # # Adapted from "http.monitor" by # Steven F. Siirila, University of Minnesota, sfs@umn.edu # # http.monitor written by # # Jon Meek # American Cyanamid Company # Princeton, NJ # # $Id: umn_mon.monitor,v 1.1.1.1 2005/02/18 17:52:23 trockij Exp $ # # Copyright (C) 1998, Jim Trocki # # 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; either version 2 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA # use Getopt::Std; use English; getopts ("p:t:"); $PORT = $opt_p || getservbyname ("mon", "tcp") || 2583; $TIMEOUT = $opt_t || 30; @failures = (); foreach $host (@ARGV) { system("fping -q -r 3 -t 2000 $host 2>/dev/null"); $status = $? / 256; next if $status; # ignore hosts which are not pingable if (! &monGET($host, $PORT)) { push (@failures, $host); } } if (@failures == 0) { exit 0; } print "@failures\n"; foreach $msg (@details) { print "$msg\n"; } exit 1; sub monGET { use Socket; use Sys::Hostname; my($Server, $Port) = @_; my($ServerOK, $TheContent); $ServerOK = 0; $TheContent = ''; ############################################################### eval { local $SIG{ALRM} = sub { die "Timeout Alarm" }; alarm $TIMEOUT; $result = &OpenSocket($Server, $Port); # Open a connection to the server if ($result == 0) { # Failure to open the socket push(@details, "${Server}: Unable to create MON connection to port $Port"); return ''; } print S "list state\r\n"; $in = ; if ($in !~ /^scheduler running$/) { alarm 0; push(@details, "${Server}: $in"); return 0; } $in = ; if ($in !~ /^220 /) { alarm 0; push(@details, "${Server}: $in"); return 0; } print S "quit\r\n"; $in = ; if ($in !~ /^220 /) { alarm 0; push(@details, "${Server}: $in"); return 0; } $ServerOK = 1; close(S); alarm 0; # Cancel the alarm }; if ($EVAL_ERROR and ($EVAL_ERROR eq 'Timeout Alarm')) { push(@details, "${Server}: Connection timed out"); return 0; } return $ServerOK; } sub OpenSocket { # # Make a Berkeley socket connection between this program and a TCP port # on another (or this) host. Port can be a number or a named service # local($OtherHostname, $Port) = @_; local($OurHostname, $sockaddr, $name, $aliases, $proto, $type, $len, $ThisAddr, $that); $OurHostname = &hostname; ($name, $aliases, $proto) = getprotobyname('tcp'); ($name, $aliases, $Port) = getservbyname($Port, 'tcp') unless $Port =~ /^\d+$/; ($name, $aliases, $type, $len, $ThisAddr) = gethostbyname($OurHostname); ($name, $aliases, $type, $len, $OtherHostAddr) = gethostbyname($OtherHostname); $sockaddr = 'S n a4 x8'; # Format for packed network address $that = pack($sockaddr, &AF_INET, $Port, $OtherHostAddr); $result = socket(S, &PF_INET, &SOCK_STREAM, $proto) || return undef; $result = connect(S, $that) || return undef; select(S); $| = 1; select(STDOUT); # set S to be un-buffered return 1; # success }mon-contrib-1.0+dfsg/monitors/mon/umn_mon/umn_mon.monitor.README000066400000000000000000000021631160532374600246610ustar00rootroot00000000000000# Try to connect to a mon server. # # For use with "mon". # # Arguments are "-p port -t timeout host [host...]" # # Adapted from "http.monitor" by # Steven F. Siirila, University of Minnesota, sfs@umn.edu # # http.monitor written by # # Jon Meek # American Cyanamid Company # Princeton, NJ # # $Id: umn_mon.monitor.README,v 1.1.1.1 2005/02/18 17:52:23 trockij Exp $ # # Copyright (C) 1998, Jim Trocki # # 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; either version 2 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA mon-contrib-1.0+dfsg/monitors/netsnmp/000077500000000000000000000000001160532374600200655ustar00rootroot00000000000000mon-contrib-1.0+dfsg/monitors/netsnmp/netsnmp-exec/000077500000000000000000000000001160532374600224735ustar00rootroot00000000000000mon-contrib-1.0+dfsg/monitors/netsnmp/netsnmp-exec/netsnmp-exec.monitor000077500000000000000000000165111160532374600265210ustar00rootroot00000000000000#!/usr/bin/perl # # Monitor external programs via SNMP (v. 1-3) # (based on netsnmp-freespace.monitor) # # Usage: # [-h] # Usage # [-t Timeout] # Timeout in ms (default: 1000000) # [-r Retries] # Retries before failure (default: 5) # [-v SNMPversion] # 1,2,2c or 3 (default: 1) # [-c Community] # For SNMP v.1,2,2c (default: public) # [-u snmpuser] # For SNMP v.3 (default: initial) # [-l seclevel] # For SNMP v.3 (default: noAuthNoPriv) # [-A authpassphrase] # For SNMP v.3 # [-n num[,num...]] # Zero-indexed external program number(s); programs # # are numbered by the order they appear in the # # remote snmpd.conf. If monitoring specific programs # # on multiple hosts, they must be consistent! # # Default is to monitor all. # host [host ...] # # This script monitors one or more external programs run by the UCD # SNMP agent. Specific programs to monitor can be specified with the # "-n" option; these are zero-indexed in the order they appear in the # monitored host's snmpd.conf file. Default is to monitor all. # # The summary output line will be of the form "host:name[,host:name]" # where "name" is the name of the failing program (the "extNames" # field as defined in snmpd.conf; not the path to the program). The # detail lines will contain full error text from the failing program # and the error value it returned. # # The script will exit with 0 value 1 for an extNames program failure # and 2 for an SNMP error. # # BUGS AND LIMITATIONS: This is designed to handle programs that only # return one line of output via snmpd; that is, with simple programs # run via the "sh" or "exec" directives in the snmpd.conf file and NOT # with programs run by "exec" and returning data in their own MIB # tables. Actually, I've only gotten the "sh" directive to work with # ucd-snmp-4.2.1 under Solaris. Also note that when given an external # program number that doesn't exist on the monitored host, the script # will return the output for program number 0 and will not report an # error (see note below). In some situations (e.g. sending v. 1 request # to a host configured only to respond to v. 3) the script will fail # silently, because the SNMP module doesn't report an error. # # # Copyright (C) 2001 Daniel J. Urist # # 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; either version 2 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA # use SNMP; use Getopt::Std; $ENV{'MIBS'} = "UCD-SNMP-MIB"; getopts("ht:r:v:c:u:l:A:n:"); my $VERSION = "0.2"; if($opt_h){ print <<"USAGE"; $0 Version $VERSION by Daniel J. Urist Usage: [-h] # Usage [-t Timeout] # Timeout in ms (default: 1000000) [-r Retries] # Retries before failure (default: 5) [-v SNMPversion] # 1,2,2c or 3 (default: 1) [-c Community] # For SNMP v.1,2,2c (default: public) [-u snmpuser] # For SNMP v.3 (default: initial) [-l seclevel] # For SNMP v.3 (default: noAuthNoPriv) [-A authpassphrase] # For SNMP v.3 [-n num[,num...]] # Zero-indexed external program number(s); programs # are numbered by the order they appear in the # remote snmpd.conf. If monitoring specific programs # on multiple hosts, they must be consistent! # Default is to monitor all. host [host ...] USAGE exit; } # FIXME we should probably offer all the v3 options that the SNMP module does my $Timeout = $opt_t || 1000000; my $Retries = $opt_r || 5; my $SNMPVersion = $opt_v || 1; my $Community = $opt_c || 'public'; my $SecName = $opt_u || 'initial'; my $SecLevel = $opt_l || 'noAuthNoPriv'; my $Authpass = $opt_A || ''; my %SNMPARGS = ( Timeout => $Timeout, Version => $SNMPVersion, ); if ($SNMPVersion eq "3"){ $SNMPARGS{SecName} = $SecName; $SNMPARGS{SecLevel} = $SecLevel; $SNMPARGS{AuthPass} = $Authpass; } else{ $SNMPARGS{Community} = $Community; } my @Extprognums = split(",", $opt_n); my $RETVAL = 0; my %Failures; my %Longerr; my $Session; foreach $host (@ARGV) { $Session = new SNMP::Session( DestHost => $host, %SNMPARGS, ); unless( defined($Session) ) { $RETVAL = ($RETVAL == 1) ? 1 : 2; $Failures{"$host session error"} = ""; $Longerr{"$host could not get SNMP session"} = ""; next; } my $ext; my $v; my @q; # We are monitoring specific programs # FIXME If $ext is out of range, i.e. for example, if $ext is 2 and # there are only programs numbered 0 and 1, the returned value is # for program number 0. It seems to me we should get an SNMP error # back, but we don't; I suspect this is a bug in the SNMP module # since passing a bogus index to snmpwalk gives a "No Such Instance" # error. Unfortunately I also can't find a way to retrieve the index # number from the returned data, so I have nothing with which to # compare it and flag the error. if( defined(@Extprognums) ){ foreach $ext (@Extprognums){ $v = new SNMP::Varbind (["extIndex", $ext]); $Session->getnext($v); @q = $Session->get ([ ["extNames", $v->iid], # 0 ["extCommand", $v->iid], # 1 ["extResult", $v->iid], # 2 ["extOutput", $v->iid], # 3 ["extErrFix", $v->iid], # 4 ]); if($q[2] != 0){ $RETVAL = 1; $Failures{$host .":" . $q[0]} = ""; $Longerr{$host .":" . $q[0] . " exited with code: " . $q[2] . ", error: \"" . $q[3] . "\""} = ""; } if ($Session->{"ErrorStr"}) { $RETVAL = ($RETVAL == 1) ? 1 : 2; $Failures{$host} = ""; $Longerr{"$host returned an SNMP error: " . $Session->{"ErrorStr"}} = ""; last; } } } # We are monitoring all programs else{ $v = new SNMP::Varbind (["extIndex"]); $Session->getnext($v); while (!$Session->{"ErrorStr"} && $v->tag eq "extIndex") { @q = $Session->get ([ ["extNames", $v->iid], # 0 ["extCommand", $v->iid], # 1 ["extResult", $v->iid], # 2 ["extOutput", $v->iid], # 3 ["extErrFix", $v->iid], # 4 ]); if($q[2] != 0){ $RETVAL = 1; $Failures{$host .":" . $q[0]} = ""; $Longerr{$host .":" . $q[0] . " exited with code: " . $q[2] . ", error: \"" . $q[3] . "\""} = ""; } if ($Session->{"ErrorStr"}) { $RETVAL = ($RETVAL == 1) ? 1 : 2; $Failures{$host} = ""; $Longerr{"$host returned an SNMP error: " . $Session->{"ErrorStr"}} = ""; last; } $Session->getnext($v); } } } if (scalar keys %Failures) { print join (", ", sort keys %Failures), "\n", "\n"; print join ("\n", sort keys %Longerr), "\n"; } exit $RETVAL; mon-contrib-1.0+dfsg/monitors/netsnmp/netsnmp-exec/netsnmp-exec.monitor.README000066400000000000000000000044511160532374600274520ustar00rootroot00000000000000# Monitor external programs via SNMP (v. 1-3) # (based on netsnmp-freespace.monitor) # # Usage: # [-h] # Usage # [-t Timeout] # Timeout in ms (default: 1000000) # [-r Retries] # Retries before failure (default: 5) # [-v SNMPversion] # 1,2 or 3 (default: 1) # [-c Community] # For SNMP v.2 (default: public) # [-u snmpuser] # For SNMP v.3 (default: initial) # [-l seclevel] # For SNMP v.3 (default: noAuthNoPriv) # [-A authpassphrase] # For SNMP v.3 # [-n num[,num...]] # Zero-indexed external program number(s); programs # # are numbered by the order they appear in the # # remote snmpd.conf. If monitoring specific programs # # on multiple hosts, they must be consistent! # # Default is to monitor all. # host [host ...] # # This script monitors one or more external programs run by the UCD # SNMP agent. Specific programs to monitor can be specified with the # "-n" option; these are zero-indexed in the order they appear in the # monitored host's snmpd.conf file. Default is to monitor all. # # The summary output line will be of the form "host:name[,host:name]" # where "name" is the name of the failing program (the "extNames" # field as defined in snmpd.conf; not the path to the program). The # detail lines will contain full error text from the failing program # and the error value it returned. # # The script will exit with 0 value 1 for an extNames program failure # and 2 for an SNMP error. # # BUGS AND LIMITATIONS: This is designed to handle programs that only # return one line of output via snmpd; that is, with simple programs # run via the "sh" or "exec" directives in the snmpd.conf file and NOT # with programs run by "exec" and returning data in their own MIB # tables. Actually, I've only gotten the "sh" directive to work with # ucd-snmp-4.2.1 under Solaris. Also note that when given an external # program number that doesn't exist on the monitored host, the script # will return the output for program number 0 and will not report an # error. In some situations (e.g. sending v. 1 request to a host # configured only to respond to v. 3) the script will fail silently, # because the SNMP module doesn't report an error. # mon-contrib-1.0+dfsg/monitors/netsnmp/netsnmp-freespace/000077500000000000000000000000001160532374600235045ustar00rootroot00000000000000mon-contrib-1.0+dfsg/monitors/netsnmp/netsnmp-freespace/netsnmp-freespace.monitor000077500000000000000000000147701160532374600305500ustar00rootroot00000000000000#!/usr/bin/perl # # Monitor diskspace via SNMP # (based on process.monitor by Brian Moore) # # Originally written by SATOH Fumiyasu . # Modified Oct 2001 by Dan Urist # Changes: added usage, SNMP v.3 support, -T threshold option and # unique-ified errors # # Usage: # [-h] # Usage # [-t Timeout] # Timeout in ms (default: 1000000) # [-r Retries] # Retries before failure (default: 5) # [-v SNMPversion] # 1,2,2c or 3 (default: 1) # [-c Community] # For SNMP v.1,2,2c (default: public) # [-u snmpuser] # For SNMP v.3 (default: initial) # [-l seclevel] # For SNMP v.3 (default: noAuthNoPriv) # [-A authpassphrase] # For SNMP v.3 # [-T threshold] # If a disk threshold is given, the script # # will exit with the value of the highest # # disk percentage found that is over the # # threshold; if no disks are over the threshold # # it will exit with value 0, and it will exit # # with value 2 for SNMP error # host [host ...] # # # This script will exit with value 1 if host:community has dskErrorFlag # set. The summary output line will be the host names that failed # and the disk information. The detail lines are what UCD snmp returns # for an dskErrMessage. ('/filesystem: less than WATERMARK free (= CURRENT)'). # If there is an SNMP error (either a problem with the SNMP libraries, # or a problem communicating via SNMP with the destination host), # this script will exit with a warning value of 2. # # If the -T threshold option is used, the script will exit with the # highest disk percentage found that is over the threshold. The intent # is to allow use with mon's "alert exit=value" parameter to allow for # finer-grained alerts based on disk usage. If no disks are over the # threshold, the script will exit with value 0; if an SNMP error # occurs (and there are no other errors), the script will exit with # value 2. # # Copyright (C) 2001 SATOH Fumiyasu # # 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; either version 2 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA # use SNMP; use Getopt::Std; $ENV{'MIBS'} = "UCD-SNMP-MIB"; getopts("ht:r:v:c:u:l:A:T:"); my $VERSION = "0.1"; if( $opt_h || (scalar @ARGV == 0) ){ print <<"USAGE"; $0 Version $VERSION; original version by SATOH Fumiyasu , SNMP v.3 support by Daniel J. Urist . Usage: [-h] # Usage [-t Timeout] # Timeout in ms (default: 1000000) [-r Retries] # Retries before failure (default: 5) [-v SNMPversion] # 1,2,2c or 3 (default: 1) [-c Community] # For SNMP v.1,2,2c (default: public) [-u snmpuser] # For SNMP v.3 (default: initial) [-l seclevel] # For SNMP v.3 (default: noAuthNoPriv) [-A authpassphrase] # For SNMP v.3 [-T threshold] # If a disk threshold is given, the script will exit # with the value of the highest disk percentage found # that is over the threshold; if no disks are over the # the threshold it will exit with value 0, and it will # exit with value 2 for SNMP error host [host ...] USAGE exit; } # FIXME we should probably offer all the v3 options that the SNMP module does my $Timeout = $opt_t || 1000000; my $Retries = $opt_r || 5; my $SNMPVersion = $opt_v || 1; my $Community = $opt_c || 'public'; my $SecName = $opt_u || 'initial'; my $SecLevel = $opt_l || 'noAuthNoPriv'; my $Authpass = $opt_A || ''; my $Threshold = $opt_T if defined($opt_T); my %SNMPARGS = ( Timeout => $Timeout, Version => $SNMPVersion, ); if ($SNMPVersion eq "3"){ $SNMPARGS{SecName} = $SecName; $SNMPARGS{SecLevel} = $SecLevel; $SNMPARGS{AuthPass} = $Authpass; } else{ $SNMPARGS{Community} = $Community; } my $RETVAL = 0; my %Failures; my %Longerr; my $Session; foreach $host (@ARGV) { $Session = new SNMP::Session( DestHost => $host, %SNMPARGS, ); unless( defined($Session) ) { $RETVAL = 2 if $RETVAL == 0; # Other errors take precedence over SNMP error $Failures{"$host session error"} = ""; $Longerr{"$host could not get SNMP session"} = ""; next; } my $v = new SNMP::Varbind (["dskIndex"]); $Session->getnext ($v); while (!$Session->{"ErrorStr"} && $v->tag eq "dskIndex") { my @q = $Session->get ([ ["dskPath", $v->iid], # 0 ["dskDevice", $v->iid], # 1 ["dskMinimum", $v->iid], # 2 ["dskMinPercent", $v->iid], # 3 ["dskTotal", $v->iid], # 4 ["dskAvail", $v->iid], # 5 ["dskUsed", $v->iid], # 6 ["dskPercent", $v->iid], # 7 ["dskPercentNode", $v->iid],# 8 ["dskErrorFlag", $v->iid], # 9 ["dskErrorMsg", $v->iid], # 10 ]); last if ($Session->{"ErrorStr"}); if( defined $Threshold ){ if($q[7] > $Threshold){ $RETVAL = $q[7] if $q[7] > $RETVAL; my ($t, $u, $a) = map { int($_/1024) } @q[4, 6, 5]; $Failures{$host} = ""; $Longerr{"$host:$q[0]($q[1]) total=$t used=$u($q[7]%) free=$a threshold=$Threshold%"} = ""; } } elsif ($q[9] > 0) { $RETVAL = 1; my ($t, $u, $a) = map { int($_/1024) } @q[4, 6, 5]; $Failures{$host} = ""; $Longerr{"$host:$q[0]($q[1]) total=$t used=$u($q[7]%) free=$a err=$q[10]"} = ""; } $Session->getnext ($v); } if ($Session->{"ErrorStr"}) { $RETVAL = 2 if $RETVAL == 0; # Other errors take precedence over SNMP error $Failures{$host} = ""; $Longerr{"$host returned an SNMP error: " . $Session->{"ErrorStr"}} = ""; } } if (scalar keys %Failures) { print join (", ", sort keys %Failures), "\n", "\n"; print join ("\n", sort keys %Longerr), "\n"; } exit $RETVAL; mon-contrib-1.0+dfsg/monitors/netsnmp/netsnmp-freespace/netsnmp-freespace.monitor.README000066400000000000000000000041041160532374600314670ustar00rootroot00000000000000# # Monitor diskspace via SNMP # (based on process.monitor by Brian Moore) # # Originally written by SATOH Fumiyasu . # Modified Oct 2001 by Dan Urist # Changes: added usage, SNMP v.3 support, -T threshold option and # unique-ified errors # # Usage: # [-h] # Usage # [-t Timeout] # Timeout in ms (default: 1000000) # [-r Retries] # Retries before failure (default: 5) # [-v SNMPversion] # 1,2,2c or 3 (default: 1) # [-c Community] # For SNMP v.1,2,2c (default: public) # [-u snmpuser] # For SNMP v.3 (default: initial) # [-l seclevel] # For SNMP v.3 (default: noAuthNoPriv) # [-A authpassphrase] # For SNMP v.3 # [-T threshold] # If a disk threshold is given, the script # # will exit with the value of the highest # # disk percentage found that is over the # # threshold; if no disks are over the threshold # # it will exit with value 0, and it will exit # # with value 2 for SNMP error # host [host ...] # # # This script will exit with value 1 if host:community has dskErrorFlag # set. The summary output line will be the host names that failed # and the disk information. The detail lines are what UCD snmp returns # for an dskErrMessage. ('/filesystem: less than WATERMARK free (= CURRENT)'). # If there is an SNMP error (either a problem with the SNMP libraries, # or a problem communicating via SNMP with the destination host), # this script will exit with a warning value of 2. # # If the -T threshold option is used, the script will exit with the # highest disk percentage found that is over the threshold. The intent # is to allow use with mon's "alert exit=value" parameter to allow for # finer-grained alerts based on disk usage. If no disks are over the # threshold, the script will exit with value 0; if an SNMP error # occurs (and there are no other errors), the script will exit with # value 2. mon-contrib-1.0+dfsg/monitors/netsnmp/netsnmp-freespace/netsnmp-freespace.monitor3000066400000000000000000000170241160532374600306230ustar00rootroot00000000000000#!/usr/bin/perl # # Monitor diskspace via SNMP # (based on process.monitor by Brian Moore) # # Modified Oct 2001 by Dan Urist # Changes: added usage, SNMP v.3 support, -T threshold option and # unique-ified errors # # Modified Feb 2002 by Dan Urist # Changes: added -C config file option; cleaned up code # # This script will exit with value 1 if host:community has dskErrorFlag # set. The summary output line will be the host names that failed # and the disk information. The detail lines are what UCD snmp returns # for an dskErrMessage. ('/filesystem: less than WATERMARK free (= CURRENT)'). # If there is an SNMP error (either a problem with the SNMP libraries, # or a problem communicating via SNMP with the destination host), # this script will exit with a warning value of 2. # # If the -T threshold option is used, the script will exit with the # highest disk percentage found that is over the threshold. The intent # is to allow use with mon's "alert exit=value" parameter to allow for # finer-grained alerts based on disk usage. If no disks are over the # threshold, the script will exit with value 0; if an SNMP error # occurs (and there are no other errors), the script will exit with # value 2. # # Copyright (C) 2001 SATOH Fumiyasu # # 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; either version 2 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA # use SNMP; use Getopt::Std; $ENV{'MIBS'} = "UCD-SNMP-MIB"; getopts("hT:" . &SNMPconfig("getopts")); my $VERSION = "0.3"; if( $opt_h || (scalar @ARGV == 0) ){ print join("\n", "$0 Version $VERSION; original version by SATOH Fumiyasu ", "SNMP v.3 support by Daniel J. Urist .", "\n", ); print "Usage: $0 OPTIONS host [host ...]\n"; print "Options:\n"; print join("\n\t", "\t-h # Usage", "[-T threshold] # Exit value is highest disk % over threshold", &SNMPconfig("usage"), "\n"); exit 2; } # Get SNMP options my %SNMPARGS = &SNMPconfig; my $Threshold = $opt_T if defined($opt_T); my $RETVAL = 0; my %Failures; my %Longerr; my $Session; foreach $host (@ARGV) { $Session = new SNMP::Session( DestHost => $host, %SNMPARGS, ); unless( defined($Session) ) { $RETVAL = 2 if $RETVAL == 0; # Other errors take precedence over SNMP error push @{$Failures{$host}}, "session error"; $Longerr{"$host could not get SNMP session"} = ""; next; } my $v = new SNMP::Varbind (["dskIndex"]); $Session->getnext ($v); while (!$Session->{"ErrorStr"} && $v->tag eq "dskIndex") { my @q = $Session->get ([ ["dskPath", $v->iid], # 0 ["dskDevice", $v->iid], # 1 ["dskMinimum", $v->iid], # 2 ["dskMinPercent", $v->iid], # 3 ["dskTotal", $v->iid], # 4 ["dskAvail", $v->iid], # 5 ["dskUsed", $v->iid], # 6 ["dskPercent", $v->iid], # 7 ["dskPercentNode", $v->iid],# 8 ["dskErrorFlag", $v->iid], # 9 ["dskErrorMsg", $v->iid], # 10 ]); last if ($Session->{"ErrorStr"}); if( defined $Threshold ){ if($q[7] > $Threshold){ $RETVAL = $q[7] if $q[7] > $RETVAL; my ($t, $u, $a) = map { int($_/1024) } @q[4, 6, 5]; push @{$Failures{$host}}, $q[0] . " ($q[7]%)"; $Longerr{"$host:$q[0]($q[1]) total=$t used=$u($q[7]%) free=$a threshold=$Threshold%"} = ""; } } elsif ($q[9] > 0) { $RETVAL = 1; my ($t, $u, $a) = map { int($_/1024) } @q[4, 6, 5]; push @{$Failures{$host}}, $q[0] . " ($q[7]%)"; $Longerr{"$host:$q[0]($q[1]) total=$t used=$u($q[7]%) free=$a err=$q[10]"} = ""; } $Session->getnext ($v); } if ($Session->{"ErrorStr"}) { $RETVAL = 2 if $RETVAL == 0; # Other errors take precedence over SNMP error push(@{$Failures{$host}}, "SNMP error"); $Longerr{"$host returned an SNMP error: " . $Session->{"ErrorStr"}} = ""; } } if (scalar keys %Failures) { my $h; my @errs; foreach $h ( sort keys %Failures ){ push( @errs, $h . ':' . join(',', @{$Failures{$h}}) ); } print join(";", @errs), "\n\n"; print join ("\n", sort keys %Longerr), "\n"; } exit $RETVAL; # # Manage the standard SNMP options # Arguments are same as netsnmp utils # # If called with "getopts", returns a string for "getopts" # If called with "usage", returns an array of usage information # Otherwise, returns a hash of SNMP config vars # # Overloading this sub like this is kinda hoakey, # but keeps everything in one place sub SNMPconfig { my($action) = @_; if($action eq "getopts"){ return "C:t:r:p:v:u:l:A:e:E:n:a:x:X:"; } elsif($action eq "usage"){ return( "[-C configfile] # SNMP vars config file", "[-t Timeout] # Timeout in ms (default: 1000000)", "[-r Retries] # Retries before failure (default: 5)", "[-p RemotePort] # Remote UDP port (default 161)", "[-v Version] # 1,2,2c or 3 (default: 1)", "[-c Community] # v.1,2,2c Community Name (default: public)", "[-u SecName] # v.3 Security Name (default: initial)", "[-l SecLevel] # v.3 Security Level (default: noAuthNoPriv)", "[-A AuthPass] # v.3 Authentication Passphrase (default: none)", "[-e SecEngineId] # v.3 security engineID (default: none)", "[-E ContextEngineId] # v.3 context engineID (default: none)", "[-n Context] # v.3 context name (default: none)", "[-a AuthProto] # authentication protocol (MD5|SHA; default MD5)", "[-x PrivProto] # privacy protocol (DES)", "[-X PrivPass] # privacy passphrase (default: none)", ); } # Read config file my %Conf; if($opt_C){ unless( open(CONF, $opt_C) ){ print "$0: Could not open config file $opt_C\n"; exit 2; } my $line; my @fields; foreach $line (){ chomp $line; @fields = split(/=/, $line); $Conf{ lc $fields[0] } = $fields[1]; } close CONF; } my %SNMPARGS; # Common options $SNMPARGS{Timeout} = $opt_t || $Conf{timeout} || 1000000; $SNMPARGS{Retries} = $opt_r || $Conf{retries} || 5; $SNMPARGS{RemotePort} = $opt_p || $Conf{remoteport} || 161; $SNMPARGS{Version} = $opt_v || $Conf{version} || 1; # v. 3 options if ($SNMPARGS{Version} eq "3"){ $SNMPARGS{SecName} = $opt_u || $Conf{secname} || 'initial'; $SNMPARGS{SecLevel} = $opt_l || $Conf{seclevel} || 'noAuthNoPriv'; $SNMPARGS{AuthPass} = $opt_A || $Conf{authpass} || ''; $SNMPARGS{SecEngineId} = $opt_e || $Conf{secengineid} || ''; $SNMPARGS{ContextEngineId} = $opt_E || $Conf{contextengineid} || ''; $SNMPARGS{Context} = $opt_n || $Conf{context} || ''; $SNMPARGS{AuthProto} = $opt_a || $Conf{authproto} || ''; $SNMPARGS{PrivProto} = $opt_x || $Conf{privproto} || ''; $SNMPARGS{PrivPass} = $opt_X || $Conf{privpass} || ''; } # v. 1,2 options else{ $SNMPARGS{Community} = $opt_c || $Conf{community} || 'public'; } return %SNMPARGS; } mon-contrib-1.0+dfsg/monitors/netsnmp/netsnmp-proc/000077500000000000000000000000001160532374600225125ustar00rootroot00000000000000mon-contrib-1.0+dfsg/monitors/netsnmp/netsnmp-proc/netsnmp-proc.monitor000077500000000000000000000162771160532374600265700ustar00rootroot00000000000000#!/usr/bin/perl # # Monitor processes via SNMP # (based on process.monitor by Brian Moore) # # Modified Oct 2001 by Dan Urist # Changes: added usage, SNMP v.3 support, -P processes option # unique-ified errors # # Modified Feb 2002 by Dan Urist # Changes: added -C config file option; cleaned up code # # This script will exit with value 1 if any prErrorFlag is greater # than 0. The summary output line will be the host names and # processes that failed in the format host1:proc1,proc2;host2:proc3... # The detail lines are what UCD snmp returns for a prErrMessage. If # there is an SNMP error (either a problem with the SNMP libraries, or # a problem communicating via SNMP with the destination host), this # script will exit with a warning value of 2. If the -P process list # option is used, only the listed processes will be monitored. If a # process given with -P is not being monitored, the script will exit # with a warning and a value of 2. # # # Copyright (C) 2001 Daniel J. Urist # # 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; either version 2 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA # use SNMP; use Getopt::Std; $ENV{'MIBS'} = "UCD-SNMP-MIB"; getopts("hP:" . &SNMPconfig("getopts")); my $VERSION = "0.3"; if( $opt_h || (scalar @ARGV == 0) ){ print join("\n", "$0 Version $VERSION; original version by Brian Moore,", "SNMP v.3 support by Daniel J. Urist .", "\n", ); print "Usage: $0 OPTIONS host [host ...]\n"; print "Options:\n"; print join("\n\t", "\t-h # Usage", "[-P proc[,proc...]]] # Processes to look for", &SNMPconfig("usage"), "\n"); exit 2; } # Get SNMP options my %SNMPARGS = &SNMPconfig; # Get process list my @Processes = split(',', $opt_P) if defined $opt_P; my $RETVAL = 0; my %Failures; my %Longerr; my $Session; foreach $host (@ARGV) { $Session = new SNMP::Session( DestHost => $host, %SNMPARGS, ); unless( defined($Session) ) { $RETVAL = 2 if $RETVAL == 0; # Other errors take precedence over SNMP error push @{$Failures{$host}}, "session error"; $Longerr{"$host could not get SNMP session"} = ""; next; } my $v = new SNMP::Varbind (["prIndex"]); $Session->getnext ($v); my @Found; while (!$Session->{"ErrorStr"} && $v->tag eq "prIndex") { my @q = $Session->get ([ ["prNames", $v->iid], # 0 ["prMin", $v->iid], # 1 ["prMax", $v->iid], # 2 ["prCount", $v->iid], # 3 ["prErrorFlag", $v->iid], # 4 ["prErrMessage", $v->iid], # 5 ["prErrFix", $v->iid], # 6 ]); last if ($Session->{"ErrorStr"}); if(@Processes){ if( grep(/^$q[0]$/, @Processes) ){ # Keep track of which processes from the list we actually found push(@Found, $q[0]); } else{ $Session->getnext ($v); next; } } if ($q[4] > 0) { $RETVAL = 1; push @{$Failures{$host}}, $q[0]; $Longerr{"$host:$q[0] Count=$q[3] Min=$q[1] Max=$q[2]"} = ""; } $Session->getnext ($v); } if ($Session->{"ErrorStr"}) { $RETVAL = 2 if $RETVAL == 0; # Other errors take precedence over SNMP error push @{$Failures{$host}}, "SNMP error"; $Longerr{"$host returned an SNMP error: " . $Session->{"ErrorStr"}} = ""; } if(@Processes){ my $p; foreach $p (@Processes){ if( !grep(/^$p$/, @Found)){ $RETVAL = 2 if $RETVAL == 0; push @{$Failures{$host}}, "process \"$p\" not monitored"; $Longerr{"process \"$p\" not monitored on host $host"} = ""; } } } } if (scalar keys %Failures) { my $f; my @m; foreach $f (keys %Failures){ push(@m, $f . ":" .join(",", @{$Failures{$f}})); } print join(";", @m), "\n\n"; print join ("\n", sort keys %Longerr), "\n"; } exit $RETVAL; # # Manage the standard SNMP options # Arguments are same as netsnmp utils # # If called with "getopts", returns a string for "getopts" # If called with "usage", returns an array of usage information # Otherwise, returns a hash of SNMP config vars # # Overloading this sub like this is kinda hoakey, # but keeps everything in one place sub SNMPconfig { my($action) = @_; if($action eq "getopts"){ return "C:t:r:p:v:u:l:A:e:E:n:a:x:X:"; } elsif($action eq "usage"){ return( "[-C configfile] # SNMP vars config file", "[-t Timeout] # Timeout in ms (default: 1000000)", "[-r Retries] # Retries before failure (default: 5)", "[-p RemotePort] # Remote UDP port (default 161)", "[-v Version] # 1,2,2c or 3 (default: 1)", "[-c Community] # v.1,2,2c Community Name (default: public)", "[-u SecName] # v.3 Security Name (default: initial)", "[-l SecLevel] # v.3 Security Level (default: noAuthNoPriv)", "[-A AuthPass] # v.3 Authentication Passphrase (default: none)", "[-e SecEngineId] # v.3 security engineID (default: none)", "[-E ContextEngineId] # v.3 context engineID (default: none)", "[-n Context] # v.3 context name (default: none)", "[-a AuthProto] # authentication protocol (MD5|SHA; default MD5)", "[-x PrivProto] # privacy protocol (DES)", "[-X PrivPass] # privacy passphrase (default: none)", ); } # Read config file my %Conf; if($opt_C){ unless( open(CONF, $opt_C) ){ print "$0: Could not open config file $opt_C\n"; exit 2; } my $line; my @fields; foreach $line (){ chomp $line; @fields = split(/=/, $line); $Conf{ lc $fields[0] } = $fields[1]; } close CONF; } my %SNMPARGS; # Common options $SNMPARGS{Timeout} = $opt_t || $Conf{timeout} || 1000000; $SNMPARGS{Retries} = $opt_r || $Conf{retries} || 5; $SNMPARGS{RemotePort} = $opt_p || $Conf{remoteport} || 161; $SNMPARGS{Version} = $opt_v || $Conf{version} || 1; # v. 3 options if ($SNMPARGS{Version} eq "3"){ $SNMPARGS{SecName} = $opt_u || $Conf{secname} || 'initial'; $SNMPARGS{SecLevel} = $opt_l || $Conf{seclevel} || 'noAuthNoPriv'; $SNMPARGS{AuthPass} = $opt_A || $Conf{authpass} || ''; $SNMPARGS{SecEngineId} = $opt_e || $Conf{secengineid} || ''; $SNMPARGS{ContextEngineId} = $opt_E || $Conf{contextengineid} || ''; $SNMPARGS{Context} = $opt_n || $Conf{context} || ''; $SNMPARGS{AuthProto} = $opt_a || $Conf{authproto} || ''; $SNMPARGS{PrivProto} = $opt_x || $Conf{privproto} || ''; $SNMPARGS{PrivPass} = $opt_X || $Conf{privpass} || ''; } # v. 1,2 options else{ $SNMPARGS{Community} = $opt_c || $Conf{community} || 'public'; } return %SNMPARGS; } mon-contrib-1.0+dfsg/monitors/netsnmp/netsnmp-proc/netsnmp-proc.monitor.README000066400000000000000000000017241160532374600275100ustar00rootroot00000000000000# Monitor processes via SNMP # (based on process.monitor by Brian Moore) # # Modified Oct 2001 by Dan Urist # Changes: added usage, SNMP v.3 support, -P processes option # unique-ified errors # # Modified Feb 2002 by Dan Urist # Changes: added -C config file option; cleaned up code # # This script will exit with value 1 if any prErrorFlag is greater # than 0. The summary output line will be the host names and # processes that failed in the format host1:proc1,proc2;host2:proc3... # The detail lines are what UCD snmp returns for a prErrMessage. If # there is an SNMP error (either a problem with the SNMP libraries, or # a problem communicating via SNMP with the destination host), this # script will exit with a warning value of 2. If the -P process list # option is used, only the listed processes will be monitored. If a # process given with -P is not being monitored, the script will exit # with a warning and a value of 2. mon-contrib-1.0+dfsg/monitors/netsnmp/process-full-command-line/000077500000000000000000000000001160532374600250445ustar00rootroot00000000000000mon-contrib-1.0+dfsg/monitors/netsnmp/process-full-command-line/process-full-command-line.monitor000077500000000000000000000063621160532374600334460ustar00rootroot00000000000000#!/usr/bin/perl # # Monitor snmp processes by reading the full command line. # Completely client-side. Do not use prTable but the standard "host" MIB. # # Arguments are: # # [-c community] -p regexp-on-the-command-line [-p regexp-on-the-command-line...] host [host ...] # # $Id: process-full-command-line.monitor,v 1.1.1.1 2005/02/18 17:52:23 trockij Exp $ # # # Copyright (C) 1998, Stephane Bortzmeyer # # 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; either version 2 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA # use SNMP; use Getopt::Long; GetOptions("c=s" => \$community, "p=s" => \@processes_re, "d+" => \$debug); if (! $community) { $community = 'public'; } if (! $#process_re) { die "At least one process name must be specified (reg. exp. are allowed)"; } $RETVAL = 0; foreach $host (@ARGV) { $session = new SNMP::Session(DestHost => $host, Community => $community); undef %processes; if (!defined ($session)) { $RETVAL = ($RETVAL == 1) ? 1 : 2; push @failures, "$host session error"; push @longerr, "$host could not get SNMP session"; next; } my $v = new SNMP::Varbind (["hrSWRunTable"]); $session->getnext ($v); while (!$session->{"ErrorStr"} && ($v->tag =~ /^hrSWRun/)) { my @q = $session->get ([ ["hrSWRunName", $v->iid], ["hrSWRunParameters", $v->iid], ]); last if ($session->{"ErrorStr"}); $command_line = $q[0] . ' ' . $q[1]; $processes{$command_line}++; $session->getnext ($v); } if ($session->{"ErrorStr"}) { push (@failures, $host); push (@longerr, "$host returned an SNMP error: " . $session->{"ErrorStr"}); $host_retval = 1; } else { $host_retval = 0; undef $missing_processes; All_regexps: foreach $process_re (@processes_re) { undef $process_found; All_processes: foreach $cl (keys (%processes)) { if ($debug >= 3) { print STDERR "TEST: \"$cl\" against \"$process_re\" on $host\n"; } if ($cl =~ m!$process_re!) { $process_found = 1; if ($debug) { print STDERR "MATCH: \"$cl\" against \"$process_re\" on $host\n"; } last All_processes; } } if (! $process_found) { $host_retval = 1; if ($missing_processes) { $missing_processes .= (", " . $process_re); } else { $missing_processes = $process_re; } } } if ($host_retval != 0) { push (@failures, $host); push (@longerr, "$host miss process: " . $missing_processes); } } if ($host_retval == 1) { $RETVAL = 1; } } if ($RETVAL == 1) { print join (", ", @failures), "\n", "\n"; print join ("\n", @longerr), "\n"; } exit $RETVAL; process-full-command-line.monitor.README000066400000000000000000000003751160532374600343160ustar00rootroot00000000000000mon-contrib-1.0+dfsg/monitors/netsnmp/process-full-command-line# Monitor snmp processes by reading the full command line. # Completely client-side. Do not use prTable but the standard "host" MIB. # # Arguments are: # # [-c community] -p regexp-on-the-command-line [-p regexp-on-the-command-line... ] host [host ...] mon-contrib-1.0+dfsg/monitors/netware/000077500000000000000000000000001160532374600200465ustar00rootroot00000000000000mon-contrib-1.0+dfsg/monitors/netware/netwarefree/000077500000000000000000000000001160532374600223555ustar00rootroot00000000000000mon-contrib-1.0+dfsg/monitors/netware/netwarefree/CHANGES000066400000000000000000000006041160532374600233500ustar00rootroot00000000000000Version 1.2.0 P.Holzleitner Changed to numeric OIDs so the MIB file is no longer needed Merged regular and --list processing Made error messages consistent (host[/volume]: problem) Improved error handling, now checks for 'missing' volumes etc. Uses ./netwarefree.cf if present for easy testing Version 1.1.0 P.Holzleitner initial public release mon-contrib-1.0+dfsg/monitors/netware/netwarefree/README000066400000000000000000000013141160532374600232340ustar00rootroot00000000000000Quick Start: Make sure SERVINST.NLM is loaded on Novell server Make sure you have UCD SNMP 3.6.2+ and the Perl SNMP module installed Copy netwarefree.mon to your mon.d directory Copy netwarefree.cf to /etc/mon and edit to match your needs Test from mon.d directory with ./netwarefree.monitor -l host1 host2 ... Add watch/service to mon.cf, using netwarefree.monitor Common commandline options: --config=/path/to/netwarefree.cf if neither /etc/mon nor /usr/lib/mon/etc --community=your_SNMP_read_community if not 'public' Basic Troubleshooting: use netwarefree.monitor --list option to see variable values use snmpwalk your_hostname public .1 | less to verify SNMP agent mon-contrib-1.0+dfsg/monitors/netware/netwarefree/netwarefree.cf000066400000000000000000000012621160532374600251770ustar00rootroot00000000000000# # netwarefree.cf - configuration file for netwarefree.monitor # # Format: # # host volname free # # host hostname of the NetWare server, should correspond with # a host defined in the host group # # volname The name of the volume to check, e.g. "SYS" # # free The amount of free space which will trigger a failure, # expressed as "10kb", "10MB", or "10GB" # novserv1 SYS 100MB novserv2 SYS 100MB novserv3 SYS 100MB novserv4 SYS 100MB novserv5 SYS 100MB novserv6 SYS 100MB novserv1 DATA 200MB novserv2 DATA 200MB novserv3 DATA 200MB novserv4 DATA 200MB novserv5 DATA 200MB novserv6 DATA 200MB mon-contrib-1.0+dfsg/monitors/netware/netwarefree/netwarefree.monitor000077500000000000000000000171671160532374600263140ustar00rootroot00000000000000#!/usr/bin/perl # ##################################################################### ## ## ## netwarefree.monitor Version 1.2.0 ## ## 2001-03-28 ## ## Copyright (C) 2000-2001 ## ## Peter Holzleitner (peter@holzleitner.com) ## ## ## ##################################################################### # # Synopsis: # # Uses SNMP to check available disk space on Novell NetWare servers. # # Exits with value of 1 if available space on any host drops below # the configured value, or exits with the value of 2 if there is a # connection or configuration error. # # Requirements: # # Requires the UCD SNMP library (3.6.2 or higher) # and G.S. Marzot's Perl SNMP module (from CPAN). # # The NetWare server needs to have the SERVINST.NLM loaded, which # is the SNMP agent extension implementing the Netware-Server-MIB. # (Version 1.00 of SERVINST.NLM has a 4GB overflow problem; upgrade # to 1.01 dated 2/12/98, contained in Novell patch mwnma4a.exe, or higher.) # # # Arguments: # # [--community=cmn] [--timeout=n] [--retries=n] # [--config=configfile] [--list[=linesperpage]] serverlist # # For every host name passed on the command line, netwarefee.monitor # walks the nwFSVolTable MIB subtree and compares the amount of available # space (available := free + freeable) to the values configured in # netwarefree.cf. # # This monitor looks for configuration files in the current directory, # in /etc/mon and /usr/lib/mon/etc. Command line option --config # overrides the location of the configuration file. # # For the configuration file format, please refer to the sample file. # # When invoked with the --list option, the output format is changed # into a more human-readable form used to check and troubleshoot the # configuration. This option must not be used from within MON as # no status and summary output are provided. # # # Written by Peter Holzleitner # (originally based on netappfree.monitor by Jim Trocki) # # # History: # # 1.2.0 28 Mar 2001 P.H. MIB no longer needed; extended error checking # 1.1.0 27 Jan 2000 P.H. initial public release # 1.0.0 15 Jan 2000 P.H. internal test version # # # 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; either version 2 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software Foundation, # Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA # # use SNMP; use English; use Getopt::Long; sub list; sub readcf; sub toKB; # no MIB needed, we're using numeric OIDs $ENV{"MIBS"} = ''; GetOptions (\%opt, "community=s", "timeout=i", "retries=i", "config=s", "list:i", "debug"); die "no host arguments\n" if (@ARGV == 0); $RET = 0; @ERRS = (); @HOSTS = (); $COMM = $opt{"community"} || "public"; $TIMEOUT = $opt{"timeout"} * 1000 * 1000 || 5000000; $RETRIES = $opt{"retries"} || 8; $CONFIG = $opt{"config"} || (-d "/etc/mon" ? "/etc/mon" : "/usr/lib/mon/etc") . "/netwarefree.cf"; # pick up local configuration file for testing $CONFIG = "./netwarefree.cf" if -e "./netwarefree.cf"; $LIST = defined $opt{"list"}; $FORMAT_LINES_PER_PAGE = $opt{'list'} || 25; $DEBUG = $opt{"debug"}; print STDERR "Using configuration file $CONFIG\n" if $DEBUG; ($nwID, $nwName, $nwSize, $nwFree, $nwFreeable) = (0..4); $nwVolID = '.1.3.6.1.4.1.23.2.28.2.14.1.1'; $nwVolPhysicalName = '.1.3.6.1.4.1.23.2.28.2.14.1.2'; $nwVolSize = '.1.3.6.1.4.1.23.2.28.2.14.1.3'; $nwVolFree = '.1.3.6.1.4.1.23.2.28.2.14.1.4'; $nwVolFreeable = '.1.3.6.1.4.1.23.2.28.2.14.1.5'; readcf ($CONFIG) || die "could not read config: $!\n"; foreach $host (@ARGV) { $size = $free = '---'; $ok = 'ERR'; if (!defined $FREE{$host}) { $RET = 2 unless $RET > 2; push (@HOSTS, $host); push (@ERRS, "$host: Host not configured"); $fsname = 'not configured'; write if($LIST); next; } if (!defined($s = new SNMP::Session (DestHost => $host, Timeout => $TIMEOUT, Community => $COMM, Retries => $RETRIES))) { $RET = 2 unless $RET > 2; push (@HOSTS, $host); push (@ERRS, "$host: Could not create session " . $SNMP::Session::ErrorStr); delete $FREE{$host}; $fsname = 'session error'; write if($LIST); next; } $v = new SNMP::VarList ( [$nwVolID], [$nwVolPhysicalName], [$nwVolSize], [$nwVolFree], [$nwVolFreeable], ); while (defined $s->getnext($v)) { $tag = $v->[$nwID]->tag; $sizeK = $v->[$nwSize]->val; $size = int($sizeK / 1024); $freeK = $v->[$nwFree]->val + $v->[$nwFreeable]->val; $free = int($freeK / 1024); $fsname = $v->[$nwName]->val; $ok = $freeK < $FREE{$host}{$fsname} ? "LOW" : "OK"; $ok = "n/c" unless defined $FREE{$host}{$fsname}; print "DEBUG: HOST=$host TAG=$tag FS=$fsname SIZE=$size FREE=$free\n" if $DEBUG; last if $tag !~ /$nwVolID/; write if $LIST; if ( $freeK < $FREE{$host}{$fsname}) { $RET = 1 unless $RET > 1; push (@HOSTS, $host); push (@ERRS, sprintf ("%s/%s: Space LOW (%.0fMB free)", $host, $fsname, $free)); } delete $FREE{$host}{$fsname}; } if ($s->{ErrorNum}) { $RET = 2 unless $RET > 2; push (@HOSTS, $host); push (@ERRS, "$host: Could not get nwVolID; " . $s->{ErrorStr}); } } # foreach $host(@ARGV) # check for leftover configured volumes that haven't been seen yet foreach $host (keys %FREE) { $vols = $FREE{$host}; push (@HOSTS, $host) if (scalar keys %$vols) && !(scalar grep /^$host$/, @HOSTS); foreach $fsname (keys %$vols) { $size = $free = 'NOT FOUND'; $ok = 'ERR'; write if $LIST; push (@ERRS, "$host/$fsname: Volume not found"); } } exit $RET if $LIST; if ($RET) { my @H = sort @HOSTS; my $e = join("\n", sort @ERRS); print "@H\n\n$e\n"; } exit $RET; # # read configuration file # sub readcf { my ($f) = @_; my ($l, $host, $filesys, $free); open (CF, $f) || return undef; while () { next if (/^\s*#/ || /^\s*$/); chomp; ($host, $filesys, $free) = split; # ignore hosts not tested this time next unless (scalar grep /^$host$/, @ARGV); if (!defined ($FREE{$host}{$filesys} = toKB ($free))) { die "error in free space specification, config $f, line $.\n"; } } close (CF); } sub toKB { my ($free) = @_; my ($n, $u); if ($free =~ /^(\d+\.\d+)(kb|mb|gb)$/i) { ($n, $u) = ($1, "\L$2"); } elsif ($free =~ /^(\d+)(kb|mb|gb)$/i) { ($n, $u) = ($1, "\L$2"); } else { return undef; } return (int ($n * 1024)) if ($u eq "mb"); return (int ($n * 1024 * 1024)) if ($u eq "gb"); int ($n); } format STDOUT_TOP = Server Volume MB total MB free Status ------------------------------------------------------------------------- . format STDOUT = @<<<<<<<<<<<<<< @<<<<<<<<<<<<<<<<<<<< @>>>>>>>>>> @>>>>>>>>>> @>>>>> $host, $fsname, $size, $free, $ok . mon-contrib-1.0+dfsg/monitors/oracle/000077500000000000000000000000001160532374600176465ustar00rootroot00000000000000mon-contrib-1.0+dfsg/monitors/oracle/sqlconn/000077500000000000000000000000001160532374600213235ustar00rootroot00000000000000mon-contrib-1.0+dfsg/monitors/oracle/sqlconn/sqlconn.monitor000066400000000000000000000051701160532374600244140ustar00rootroot00000000000000From duncanl@demon.net Mon Aug 23 06:51:17 1999 Date: Fri, 06 Aug 1999 15:59:30 +0100 From: Duncan Lawie To: mon@linux.kernel.org Subject: sqlconn.monitor Hi, herewith a monitor which checks on sqlnet connections. It uses DBI but, as it stands, is coded in an Oracle-specific way. The matching mon.cf lines would look something like this hostgroup first_db second_db watch ora_dbs service sqlconnect interval 15m monitor sqlconn.monitor period wd {Mon-Fri} hr {9am-5pm} alert mail.alert duncanl@demon.net alertevery 1h period wd {Sat-Sun} alert mail.alert duncanl@demon.net There is an element of hack in that the hostgroup is actually a list of database names, not unix hosts. I am a little uncomfortable (as yet) with GPL, but as I understand it I can sidestep the issue by making this open source under the terms of perl. I also understand that if it were intergrated into mon it would them be distributed under the GPL along with mon. Can anyone offer me enlightenment on this issue? Duncan. #!/usr/local/bin/perl -w # # Monitor sqlnet connection # # Arguments are: names of databases (as understood by listener) # # Available under the same terms as perl itself if distributed alone. # # use Local::Env; # local environment variable setting use DBI; $dbuser = $ENV{ORACLE_USERID}; # from Local::Env or set it explicitly foreach $dbname (@ARGV) { unless ( eval { $dbh = DBI->connect("dbi:Oracle:$dbname", $dbuser, '', { RaiseError => 1, AutoCommit => 1 }) } ) { push @failures, "$dbname connect"; push @longerr, "$dbname: $DBI::errstr"; $retval++; next } unless ( $sth = $dbh->prepare("select sysdate from sys.dual") ) { push @failures, "$dbname prepare"; push @longerr, "$dbname: $dbh->errstr"; $retval++; next } unless ( $sth->execute() ) { push @failures, "$dbname execute"; push @longerr, "$dbname: $dbh->errstr"; $retval++; next } unless ( $sth->finish() ) { push @failures, "$dbname finish"; push @longerr, "$dbname: $dbh->errstr"; $retval++; next } unless ( $dbh->disconnect ) { push @failures, "$dbname disconnect"; push @longerr, "$dbname: $dbh->errstr"; $retval++; next } } if (@failures) { print join (", ", @failures), "\n"; print join ("\n", @longerr), "\n"; } exit $retval; mon-contrib-1.0+dfsg/monitors/oracle/sqlconn/sqlconn.monitor.README000066400000000000000000000021221160532374600253420ustar00rootroot00000000000000From duncanl@demon.net Mon Aug 23 06:51:17 1999 Date: Fri, 06 Aug 1999 15:59:30 +0100 From: Duncan Lawie To: mon@linux.kernel.org Subject: sqlconn.monitor Hi, herewith a monitor which checks on sqlnet connections. It uses DBI but, as it stands, is coded in an Oracle-specific way. The matching mon.cf lines would look something like this hostgroup first_db second_db watch ora_dbs service sqlconnect interval 15m monitor sqlconn.monitor period wd {Mon-Fri} hr {9am-5pm} alert mail.alert duncanl@demon.net alertevery 1h period wd {Sat-Sun} alert mail.alert duncanl@demon.net There is an element of hack in that the hostgroup is actually a list of database names, not unix hosts. I am a little uncomfortable (as yet) with GPL, but as I understand it I can sidestep the issue by making this open source under the terms of perl. I also understand that if it were intergrated into mon it would them be distributed under the GPL along with mon. Can anyone offer me enlightenment on this issue? Duncan. mon-contrib-1.0+dfsg/monitors/ospf/000077500000000000000000000000001160532374600173505ustar00rootroot00000000000000mon-contrib-1.0+dfsg/monitors/ospf/ospf.monitor000077500000000000000000000132261160532374600217370ustar00rootroot00000000000000#!/usr/bin/perl # # Router ospf (Open Shortest Path First) monitor # Look at each router and get the status of all OSPF neighbors. # Issue alarm if any interfaces configured for neighbors do not # have a full adjacencies # Detail log shows status of all enabled OSPF interfaces. # Usage: # ospf.monitor [--exclude pattern] [--community str] router1 [...] # # --exclude - don't alarm for IP addresses that match . Periods # in the IP address will be escaped so that they only match periods. Use # [0-9] or the like if you need character class matching. Use 'ip|ip|ip' # to exclude multiple peers. # # --community - SNMPv1 community name to use. But it's more secure # to pass the community in via the environment variable COMMUNITY. # # Edit history below # Version 0.1 # # By Ed Ravin This code is made available courtesy of # PANIX http://www.panix.com. # Copyright 2005, by Ed Ravin # # License: GNU GPL v2, see http://www.gnu.org/copyleft/gpl.html # # Loosely based on bgp.monitor which is: # Copyright 2002, by Marc Hauswirth, Safe Host SA # # Some inspiration is taked from others mon monitors and from # routerinfo.pl by Ben Buxton (bb@zipworld.net), also under GPL, see http://www.zipworld.com.au/~bb/linux/ # and from routerint.monitor by P. Strauss (philou@philou.ch) and me self (marc@safehostnet.com). # # This script need the SNMP Session module from Simon Leinen # Wich you could found under http://www.switch.ch/misc/leinen/snmp/perl/ # It is also part of MRTG (http://people.ee.ethz.ch/~oetiker/webtools/mrtg/) use SNMP; use SNMP_Session; use Getopt::Long; use strict; my %opt; $opt{'community'}= undef; $opt{'exclude'}= ""; $opt{'debug'}= undef; my $usage="Usage: [COMMUNITY=str] ospf.monitor [--exclude regexp] [--community str] [--timeout usecs] [--version N] [--retries nn] router [...]\n"; GetOptions(\%opt, "exclude=s", "community=s", "timeout=i", "version=i", "retries=i", "debug") or die $usage; # It's highly unlikely someone wants dots in an IP address to be treated # as a regexp pattern, so we'll escape them to make behavior more predictable. # If you really want to use pattern matching, use a character class like # [0-9] instead. $opt{exclude} =~ s/\./\\./g; $opt{exclude}= '^(' . $opt{exclude} . ')'; $opt{exclude}= "NOT_USED" if $opt{exclude} eq "^()"; ## -- my $community = $opt{'community'} || $ENV{'COMMUNITY'} || "public"; my $timeout= $opt{'timeout'} || 5000000; my $retries= $opt{'retries'} || 3; my $version= $opt{'version'} || 1; ## -- my @failures; my @details; $ENV{'MIBS'}= ""; # all OIDs needed are specified in script # OID's to the SNMP elements that I want to show... # From Cisco's MIB and RFC's # http://sunsite.cnlab-switch.ch/ftp/doc/standard/rfc/16xx/1657 # http://www.telecomm.uh.edu/stats/rfc/BGP4-MIB.html my %oids = ( "SysUptime" => "1.3.6.1.2.1.1.3.0", "ifDescr" => "1.3.6.1.2.1.2.2.1.2", "ospfRouterId" => "1.3.6.1.2.1.14.1.1" , "ospfIfIpAddress" => "1.3.6.1.2.1.14.7.1.1" , "ospfAddressLessIf" => "1.3.6.1.2.1.14.7.1.2" , "ospfIfAdminStat" => "1.3.6.1.2.1.14.7.1.5" , "ospfIfState" => "1.3.6.1.2.1.14.7.1.12" , ); my %ospfIfStates = ( 1 => "down", 2 => "loopback", 3 => "waiting", 4 => "pointToPoint", 5 => "designatedRouter", 6 => "backupDesignatedRouter", 7 => "otherDesignatedRouter", ); my %ospfAdminStatus = ( 1 => "enabled", 2 => "disabled", ); use vars qw($router); sub snmpget1 # session, oid-hashstr, instance { my $session= shift; my $oidstr= shift; my $instance = shift; my $result= $session->get(".$oids{$oidstr}.$instance"); if ($session->{ErrorNum}) { push @failures, $router; push @details, "$router: error on SNMP get of $oidstr.$instance: $session->{ErrorStr}"; return 0; } return $result; } foreach $router (@ARGV) { # Get some infos about this router my $sess = new SNMP::Session ( DestHost => $router, Community => $community, Version=> $version, Timeout=> $timeout, Retries=> $retries, ); if (!defined($sess)) { push @failures, $router; push @details, "$router: cannot create SNMP session"; next; } my $ospfRouterID = snmpget1($sess, "ospfRouterId", "0") || next; push @details, "$router (Router-ID $ospfRouterID)"; # Find the indexes of the interfaces with OSPF enabled my @ospfinterfaces; my $vars = new SNMP::VarList([$oids{ospfIfAdminStat}]); for (my @vals = $sess->getnext($vars); $vars->[0]->tag =~ /1\.3\.6\.1\.2\.1\.14\.7\.1\.5/ # still in table (Did you have a cleaner solutions ?) and not $sess->{ErrorStr}; # and not end of mib or other error @vals = $sess->getnext($vars)) { my $textIfAdminStatus = $ospfAdminStatus{$vals[0]}; push @ospfinterfaces, $vars->[0]->tag if $textIfAdminStatus eq "enabled"; } # trim down OID to keep just the interface part, which we will use # shortly as an instance ID map {s/^\.$oids{ospfIfAdminStat}\.//} @ospfinterfaces; foreach my $int (@ospfinterfaces) { my $ifstate = snmpget1($sess, "ospfIfState", "$int"); my $ifinfo= $int; if ($int =~ /0\.0\.0\.0\.(\d+)$/) { my $ifindex= $1; $ifinfo= snmpget1($sess, "ifDescr", $ifindex) . " (.$ifindex)"; } push @details, sprintf("$router: Interface %-23s %-15s",$ifinfo, $ospfIfStates{$ifstate}); # if ospfIfState not in [4..7] (OSPF full adjacency states) if ($ifstate < 4 or $ifstate > 7) { push @failures, $router unless $int =~ /$opt{exclude}\b/ or grep(/^$router$/, @failures); $details[$#details] .= " [NO ADJACENCY]"; } } } if (@failures) { print join(' ', @failures), "\n"; }; if (@details) { print "\n"; print join("\n", @details), "\n"; } if (@failures) { # Error state exit exit 1; } else { # Correct exit exit 0; }; mon-contrib-1.0+dfsg/monitors/postgres/000077500000000000000000000000001160532374600202475ustar00rootroot00000000000000mon-contrib-1.0+dfsg/monitors/postgres/postgresql/000077500000000000000000000000001160532374600224525ustar00rootroot00000000000000mon-contrib-1.0+dfsg/monitors/postgres/postgresql/postgresql.monitor000066400000000000000000000061351160532374600262730ustar00rootroot00000000000000#!/usr/bin/perl # # $Id: postgresql.monitor,v 1.1.1.1 2005/02/18 17:52:24 trockij Exp $ # $Revision: 1.1.1.1 $ # $Author: trockij $ # #Usage: postresql.monitor [options] # # --database= indicates the database to which is connected # --username= DB-User which is used to connect to the DB # --password= DB-Password which is used to connect to the DB # --host= Host of the Database (optional,default=localhost) # --port= Port on which you want to connect (optional,default=5432) # # a monitor to determine if a PostgreSQL database server is operational # # Rather than use tcp.monitor to ensure that your SQL server is responding # on the proper port, this attempts to connect to and list the databases # on a given database server. # # This monitor requires the perl5 DBI, DBD::mSQL and DBD::mysql modules, # available from CPAN (http://www.cpan.org) # # Copyright (C) 2001, CubIT IT Solutions # Written by Severin Luftensteiner # # 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; either version 2 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA # use DBI; use Getopt::Long; GetOptions( \%options,"port=s", "username=s", "password=s", "database=s", "host=s" ); # uncomment these two lines and provide suitable information if you don't # want to pass sensitive information on the command line #$options{username} ||= "username"; #$options{password} ||= "password"; $mode="Pg"; if ($options{host} eq ""){ $options{"host"=>"localhost"}; } if ($options{port} eq ""){ $options{"port"=>"5432"}; } if (($options{username} eq "") || ($options{password} eq "") || ($options{database} eq "")){ print < indicates the database to which is connected --username= DB-User which is used to connect to the DB --password= DB-Password which is used to connect to the DB --host= Host of the Database (optional,default=localhost) --port= Port on which you want to connect (optional,default=5432) EOP1 die(); } my( $dbh ) = DBI->connect( "DBI:$mode:dbname=$options{database};$options{host};$options{port}", $options{username}, $options{password} ); if( ! $dbh ) { push( @failures, "Could not connect to $mode server $host: " . $DBI::errstr ); } if (@failures) { print join (", ", @failures), "\n"; exit 1; }; if ($dbh){ $dbh->disconnect(); } exit 0; mon-contrib-1.0+dfsg/monitors/postgres/postgresql/postgresql.monitor.README000066400000000000000000000033701160532374600272250ustar00rootroot00000000000000# $Id: postgresql.monitor.README,v 1.1.1.1 2005/02/18 17:52:24 trockij Exp $ # $Revision: 1.1.1.1 $ # $Author: trockij $ # #Usage: postresql.monitor [options] # # --database= indicates the database to which is connected # --username= DB-User which is used to connect to the DB # --password= DB-Password which is used to connect to the DB # --host= Host of the Database (optional,default=localhost)# --port= Port on which you want to connect (optional,default=5432) # # a monitor to determine if a PostgreSQL database server is operational # # Rather than use tcp.monitor to ensure that your SQL server is responding # on the proper port, this attempts to connect to and list the databases # on a given database server. # # This monitor requires the perl5 DBI, DBD::mSQL and DBD::mysql modules, # available from CPAN (http://www.cpan.org) # # Copyright (C) 2001, CubIT IT Solutions # Written by Severin Luftensteiner # # 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; either version 2 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA mon-contrib-1.0+dfsg/monitors/printers/000077500000000000000000000000001160532374600202475ustar00rootroot00000000000000mon-contrib-1.0+dfsg/monitors/printers/printmib/000077500000000000000000000000001160532374600220735ustar00rootroot00000000000000mon-contrib-1.0+dfsg/monitors/printers/printmib/printmib.monitor000066400000000000000000000104771160532374600253410ustar00rootroot00000000000000#!/usr/bin/perl # SNMP monitoring of printmib compliant printers # $Id: printmib.monitor,v 1.1.1.1 2005/02/18 17:52:24 trockij Exp $ # Added changes as per information from Andrew Ryan # fixed bug where it would not return error if the device was not a printer # or was not responding to snmp connects # # returns 1 if problem with printer # # Seth Vidal (skvidal@phy.duke.edu) # many portions of this code were hacked out of hpnp.monitor # newer hps don't support the oid specified in hpnp so I wrote this to watch # them - it should work with almost any printmib compliant printer # Copyright (C) 2000, Seth Vidal # # 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; either version 2 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA # #first update under cvs use SNMP; use Getopt::Long; $SNMP::use_long_names=1; $ENV{'MIBS'}="ALL"; $SNMP::use_enums=1; $SNMP::use_sprint_value=1; GetOptions (\%opt, "community=s", "timeout=i", "retries=i"); die "no host arguments\n" if (@ARGV == 0); $COMM = $opt{"community"} || "public"; $TIMEOUT = $opt{"timeout"} * 1000 * 1000 || 2000000; $RETRIES = $opt{"retries"} || 5; $string="prtAlertTable"; my @err; foreach $host (@ARGV) { my $error=0; undef $sess; if (!defined($sess = new SNMP::Session (DestHost => $host, Timeout => $TIMEOUT, Community => $COMM, Retries => $RETRIES))) { push @err, "cannot create SNMP session to $host"; push @hosts, $host; next; } else { my $testvar = new SNMP::Varbind(['printmib.prtChannel.prtChannelTable.prtChannelEntry.prtChannelType.1',1]); my $descr=$sess->get($testvar); if (($descr eq "") || ($sess->{ErrorNum} ne 0)) { push @err, "$host is probably down (or might not be a printer)"; push @hosts, $host; } } my $tablevar = new SNMP::Varbind([$string]); for ($val=$sess->getnext($tablevar); #get the data $tablevar->[$SNMP::Varbind::tag_f] =~ /$string/ #stay in the table and not $sess->{ErrorStr}; $val=$sess->getnext($tablevar)) { @oidname=split(/\./, $tablevar->[$SNMP::Varbind::tag_f]); $uniq{$oidname[-1]}=1; #don't want the whole string just the last section ${$oidname[-1]}{$tablevar->[$SNMP::Varbind::iid_f]}=$val; #stick it into a hash by that name } #at this point all the field names are in a hash for uniqueness called $uniq #and all the data is indexed by the indexnumber in hashes named after the last #portion of the object id tag so I dump the field names to an array grab the #index numbers from any of them (first one in the array)and I print over #them - print how you'd like @fields=keys(%uniq); foreach $index (sort (keys %{$fields[0]})) { if ("$prtAlertCode{$index}" ne "23") { #code 23 is powersaving on most newer hp's if ("$prtAlertCode{$index}" eq "other") { #sometimes powersaving is other on older hp's if ("$prtAlertDescription{$index}" !~ m/SAVE/i) { #so I check for "SAVE" in the descript $error++; push @err, "Error on host $host = $prtAlertDescription{$index}"; } } else { $error++; push @err, "Error on host $host = $prtAlertDescription{$index}"; } } } #clear out the named hashes foreach $field (@fields) { %{$field}=(); } if ($error > 0) { push @hosts, $host } } if ($#hosts > -1) { print "@hosts\n"; print "Errors:\n"; foreach $error (@err) { print "$error\n"; } exit 1; } exit 0;mon-contrib-1.0+dfsg/monitors/printers/printmib/printmib.monitor.README000066400000000000000000000026661160532374600262760ustar00rootroot00000000000000# SNMP monitoring of printmib compliant printers # # You can get a copy of the PRINTER-MIB at: # http://www.simpleweb.org/ietf/mibs/modules/IETF/txt/Printer-MIB # # $Id: printmib.monitor.README,v 1.1.1.1 2005/02/18 17:52:24 trockij Exp $ # Added changes as per information from Andrew Ryan # fixed bug where it would not return error if the device was not a printer # or was not responding to snmp connects # # returns 1 if problem with printer # # Seth Vidal (skvidal@phy.duke.edu) # many portions of this code were hacked out of hpnp.monitor # newer hps don't support the oid specified in hpnp so I wrote this to watch # them - it should work with almost any printmib compliant printer # Copyright (C) 2000, Seth Vidal # # 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; either version 2 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA # mon-contrib-1.0+dfsg/monitors/ps/000077500000000000000000000000001160532374600170235ustar00rootroot00000000000000mon-contrib-1.0+dfsg/monitors/ps/ps.monitor000077500000000000000000000044751160532374600210730ustar00rootroot00000000000000#!/usr/bin/perl # Monitors processes on the local host. Requires Proc::ProcessTable # usage: # monitor ps.monitor ( process:[min]-[max] )+ ;; # # where: # process process name # min optional minimum number of process name running # max optional maxumum number of process name running # # example: # monitor ps.monitor dhcpd3:1-1 syslog-ng:1- ;; #Copyright 2005 Allan Wind # #Permission is hereby granted, free of charge, to any person obtaining a copy of #this software and associated documentation files (the "Software"), to deal in #the Software without restriction, including without limitation the rights to #use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies #of the Software, and to permit persons to whom the Software is furnished to do #so, subject to the following conditions: # #The above copyright notice and this permission notice shall be included in all #copies or substantial portions of the Software. # #THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR #IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, #FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE #AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER #LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, #OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE #SOFTWARE. use Proc::ProcessTable; # parse command line my %watched_processes; while(<@ARGV>) { if(m/([^:]+):([0-9]*)?-([0-9]*)?/) { # $1 is process, $2 is min and $3 is max $watched_processes{$1} = [$2, $3, 0]; } else { print "Cannot parse the argument \"$_\"\n"; } } # read process table and count the processes of interest my $process_table = new Proc::ProcessTable('cache_ttys' => 0 ); foreach $process ( @{$process_table->table} ) { if( defined($watched_processes{$process->fname}) ) { $watched_processes{$process->fname}[2]++; } } # print name:count of processes if needed my $report = 0; for $process (keys(%watched_processes)) { my $count = $watched_processes{$process}[2]; my $min = $watched_processes{$process}[0] || $count; my $max = $watched_processes{$process}[1] || $count; if($min > $count || $max < $count) { $report = 1; print "$process:$watched_processes{$process}[2]\n"; } } exit $report; mon-contrib-1.0+dfsg/monitors/pubcookie/000077500000000000000000000000001160532374600203615ustar00rootroot00000000000000mon-contrib-1.0+dfsg/monitors/pubcookie/pubcookielogin.monitor000077500000000000000000000131541160532374600250120ustar00rootroot00000000000000#!/usr/bin/perl # # Try to authenticate to a pubcookie login server. See http://www.pubcookie.org # User, password and realm can either be specified on the command line # or in the monitor-auth.cf file. # # Arguments are "[-c monitor-auth-config] [-u user] [-p pass] [-r realm] [-t timeout] host [host...]" # # Adapted from "nis.monitor" by # Carnegie Mellon University, Computing Services # # nis.monitor written by Juha Ylitalo # # Copyright (C) 1999, Juha Ylitalo # # 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; either version 2 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA # use Getopt::Std; use English; use IO::File; use LWP; use HTTP::Request; use HTTP::Cookies; #use LWP::Debug qw(+); getopts ("c:p:r:t:u:"); $TIMEOUT = $opt_t || 30; $user = $opt_u; $password = $opt_p; $realm = $opt_r; unless (&parse_cf) { print "Monitoring Error\nNo user/password specified on command line and Can't open or parse config file\n"; exit 255; } @failures = (); @report = (); foreach $server ( @ARGV ) { &pubcookie_login_poll( $server ); } if (@failures == 0) { exit 0; } print "@failures\n\n"; print join "\n", @report; print "\n"; exit 1; sub pubcookie_login_poll { my ( $server ) = @_; my ($pin, $pout); my ($cell, $cmd, $pid); my $service; ############################################################### eval { local $SIG{ALRM} = sub { die "Timeout Alarm" }; my $ua= new LWP::UserAgent; my $url="https://$server"; alarm $TIMEOUT; my $request= new HTTP::Request (HEAD => "$url"); $res = $ua->simple_request($request); alarm 0; my $subj=$res->header("Client-SSL-Cert-Subject"); if ($subj =~ /CN=([\.\w]+)$/) { $service=$1; } }; if ($EVAL_ERROR and ($EVAL_ERROR eq 'Timeout Alarm')) { push @failures, $appsrv; push @report, $appsrv . ":Timed Out\n"; return @failures; } eval { local $SIG{ALRM} = sub { die "Timeout Alarm" }; alarm $TIMEOUT; my $ua= new LWP::UserAgent; my $cj= new HTTP::Cookies; $ua->cookie_jar($cj); my $request= new HTTP::Request (POST => "https://$server/login.cgi"); $request->content_type('application/x-www-form-urlencoded'); if ($service) { $request->header("host", $service); } $request->content("user=$user"); $request->add_content("&realm=$realm"); $request->add_content("&pass=$password"); $request->add_content("&one=webiso.andrew.cmu.edu"); $request->add_content("&two=pinit"); $request->add_content("&creds_from_greq=1"); $request->add_content("&three=1"); $request->add_content("&four="); $request->add_content("&five="); $request->add_content("&six=webiso.andrew.cmu.edu"); $request->add_content("&seven=/login.cgi"); $request->add_content("&pinit=true"); $request->add_content("&reply=1"); my $res = $ua->request($request); if ($res->is_success) { my %cookies; $cj->scan(sub{ #print "COOKIE: $_[1]:$_[4]\n"; $cookies{$_[1]}=1; }); # pubcookie_cred and pubcookie_l will be rejected by HTTP::Cookies # if the servername doesn't match if ($cookies{pubcookie_g}) { if (not defined($cookies{pubcookie_l}) or not defined($cookies{pubcookie_cred})) { # wrong service name.... complain or not? } #print "OK\n"; } else { #print "auth reply cookies not present\n"; push @failures, $server; push @report, $server . ": authentication request failed\n"; } #print $cj->as_string(0), "\n\n\n"; #print $res->as_string(), "\n"; } else { push @failures, $server; push @report, $server . ": " . $res->status_line(); } alarm 0; # Cancel the alarm }; if ($EVAL_ERROR and ($EVAL_ERROR eq 'Timeout Alarm')) { push @report , "$server: Time Out\n"; push @failures , $server; } return @failures; } sub parse_cf { my (%users, %passwords, %realms); my $g=$ENV{MON_GROUP}; my $s=$ENV{MON_SERVICE}; my $file = $opt_c || $ENV{MON_CFBASEDIR}."/monitor-auth.cf"; $cf=new IO::File "<$file" or return 0; while (<$cf>) { if (/^(\S+):user\s*=\s*(\S+)$/) { $users{$1}=$2; } if (/^(\S+):password\s*=\s*(\S+)$/) { $passwords{$1}=$2; } if (/^(\S+):realm\s*=\s*(\S+)$/) { $realms{$1}=$2; } } $user ||= $users{"$g:$s"}; $user ||= $users{"$g:*"}; $user ||= $users{"*:$s"}; $user ||= $users{"*:*"}; $password ||= $passwords{"$g:$s"}; $password ||= $passwords{"$g:*"}; $password ||= $passwords{"*:$s"}; $password ||= $passwords{"*:*"}; $realm ||= $realms{"$g:$s"}; $realm ||= $realms{"$g:*"}; $realm ||= $realms{"*:$s"}; $realm ||= $realms{"*:*"}; return 0 unless (defined($user) && defined($password) && defined($realm)); return 1; } mon-contrib-1.0+dfsg/monitors/pubcookie/webapp.monitor000077500000000000000000000272601160532374600232620ustar00rootroot00000000000000#!/usr/bin/perl # # Try to establish a connection to a web application using pubcookie # authentication. See http://www.pubcookie.org # # User, password, realm and pubcookie login server can either be # specified on the command line or in the monitor-auth.cf file. # # Arguments are "[-c monitor-auth-config] [-U user] [-P pass] [-R # realm] [-L pubcookie-login-server] [-t timeout] [-u urlsuffix] host # [host...]" # # Adapted from "nis.monitor" by # Carnegie Mellon University, Computing Services # # nis.monitor written by Juha Ylitalo # # Copyright (C) 1999, Juha Ylitalo # # 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; either version 2 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA # use strict; use vars qw(@failures @report $ua $cj $pubcookie_status $TIMEOUT $appurl $debug $opt_t $opt_u $opt_d $opt_U $opt_P $opt_R $opt_L $opt_c $user $password $realm $pcserver); use Getopt::Std; use English; use IO::File; use LWP; use HTTP::Request; use HTTP::Cookies; getopts ("u:t:d:U:P:R:L:c:"); $TIMEOUT = $opt_t || 30; $appurl = $opt_u || ""; $debug = $opt_d || 0; $user = $opt_U; $password = $opt_P; $realm = $opt_R; $pcserver = $opt_L; if ($debug > 1) { require LWP::Debug; import LWP::Debug qw(+); } unless (&parse_cf) { print join(' ', @ARGV) . "\n\nMonitoring Error!\nNo user/password specified on command line and can't open or parse config file\n"; exit 254; } @failures = (); @report = (); $ua= new LWP::UserAgent; $cj= new HTTP::Cookies; # Masquerade as MSIE, because some servers return an error for a user agent of libwww-perl. # suck suck suck $ua->agent('Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1)'); $ua->cookie_jar($cj); $pubcookie_status=pubcookie_login($ua, $cj, $pcserver); if ($pubcookie_status) { print join(' ', @ARGV) . "\n\nUnable to complete initial pubcookie login!\n$pubcookie_status\n"; exit(254); } foreach my $server ( @ARGV ) { &webapp_poll($ua, $pcserver, $server ); } if (@failures == 0) { exit 0; } print "@failures\n\n"; print join "\n\n", @report; print "\n"; exit scalar(@failures); sub pubcookie_login { my ($ua, $cj, $pcserver ) = @_; my ($fail); undef $fail; ############################################################### warn "Authenticating to pubcookie server $pcserver.\n" if ($debug); eval { local $SIG{ALRM} = sub { die "Timeout Alarm" }; alarm $TIMEOUT; my $request= new HTTP::Request (POST => "https://$pcserver/login.cgi"); $request->content_type('application/x-www-form-urlencoded'); $request->content("user=$user"); $request->add_content("&realm=$realm"); $request->add_content("&pass=$password"); $request->add_content("&one=$pcserver"); $request->add_content("&two=pinit"); $request->add_content("&creds_from_greq=1"); $request->add_content("&three=1"); $request->add_content("&four="); $request->add_content("&five="); $request->add_content("&six=$pcserver"); $request->add_content("&seven=/login.cgi"); $request->add_content("&reply=1"); my $res = $ua->request($request); if ($res->is_success) { my %cookies; $cj->scan(sub{ warn "COOKIE: $_[1]\n" if ($debug > 1); $cookies{$_[1]}=1; }); if ($cookies{pubcookie_cred}) { print "Pubcookie login OK\n" if ($debug); } else { print "auth reply cookies not present\n" if ($debug); $fail="$pcserver: authentication request failed\n"; } print $cj->as_string(), "\n\n\n" if ($debug > 1); print $res->as_string(), "\n" if ($debug > 1); } else { $fail=$pcserver .": " . $res->status_line(); } alarm 0; # Cancel the alarm }; if ($EVAL_ERROR and ($EVAL_ERROR eq 'Timeout Alarm')) { $fail="$pcserver: Time Out\n"; } return $fail; } sub pubcookie_appsrvreq { my ($ua, $pcserver, $appurl ) = @_; my ($fail); my $res; undef $fail; ############################################################### warn "Talking to $pcserver about access to $$appurl\n" if ($debug); eval { local $SIG{ALRM} = sub { die "Timeout Alarm" }; alarm $TIMEOUT; my $request= new HTTP::Request (GET => "https://$pcserver/"); # my $request2=$request->clone; # $ua->cookie_jar->add_cookie_header($request2); # print "-=-=-=-=-=-=\n",$request2->as_string(), "\n-=-=-=-=-=-=-=\n"; $res = $ua->request($request); alarm 0; # Cancel the alarm }; if ($EVAL_ERROR and ($EVAL_ERROR eq 'Timeout Alarm')) { return "$pcserver request Timed Out"; } elsif ($EVAL_ERROR) { return $EVAL_ERROR } if ($res->is_success) { warn $cj->as_string(), "\n\n\n" if ($debug > 1); warn $res->as_string(), "\n" if ($debug > 1); my %cookies; $cj->scan(sub{ $cookies{$_[1]}=1; }); if ($cookies{pubcookie_l}) { warn "OK\n" if ($debug > 1); } else { warn "$pcserver refused application request\n" if ($debug); return "$pcserver refused application request\n"; } } else { warn "$pcserver request failed: " . $res->status_line() if ($debug); return "$pcserver request failed: " . $res->status_line(); } my $refr=$res->header("Refresh"); if ($refr) { warn "Got refresh $refr\n" if ($debug); if ($refr =~ m,\d+;URL=[a-z]+://[^/]+/(\S+)$,) { $$appurl=$1; } } return undef; } sub webapp_poll { my ( $ua, $pcserver, $appsrv) = @_; my $retry = 0; my $retry_limit = 3; my $res; my $pubcookie_status; my $justreturn; my $appsvc; ############################################################### warn "Attempting to access https://$appsrv\n" if ($debug); eval { local $SIG{ALRM} = sub { die "Timeout Alarm" }; my $url="https://$appsrv"; alarm $TIMEOUT; my $request= new HTTP::Request (HEAD => "$url"); $res = $ua->simple_request($request); alarm 0; my $subj=$res->header("Client-SSL-Cert-Subject"); if ($subj =~ /CN=([\.\w]+)$/) { $appsvc=$1; } }; if ($EVAL_ERROR and ($EVAL_ERROR eq 'Timeout Alarm')) { push @failures, $appsrv; push @report, $appsrv . ":\nUnable to authenticate via pubcookie to $appsrv.\nFailed to establish initial connection to https://$appsrv, connection timed out.\n"; return @failures; } retry: eval { local $SIG{ALRM} = sub { die "Timeout Alarm" }; my $url="https://$appsrv/$appurl"; alarm $TIMEOUT; # LWP::UserAgent deletes the host and cookie headers when it recurses on # a redirect. We don't want that. On the other hand, we do want to make # sure there are no off-server redirects, so we use simple_request and # process redirects ourselves while (my $i++ < 10) { warn "Fetching $url\n" if ($debug); my $request= new HTTP::Request (GET => "$url"); $request->header("Host", $appsvc) if ($appsvc); $res = $ua->simple_request($request); alarm 0; # Cancel the alarm warn "HTTP request success.\n" if ($debug && $res->is_success); warn "HTTP response code ".$res->code."\n" if ($debug); last if ($res->is_success); my $code=$res->code; if ($code == &HTTP::Status::RC_MOVED_PERMANENTLY or $code == &HTTP::Status::RC_MOVED_TEMPORARILY) { $url=$res->header("Location"); { # code taken from LWP::UserAgent local $URI::ABS_ALLOW_RELATIVE_SCHEME = 1; my $base = $res->base; $url = $HTTP::URI_CLASS->new($url, $base) ->abs($base); warn "Got redirect to $url\n" if ($debug); } # some things (e.g. the portal) will issue absolute redirects # to the load-balanced name. We want to do all testing against # the actual requested target if ($appsvc && $url =~ m,https://$appsvc,) { $url=~ s/$appsvc/$appsrv/; } if ($url !~ m,https://$appsrv,) { push @failures, $appsrv; push @report, $appsrv . ":\nUnable to authenticate via pubcookie to https://$appsrv/$appurl\nReceived unexpected redirect to $url\n"; $justreturn=1; last; } } else { last; } } }; if ($EVAL_ERROR and ($EVAL_ERROR eq 'Timeout Alarm')) { push @failures, $appsrv; push @report, $appsrv . ":\nUnable to authenticate via pubcookie to https://$appsrv/$appurl, connection timed out.\n"; } return @failures if ($justreturn); if ($res->is_success) { my $refr=$res->header('Refresh'); if ($refr && $refr =~ /^0;/) { warn "Got refresh $refr, pcserver = $pcserver, Retry is $retry.\n" if ($debug); if (($retry <= $retry_limit) && ($refr =~ /$pcserver/)) { $pubcookie_status=pubcookie_appsrvreq($ua, $pcserver, \$appurl); if ($pubcookie_status) { push @failures, $appsrv; push @report, $appsrv . ":\nUnable to authenticate via pubcookie to https://$appsrv/$appurl\n" . $pubcookie_status; } else { $retry++; goto retry; } } else { push @failures, $appsrv; push @report, $appsrv . ":\nUnable to authenticate via pubcookie to https://$appsrv/$appurl\nToo many redirects ($retry), received redirect to $refr"; } } else { warn "$appsrv request OK\n" if ($debug); } warn $cj->as_string(), "\n\n\n" if ($debug > 1); warn $res->as_string(), "\n" if ($debug > 1); } else { push @failures, $appsrv; push @report, $appsrv . ":\nUnable to authenticate via pubcookie to https://$appsrv/$appurl\n". $res->status_line(); } return @failures; } sub parse_cf { my (%users, %passwords, %realms, %pcservers, $cf); my $g=$ENV{MON_GROUP}; my $s=$ENV{MON_SERVICE}; warn "Parsing config file.\n" if ($debug); my $file = $opt_c || $ENV{MON_CFBASEDIR}."/monitor-auth.cf"; $cf=new IO::File "<$file" or return 0; while (<$cf>) { if (/^(\S+):user\s*=\s*(\S+)$/) { $users{$1}=$2; } if (/^(\S+):password\s*=\s*(\S+)$/) { $passwords{$1}=$2; } if (/^(\S+):realm\s*=\s*(\S+)$/) { $realms{$1}=$2; } if (/^(\S+):pubcookie_server\s*=\s*(\S+)$/) { $pcservers{$1}=$2; } } $user ||= $users{"$g:$s"}; $user ||= $users{"$g:*"}; $user ||= $users{"*:$s"}; $user ||= $users{"*:*"}; $password ||= $passwords{"$g:$s"}; $password ||= $passwords{"$g:*"}; $password ||= $passwords{"*:$s"}; $password ||= $passwords{"*:*"}; $realm ||= $realms{"$g:$s"}; $realm ||= $realms{"$g:*"}; $realm ||= $realms{"*:$s"}; $realm ||= $realms{"*:*"}; $pcserver ||= $pcservers{"$g:$s"}; $pcserver ||= $pcservers{"$g:*"}; $pcserver ||= $pcservers{"*:$s"}; $pcserver ||= $pcservers{"*:*"}; warn "Config is: user:$user, password:$password, realm:$realm, pcserver:$pcserver\n" if ($debug > 1); return 0 unless (defined($user) && defined($password) && defined($realm) && defined($pcserver)); return 1; } mon-contrib-1.0+dfsg/monitors/radius/000077500000000000000000000000001160532374600176705ustar00rootroot00000000000000mon-contrib-1.0+dfsg/monitors/radius/radius.monitor.detailcheck/000077500000000000000000000000001160532374600251045ustar00rootroot00000000000000mon-contrib-1.0+dfsg/monitors/radius/radius.monitor.detailcheck/radius.monitor.detailcheck000077500000000000000000000072701160532374600322540ustar00rootroot00000000000000#!/usr/bin/perl # # An anal-retentive check of radius. We check to make sure that # we get an expected list of specially cooked items in the reply # that matches a predefined list and we alert if we don't see all # the items, or if any don't match, or if we get unexpected avpairs # in the reply. # # To use this: # # You first need to set up your radius servers to accept requests from # your mon host and test and verify that you can peform simple radius # authorizations using radclient before your proceed. See your radius # server documentation for details. # # 1) Create a special radius test user. I have 'mon' here, # but it's user configurable. Set the below vars to this name and # password. # # 2) Assign different attributes to return for this this user. The # minimum reccomended list is: # # Framed-IP-Address # Framed-IP-Netmask # Framed-Route # Framed-MTU # Filter-Id # # **You should set these all to some weird nonsensical values that # would not be in use in your network. The purpose is to make sure # that these values are being passed thru your radius unaltered.** # # 3) Insert the attributes and values you selected above into # the %refvars hash. This has to match what radius hands back, otherwise, # it will generate an alert. # # 4) Test by running this command and checking the output: # # ./radius.monitor.detailcheck serversecret serverhost1 serverhost2 .. # # You made need to adjust the path to radclient as well as where your local # radius dictionaries are kept. # # Mike Ireton # mike@willitsonline.com # BEGIN { $TEMPFILE=`mktemp /tmp/radius.detailcheck.XXXXXX`; chomp($TEMPFILE); } END { unlink ($TEMPFILE); }; $RADCLIENT="/usr/bin/radclient"; $DICTIONARY="/etc/freeradius"; $USER="mon"; $PASS="yourpasswordhere"; $SECRET=shift; $ok=0; while ($SERVER = shift) { %refvars = ( 'Framed-IP-Address' => "192.168.255.1", 'Framed-MTU' => "1638", 'Service-Type' => "Framed-User", 'Framed-Protocol' => "PPP", 'Framed-Compression' => "Van-Jacobson-TCP-IP", 'Framed-IP-Netmask' => "255.248.240.224", 'Filter-Id' => "\"radiusdebug\"", 'Framed-Route' => "\"192.168.255.252/30\"", ); %skipvars = ( 'User-Name' => "any", 'CHAP-Password' => "any", 'Framed-Protocol' => "any", ); # First, test Access-Accept and returned variables open(FP,"|$RADCLIENT -d $DICTIONARY -r 2 -x $SERVER auth $SECRET > $TEMPFILE 2>&1"); print FP "User-Name = \"$USER\"\n"; print FP "Chap-Password = \"$PASS\"\n"; print FP "Framed-Protocol = PPP\n"; close(FP); open(RESULTS,"<$TEMPFILE"); do { $line=; if($line =~ /radclient: no response from server/) { $ok=1; print "Server failed to respond: $SERVER\n"; next; } if($line =~ /rad_recv: Access-Reject/) { $ok=1; print "Server rejected test credentials: $SERVER\n"; next; } if($line =~ /Shared secret is incorrect/) { $ok=1; print "Server test failed on $SERVER: shared secret incorrect?\n"; next; } } until $line =~ /^rad_recv/; while ($line=) { if ($line =~ /^\s+([-a-zA-Z]+)\s?=\s(.+)/ ) { $var=$1; $value=$2; if ( defined $refvars{$var} ) { if ( $refvars{$var} ne $value ) { push @mismatched,"got $var = $value, expected $var = " . $refvars{$var}; } delete $refvars{$var}; } else { push @unexpected,"$var = $value"; } } } close(RESULTS); if(( keys( %refvars ) != 0) || ( @mismatched !=0 ) || (@unexpected != 0)) { print "A server failed avresponse check: $SERVER\n"; $ok=1; }; foreach ( keys %refvars ) { print "\tFailed to receive avpair: " . " " . "$_ = " . $refvars{$_} . "\n"; } foreach ( @mismatched ) { print "\tFailed to match avpair: $_ \n"; } foreach ( @unexpected ) { print "\tUnexpected avpair: $_ \n"; } undef @mismatched; undef @unxepected; } exit $ok; mon-contrib-1.0+dfsg/monitors/radius/radius.monitor.detailcheck/radius.monitor.detailcheck.README000066400000000000000000000016121160532374600331770ustar00rootroot00000000000000radius.monitor.detailcheck README ================================= This is an anal-retentive check of radius to ensure that not only are your servers online, but that they are returning expected av pairs. This is a good extra additional check to be doing because configuration mistakes or database problems may create problems for radius that don't show up as a simple 'access-reject'. Since mon only passes simple command line params, and because we need more extensive configuration, you need to modify the script's configuration vars to suit your installation. The general idea is that you set it up with as many unique av pairs as you can, with values that do not match anything you're likely to ever legitimately assign elsewhere, and then this script checks to make sure that all av pairs are returned and ONLY these pairs are seen else it reports. Mike Ireton WillitsOnline Feb 13 2008 mon-contrib-1.0+dfsg/monitors/raid/000077500000000000000000000000001160532374600173205ustar00rootroot00000000000000mon-contrib-1.0+dfsg/monitors/raid/softraid.monitor000077500000000000000000000025611160532374600225530ustar00rootroot00000000000000#!/bin/bash # softraid.monitor # Linux Software RAID check with mon compatible output/return values # Call without arguments. # The reference file $md_ref must exist. To generate it: # softraid.monitor learn # [ cat /proc/mdstat > /path/to/dir/mdstat.reference ] # no administrative permissions needed for this script. # Return values: 3 /proc/mdstat missing, no Software RAID? # 2 reference file missing # 1 RAID not okay # 0 alles okay # # Date: Thu, 07 Apr 2005 17:28:02 +0200 # From: Kevin Ivory # To: mon@linux.kernel.org # Subject: Re: Monitoring software raid? # mdstat="/proc/mdstat" # THIS NEEDS TO BE SOMEWHERE THE CHECKING USER CAN WRITE md_ref="/var/something/mdstat.reference" if [ ! -r "$mdstat" ]; then echo -e "$HOSTNAME:$0 Missing RAID status file: $mdstat Perhaps no software RAID?" exit 3 fi if [ "$1" = "learn" ]; then cat "$mdstat" > "$md_ref" fi if [ ! -r "$md_ref" ]; then echo -e "$HOSTNAME:$0 Missing RAID reference file: $md_ref Generate with: $0 learn > $md_ref" exit 2 fi md_out="Complete contents of $mdstat:\n\n$(cat $mdstat)" diff=$(diff -u -U 0 $md_ref $mdstat) stat=$? if [ $stat -eq 0 ]; then echo -e "$HOSTNAME\nSoftware RAID ok:\n$md_out" else echo -e "$HOSTNAME\nSoftware RAID not ok:\n$diff\n\n$md_out" exit 1 fi # end of softraid.monitor mon-contrib-1.0+dfsg/monitors/remote/000077500000000000000000000000001160532374600176745ustar00rootroot00000000000000mon-contrib-1.0+dfsg/monitors/remote/remote/000077500000000000000000000000001160532374600211675ustar00rootroot00000000000000mon-contrib-1.0+dfsg/monitors/remote/remote/remote.monitor000066400000000000000000000203051160532374600240730ustar00rootroot00000000000000#!/usr/bin/perl -w # # Returns a mon server list that failed services # # Usage : remote.monitor [options] [host1 host2 ...] # # --port n : the mon port # # --timeout n : the timeout connexion (default 10 seconds) # # --summary : flag to extend the summary of this monitor # return for each failed mon server the list of the # failed. Like : host1([g1:s1|s3][g4:s5]) ... # # --bigsummary : flag to extend the summary of this monitor # return for each failed mon server the list of the # failed. Like : host1([g1:s1{sum}|s3{sum}][g4:s5{sum}]) ... # # --debug : some debug information (do not use this with mon) # # --restrict watch[:service] : restrict test to specified watch # [and service] # # --help : prints this message. # # host1 host2 : list of remote MON servers to check # # Contributors : # Gilles LAMIRAL, lamiral@mail.dotcom.fr # Laurent COMBE, laurent.combe@free.fr # Thomas MORIN, thomas.morin@webmotion.com # # Copyright (C) 1999, Gilles LAMIRAL # # This program is free software; you can redistribute it and/or # modify it under the terms of the GNU General Public License. # Variables: # @failures failed hosts array. # @failuresDetails detailed failed hosts array. use Getopt::Long; use Mon::Client; GetOptions( "port|p:i" => \$port, "timeout|t:i" => \$timeout, "summary" => \$summary, "bigsummary" => \$bigsummary, "debug|d" => \$debug, "help|h" => \$help, "restrict|r:s" => \$restrict, ); my $rcs = ' $Id: remote.monitor,v 1.1.1.1 2005/02/18 17:52:23 trockij Exp $ ' ; $rcs =~ m/,v (\d+\.\d+)/; $VERSION = ($1) ? $1 : "0.1"; usage() and exit if ($help); $port = ($port) ? $port : "2583"; $timeout = ($timeout) ? $timeout : "10"; $summary = ($summary) ? $summary : $bigsummary; ($restrict) and ($only_watch,$only_service) = split( /:/, ($restrict) ); @failures = (); @failuresDetails = (); @extendsummary = (); foreach $host (@ARGV) { my $begin = time; eval { local $SIG{ALRM} = sub { die "Timeout Alarm" }; alarm $timeout; &getinfo($host, $port); alarm 0; # Cancel the alarm }; my $end = time; my $timeResponse = $end - $begin; if ($EVAL_ERROR and ($EVAL_ERROR =~ /^Timeout Alarm/)) { ($debug) and print "Timeout connection\n"; $failuresDetails{${host}} = join("", "Timeout connection"); push (@failures, ${host}); push (@extendsummary, "${host}:TIMEOUT(${timeResponse})"); next; } } if (@failures == 0) { exit 0; } if ($summary) { print "@extendsummary\n\n"; } else { print "@failures\n\n"; } foreach $host (@failures) { print "Details for $host failure :\n", "$failuresDetails{$host}\n\n"; } # exit with the the error status on. exit(1); sub getinfo { ($host, $port) = @_; ($debug) and print "testing mon server $host :\n"; $cl = Mon::Client->new; $cl->host ($host); $cl->port ($port); unless (defined ($cl->connect)) { ($debug) and print "connection failed: ", $cl->error, "\n"; $failuresDetails{${host}} = join("", "Connection failed: ", $cl->error); push (@failures, ${host}); push (@extendsummary, "${host}:CONNECT"); return; }else{ ($debug) and print "connection succeeded\n"; ($debug) and print "host : ", $cl->host, "\n", "port : ", $cl->port, "\n", "error : ", $cl->error, "\n", ; %s = $cl->list_opstatus; ($debug) and print "list_opstatus: ", %s, "\n", "error : ", $cl->error,"\n", ; if ($cl->error) { $failuresDetails{${host}} = join("", "list_opstatus failed:", $cl->error); push (@failures, ${host}); push (@extendsummary, "${host}:list_opstatus"); next; } %d = $cl->list_disabled; ($debug) and print "list_disabled: ", %d, "\n", "error : ", $cl->error,"\n", ; # parsing of %d if ($debug) { print "===\nlist_disabled detail:\n"; while ( ($category,$pwatch) = each %d ) { while( ($watch, $pvalue) = each %$pwatch ) { while( ($value) = each %$pvalue ) { print "$category,$watch,$value\n"; } } } print "end of list_disabled detail\n===\n"; } # error state host flag my($hosterr) = 0; my($hostwatch); ($debug) and print "===\nlist_opstatus detail:\n"; foreach $watch (sort keys %s) { my $watcherr = 0; my $ext_service = "[$watch:"; next if ( ($only_watch) && !( $watch eq ($only_watch) )); foreach $service (sort keys %{$s{$watch}}) { my($opstatus); next if ( ($only_service) && !( $service eq ($only_service) )); # state service recuperation $opstatus = $s{$watch}{$service}{opstatus}; ($debug) and print "$watch $service opstatus=$opstatus\n"; #if no error (!= 0) then next next if ($opstatus != 0); #if this service is disabled then next next if (defined($d{services}{$watch}{$service})); # at this point we've got a failure so get the last summary $last_summary = $s{$watch}{$service}{last_summary}; # service failed and not disabled $hosterr++; $watcherr++; ($debug) and print "Watch $watch service $service failed\n"; push (@failures, ${host}) unless (defined($failuresDetails{${host}})); $failuresDetails{${host}} .= "Watch $watch, service $service, failed ". "with summary : ${last_summary}\n"; # save services if ($summary) { if ($bigsummary) { $ext_service .="${service}{${last_summary}}|"; } else { $ext_service .="${service}|"; } } } if ($watcherr) { chop($ext_service); $ext_service .= "]"; $hostwatch .= $ext_service; } } #modification of summary if ($hosterr) { push (@extendsummary, "$host($hostwatch)"); } ($debug) and print "end of list_opstatus detail:\n===\n"; } $cl->disconnect; } sub usage { print < because of a "special feature ;-)" of gilles' minotor 0.05 ---------------------------- revision 1.6 date: 2000/10/08 16:09:13; author: laurent; state: Exp; lines: +18 -9 - Minor modification of the output with the summary option activated: host1([g1:s1|s3][g3:s5]) host(...) ... for each failed service now we've got the summary - Also give the summary of each service failed in the detail - Delete line "use FileHandle;" ---------------------------- revision 1.5 date: 2000/10/08 15:05:08; author: laurent; state: Exp; lines: +1 -2 - remove the 'use English' line because of no call to this module ---------------------------- revision 1.4 date: 2000/10/08 15:03:02; author: laurent; state: Exp; lines: +8 -3 - Merge from Thomas Morin restrict patch ---------------------------- revision 1.3 date: 2000/10/08 14:40:40; author: laurent; state: Exp; lines: +2 -20 - remove detailed history in the monitor ---------------------------- revision 1.2 date: 2000/10/08 14:36:39; author: laurent; state: Exp; lines: +135 -140 - Merging with version 1.5 of gilles branch - more untabify - change variable name: hostservice -> ext_service ---------------------------- revision 1.1 date: 2000/10/08 08:07:44; author: cvsadm; state: Exp; branches: 1.1.1; Initial revision ---------------------------- revision 1.1.1.1 date: 2000/10/08 08:07:44; author: cvsadm; state: Exp; lines: +0 -0 Mise sous CVS =============================================================================mon-contrib-1.0+dfsg/monitors/remote/startremote/000077500000000000000000000000001160532374600222455ustar00rootroot00000000000000mon-contrib-1.0+dfsg/monitors/remote/startremote/startremote.monitor000066400000000000000000000041161160532374600262310ustar00rootroot00000000000000#!/usr/bin/perl # # $Id: startremote.monitor,v 1.1.1.1 2005/02/18 17:52:23 trockij Exp $ # $Revision: 1.1.1.1 $ # $Author: trockij $ # #Usage: startremote.monitor [options] # # --remotehost Host on which the monitor should be started # --remoteuser User on the remote-host which is allowed to run the given monitor # --remotemon Monitor which should be started # --remoteparam Params for the monitor program # # # # # Copyright (C) 2001, CubIT IT Solutions # Written by Severin Luftensteiner # # 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; either version 2 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA # use Getopt::Long; GetOptions( \%options,"remotehost=s", "remoteuser=s", "remotemon=s", "remoteparam=s" ); if (($options{remotehost} eq "") || ($options{remoteuser} eq "") || ($options{remotemon} eq "")){ print < Host on which the monitor should be started --remoteuser User on the remote-host which is allowed to run the postgresql.monitor --remotemon Monitor which should be started --remoteparam Params for the monitor program EOP1 die(); } my $output=`ssh $options{remoteuser}\@$options{remotehost} $options{remotemon} $options{remoteparam} 2> /dev/null`; chomp($output); if ($output ne ""){ print $output."\n"; exit 1; } exit 0; mon-contrib-1.0+dfsg/monitors/remote/startremote/startremote.monitor.README000066400000000000000000000024541160532374600271700ustar00rootroot00000000000000# $Id: startremote.monitor.README,v 1.1.1.1 2005/02/18 17:52:23 trockij Exp $ # $Revision: 1.1.1.1 $ # $Author: trockij $ # #Usage: startremote.monitor [options] # # --remotehost Host on which the monitor should be started # --remoteuser User on the remote-host which is allowed to run the given monitor # --remotemon Monitor which should be started # --remoteparam Params for the monitor program # # # # # Copyright (C) 2001, CubIT IT Solutions # Written by Severin Luftensteiner # # 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; either version 2 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA mon-contrib-1.0+dfsg/monitors/repeater/000077500000000000000000000000001160532374600202105ustar00rootroot00000000000000mon-contrib-1.0+dfsg/monitors/repeater/rptr/000077500000000000000000000000001160532374600211775ustar00rootroot00000000000000mon-contrib-1.0+dfsg/monitors/repeater/rptr/rptr.monitor000066400000000000000000000135741160532374600236110ustar00rootroot00000000000000#!/usr/bin/perl # # SNMP monitoring of ethernet repeaters # # Returns 1 on SNMP errors, 2 for other errors (usually failure to # communicate with device). # # Phil Gregory # # rptr.monitor, v. 0.9, 2000-02-28 # # Initially derived from the hpnp.monitor code. # # # Copyright (C) 2000, Phil Gregory # # 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; either version 2 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA # # # Still TODO: # # - Be more discerning about errors. Currently, everything not # "operational" is considered an error. Depending on how people use # this, the monitor may only want to report "malfunctioning" groups # and ports. # # - The program should try to detect cases where the host exists, but # does not support the correct MIB. (In this case, the repeater MIB.) # # - Checking the ports to see if they're autopartitioned might be # useful. # # - There may be a better way to work through the ports. In particular, # there should only be entries in rptrGroupTable for existing groups. # Querying only existing groups is much better on the bandwidth than # trying all possible groups and ignoring the errors (which is how the # script currently works). It also appears possible for ports to be # numbered higher than the maximum number of ports--e.g. the 3Com SSII # switch 1000 where the 13 ports are numbered 1-12 and 14. (I need to # look at UCD's snmptable and see how they get table dimensions.) use SNMP; use Getopt::Long; GetOptions (\%opt, "community=s", "timeout=i", "retries=i", "lpq"); die "no host arguments\n" if (@ARGV == 0); $RET = 0; @ERRS = (); $COMM = $opt{"community"} || "public"; $TIMEOUT = $opt{"timeout"} * 1000 * 1000 || 2000000; $RETRIES = $opt{"retries"} || 5; @rptrDesc = ("", "other", "ok", "repeater failure", "group failure", "port failure", "general failure"); @groupDesc = ("", "other", "operational", "malfunctioning", "not present", "under test", "resetting"); @portDesc = ("", "operational", "not operational", "not present"); foreach $host (@ARGV) { undef $s; if (!defined($s = new SNMP::Session (DestHost => $host, Timeout => $TIMEOUT, Community => $COMM, Retries => $RETRIES))) { print "cannot create SNMP session to $host\n"; $RET = ($RET == 1) ? 1 : 2; next; } undef $rptrVars; $rptrVars = new SNMP::VarList ( ['.1.3.6.1.2.1.22.1.1.2', 0], # rptrOperStatus ['.1.3.6.1.2.1.22.1.1.3', 0], # rptrHealthText ['.1.3.6.1.2.1.22.1.1.1', 0], # rptrGroupCapacity ); if (!defined($s->get($rptrVars))) { push(@hosts, $host); push(@ERRS, "$host unreachable\n\n"); $RET = ($RET == 1) ? 1 : 2; next; } $rptrHealth = ""; @groupHealth = @groupDescr = @groupNum = (); @portHealth = @portNum = @portGroupDescr = @portGroupNum = (); if (${$rptrVars}[0]->val != 2) { $rptrHealth = ${$rptrVars}[1]->val . "\n\n"; } for ($group = 1; $group <= ${$rptrVars}[2]->val; $group++) { undef $groupVars; $groupVars = new SNMP::VarList ( ['.1.3.6.1.2.1.22.1.2.1.1.4', $group], # rptrGroupOperStatus ['.1.3.6.1.2.1.22.1.2.1.1.2', $group], # rptrGroupDescr ['.1.3.6.1.2.1.22.1.2.1.1.6', $group], # rptrGroupPortCapacity ); if (!defined ($s->get($groupVars)) or !(${$groupVars}[0]->val)) { next; } if (${$groupVars}[0]->val != 2) { push (@groupHealth, $groupDesc[${$groupVars}[0]->val]); push (@groupDescr, ${$groupVars}[1]->val); push (@groupNum, $group); } for ($port = 1; $port <= ${$groupVars}[2]->val; $port++) { undef $portVars; $portVars = new SNMP::VarList ( ['.1.3.6.1.2.1.22.1.3.1.1.5.$group', $port], # rptrPortOperStatus ); if (!defined ($s->get($portVars)) or !(${$portVars}[0]->val)) { next; } if (${$portVars}[0]->val != 1) { push (@portHealth, $portDesc[${$portVars}[0]->val]); push (@portNum, $port); push (@portGroupDescr, ${$groupVars}[1]->val); push (@portGroupNum, $group); } } } if ($rptrHealth) { $headline = "Repeater Error"; } elsif (@groupHealth > 0) { $headline = "Group Error"; } elsif (@portHealth > 0) { $headline = "Port Error"; } else { $headline = ""; } if ($headline) { $RET = 1; push (@hosts, $host); push (@ERRS, "$host\n" . "-" x length($host) . "\n\n"); if ($rptrHealth) { push (@ERRS, "Repeater Error\n" . "-" x 14 . "\n" . $rptrHealth); } if (@groupHealth > 0) { push (@ERRS, "Group Errors\n" . "-" x 12 . "\n"); for ($i = 0; $i < @groupHealth; $i++) { push (@ERRS, "Group $groupNum[$i], $groupDescr[$i]: $groupHealth[$i]\n"); } push (@ERRS, "\n"); } if (@portHealth > 0) { push (@ERRS, "Port Errors\n" . "-" x 11 . "\n"); for ($i = 0; $i < @portHealth; $i++) { push (@ERRS, "Group $portGroupNum[$i], Port $portNum[$i]: " . "$portHealth[$i]\n"); } push (@ERRS, "\n"); } } } if (@hosts > 0) { print join (" ", @hosts), "\n"; print "\n"; print @ERRS; } exit $RET;mon-contrib-1.0+dfsg/monitors/repeater/rptr/rptr.monitor.README000066400000000000000000000040521160532374600245340ustar00rootroot00000000000000# SNMP monitoring of ethernet repeaters # # Returns 1 on SNMP errors, 2 for other errors (usually failure to # communicate with device). # # Phil Gregory # # rptr.monitor, v. 0.9, 2000-02-28 # # Initially derived from the hpnp.monitor code. # # # Copyright (C) 2000, Phil Gregory # # 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; either version 2 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA # # # Still TODO: # # - Be more discerning about errors. Currently, everything not # "operational" is considered an error. Depending on how people use # this, the monitor may only want to report "malfunctioning" groups # and ports. # # - The program should try to detect cases where the host exists, but # does not support the correct MIB. (In this case, the repeater MIB.) # # - Checking the ports to see if they're autopartitioned might be # useful. # # - There may be a better way to work through the ports. In particular, # there should only be entries in rptrGroupTable for existing groups. # Querying only existing groups is much better on the bandwidth than # trying all possible groups and ignoring the errors (which is how the # script currently works). It also appears possible for ports to be # numbered higher than the maximum number of ports--e.g. the 3Com SSII # switch 1000 where the 13 ports are numbered 1-12 and 14. (I need to # look at UCD's snmptable and see how they get table dimensions.) mon-contrib-1.0+dfsg/monitors/samba/000077500000000000000000000000001160532374600174645ustar00rootroot00000000000000mon-contrib-1.0+dfsg/monitors/samba/samba/000077500000000000000000000000001160532374600205475ustar00rootroot00000000000000mon-contrib-1.0+dfsg/monitors/samba/samba/samba.monitor000066400000000000000000000060451160532374600232500ustar00rootroot00000000000000#!/usr/bin/perl # # Use: try to connect anonymously to a Samba server, and # wait for the right output. # # For use with "mon". # ## Arguments are " [-d] [-w] [-o] [-v] -t timeout host [host...]" # # -d : NT domain (ex: FT) # -w : Windows Workgroup (ex: FT) # -o : OS [NT, Unix] # -v : Samba Version (ex: 'Samba 1.9.17p4') # # Adapted from "http.monitor" by # Jean Le Moigne # # http.monitor originally written by # # Jon Meek # American Cyanamid Company # Princeton, NJ # # $Id: samba.monitor,v 1.1.1.1 2005/02/18 17:52:23 trockij Exp $ # # Copyright (C) 1998, Jean Le Moigne # # 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; either version 2 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA # use Getopt::Std; # Definitions # $SAMBA_DIR = "/usr/local/samba"; $SAMBA_BIN_DIR = "$SAMBA_DIR/bin"; $uid = `/usr/bin/id`; chomp $uid; $uid =~ /^uid=\S+\((\S+)\)\s+gid=\S+$/ ; if ( defined $1 ) { $uid = "$1"; } getopts ("d:w:o:v:u:"); $Domain = $opt_d || ".*"; $Workgroup = $opt_w || ".*"; $OS = $opt_o || ".*"; $Server_version = $opt_v || ".*"; $UID = $uid; #$TIMEOUT = $opt_t || 10; @failures = (); foreach $host (@ARGV) { if (! &Samba_test ($host)) { push (@failures, $host); } } if (@failures == 0) { exit 0; } print "@failures\n"; exit 1; sub Samba_test { my ($Server_name) = shift (@_); open (SCAN, "$SAMBA_BIN_DIR/smbclient -L $Server_name |") || die ">>> Cannot run find: $!\n"; ($Server_short_name, $void) = split (/\./, $Server_name); $Samba_server_name = "\U$Server_short_name"; $ligne = ; $ligne = ; chomp $ligne; if ( !($ligne =~ /^Server time is/) ) { close (SCAN); return (0); } $ligne = ; chomp $ligne; if ( !($ligne =~ /^Timezone is/) ) { close (SCAN); return (0); } $ligne = ; chomp $ligne; if ( !($ligne =~ /^Domain=\[$Domain\]\s+OS=\[$OS\]\s+Server=\[$Server_version\]/) ) { close (SCAN); return (0); } $ligne = ; chomp $ligne; if ( !($ligne =~ /^connected as guest security=share/) ) { close (SCAN); return (0); } $ligne = ; chomp $ligne; if ( $ligne ne "" ) { close (SCAN); return (0); } $ligne = ; chomp $ligne; if ( !($ligne =~ /^Server=\[$Samba_server_name\]\s+User=\[$UID\]\s+Workgroup=\[$Workgroup\]\s+Domain=\[$Domain\]/) ) { close (SCAN); return (0); } close (SCAN); return (1); } # (end sub Samba_test) mon-contrib-1.0+dfsg/monitors/samba/samba/samba.monitor.README000066400000000000000000000025051160532374600242010ustar00rootroot00000000000000# Use: try to connect anonymously to a Samba server, and # wait for the right output. # # For use with "mon". # ## Arguments are " [-d] [-w] [-o] [-v] -t timeout host [host...]" # # -d : NT domain (ex: FT) # -w : Windows Workgroup (ex: FT) # -o : OS [NT, Unix] # -v : Samba Version (ex: 'Samba 1.9.17p4') # # Adapted from "http.monitor" by # Jean Le Moigne # # http.monitor originally written by # # Jon Meek # American Cyanamid Company # Princeton, NJ # # $Id: samba.monitor.README,v 1.1.1.1 2005/02/18 17:52:23 trockij Exp $ # # Copyright (C) 1998, Jean Le Moigne # # 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; either version 2 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA mon-contrib-1.0+dfsg/monitors/smtp/000077500000000000000000000000001160532374600173645ustar00rootroot00000000000000mon-contrib-1.0+dfsg/monitors/smtp/mailloop/000077500000000000000000000000001160532374600212005ustar00rootroot00000000000000mon-contrib-1.0+dfsg/monitors/smtp/mailloop/mailloop.monitor000066400000000000000000000117401160532374600244300ustar00rootroot00000000000000#!/usr/bin/perl # # mailloop.monitor - sends email to mailboxes that are expected to send # the mail back to the sender. Probably not hard to do with procmail, etc. # I've only used a reflector agent for Lotus Notes. Instead of "hosts" in # a hostgroup, use email addresses you want to send bounce tests to. The # code still refers to these as hosts. # # You can use as many addresses as you'd like, but you'll need to use a # unique from address for each hostgroup that calls this monitor, because # it eats all the mail this running copy of the monitor didn't send. # Otherwise, previously delayed mail might lay around forever. # # The monitor then polls a POP3 account for the mail it sent. Don't use # that mailbox for anything else, the monitor will delete all your mail! # I'm not kidding, I didn't say "might", it *will*. # # This monitor assumes the local sendmail knows how to get the mail to # the the first relay in the loop you're testing. It also assumes that # the last host knows to deliver mail sent to the configured from # address so that it shows up in the POP server we poll. # # Takes 5 options: # -d Debug Mode. Not really compatible with normal mon scheduling, # because it doesn't log to syslog or anything, just print to STDOUT. # You'll have to call the monitor by hand to use this option. # Mostly helpful to debug your POP/SMTP setup. # # -f Set the from address, this option will also set the POP user to # all the bits before the '@'. So, don't do any wild aliasing... # # -p Set the POP password. Defaults to null password # # -s Set the POP server. Defaults to localhost. # # -t Standard monitor timeout option. # # # $Id: mailloop.monitor,v 1.1.1.1 2005/02/18 17:52:24 trockij Exp $ # # Copyright 2000 Shared Medical Systems, Inc. # Author: Bill Smargiassi # Email: william.smargiassi@smed.com # # 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; either version 2 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA # use Getopt::Std; use Mail::Sendmail; use POSIX; use Mail::POP3Client; sub dbgprint { my ($str) = @_; print $str, "\n" if $DEBUG; } # "check sum of tests left", not to be confused with a checksum :) sub checksum { my $sum; $sum = 0; foreach $id (keys %check) { $sum += $check{$id}; } dbgprint "sum is " . $sum; return $sum; } sub diefailures { my $hosts, @parts; $hosts = ''; foreach $id (keys %check) { if ($check{$id}) { @parts = split(/ /, $id); $hosts .= $parts[0]; } } dbgprint "hosts is " . $hosts; print $hosts, "\n"; exit 1; } getopts("df:p:s:t:"); $Timeout = $opt_t || 900; $hostname = `hostname`; $fromaddr = "mailloop\@$hostname"; # popname is inferred from fromaddr if set with -f opt $popname = 'mailloop'; if ($opt_f) { $fromaddr = $opt_f; @parts = split(/\@/, $opt_f); $popname = $parts[0]; } $poppass = $opt_p || 'mailloop'; $popserv = $opt_s || 'localhost'; $DEBUG = $opt_d || 0; dbgprint "Timeout = $Timeout"; $failures = ""; foreach $reflect (@ARGV) { # Send some mail to the reflector address $id = "$reflect " . strftime("%Y%m%d%H%M%S", localtime(time)); dbgprint "Sending mail: $id"; %mail = ( To => $reflect, From => $fromaddr, Message => "REFL: $id" ); # remember the id for later POP retrieval $check{$id} = 1; if (sendmail %mail) { } else { $failures .= "Error sending mail: $Mail::Sendmail::error " } } dbgprint "Done sending mail"; if ($failures) {die $failures} local $SIG{TERM} = \&diefailures; $starttime = time; # look for replies $pop = new Mail::POP3Client( USER => $popname, PASSWORD => $poppass, HOST => $popserv, DEBUG => $DEBUG); while(checksum()) { if ((time - $starttime) > $Timeout) { diefailures(); } sleep(30); dbgprint "Logging in..."; $pop->Connect; dbgprint "There are " . $pop->Count . " messages"; for ($i = 1; $i <= $pop->Count; $i++) { $id = ""; @lines = split(/\n/, $pop->Body($i)); foreach $line (@lines) { dbgprint $line; if ($line =~ m/REFL: (\S+ \d+)/g) { $id = $1; dbgprint "Found: $id"; } } $check{$id} = 0; $pop->Delete($i); } dbgprint "Logging out"; $pop->Close; } exit 0; mon-contrib-1.0+dfsg/monitors/smtp/mailloop/mailloop.monitor.README000066400000000000000000000047251160532374600253710ustar00rootroot00000000000000# mailloop.monitor - sends email to mailboxes that are expected to send # the mail back to the sender. Probably not hard to do with procmail, etc. # I've only used a reflector agent for Lotus Notes. Instead of "hosts" in # a hostgroup, use email addresses you want to send bounce tests to. The # code still refers to these as hosts. # # You can use as many addresses as you'd like, but you'll need to use a # unique from address for each hostgroup that calls this monitor, because # it eats all the mail this running copy of the monitor didn't send. # Otherwise, previously delayed mail might lay around forever. # # The monitor then polls a POP3 account for the mail it sent. Don't use # that mailbox for anything else, the monitor will delete all your mail! # I'm not kidding, I didn't say "might", it *will*. # # This monitor assumes the local sendmail knows how to get the mail to # the the first relay in the loop you're testing. It also assumes that # the last host knows to deliver mail sent to the configured from # address so that it shows up in the POP server we poll. # # Takes 5 options: # -d Debug Mode. Not really compatible with normal mon scheduling, # because it doesn't log to syslog or anything, just print to STDOUT. # You'll have to call the monitor by hand to use this option. # Mostly helpful to debug your POP/SMTP setup. # # -f Set the from address, this option will also set the POP user to # all the bits before the '@'. So, don't do any wild aliasing... # # -p Set the POP password. Defaults to null password # # -s Set the POP server. Defaults to localhost. # # -t Standard monitor timeout option. # # # $Id: mailloop.monitor.README,v 1.1.1.1 2005/02/18 17:52:24 trockij Exp $ # # Copyright 2000 Shared Medical Systems, Inc. # Author: Bill Smargiassi # Email: william.smargiassi@smed.com # # 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; either version 2 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA mon-contrib-1.0+dfsg/monitors/smtp/smtp-ssl.monitor000077500000000000000000000125071160532374600225670ustar00rootroot00000000000000#!/usr/bin/perl # # Use try to connect to a SMTP server over SSL, and # wait for the right output. Can also warn about cert expiration. # # For use with "mon". # # Arguments are "-p port -t timeout host [host...]" # # Adapted from "smtp.monitor" by # David Nolan, vitroth+mon@cmu.edu # # Which was adapted from "http.monitor" by # Jim Trocki, trockij@transmeta.com # # http.monitor written by # # Jon Meek # American Cyanamid Company # Princeton, NJ # # $Id: smtp-ssl.monitor,v 1.1 2005/08/20 17:54:09 vitroth Exp $ # # Copyright (C) 1998, Jim Trocki # # 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; either version 2 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA # use Getopt::Std; use Net::SSLeay::Handle qw/shutdown/; use English; use Time::ParseDate; getopts ("p:t:T:w:"); $PORT = $opt_p || 465; $TIMEOUT = $opt_t || 30; $THRESHOLD = $opt_T || 0; $EXPIREWARN = $opt_w ; # How long in advance to warn about cert expiration. 0 means don't warn $EXPIREWARN = 0 if (!defined $EXPIREWARN); # Don't warn by default @failures = (); foreach $host (@ARGV) { if (! &smtpGET($host, $PORT)) { push (@failures, $host); } } if (@failures == 0) { exit 0; } print join (" ", sort @failures), "\n"; foreach $msg (@details) { print "$msg\n"; } if (@failures <= $THRESHOLD) { exit @failures; } exit 255; sub smtpGET { use Socket; use Sys::Hostname; my($Server, $Port) = @_; my($ServerOK, $TheContent); my ($OurHostname); $ServerOK = 0; $TheContent = ''; $Path = '/'; ############################################################### eval { local $SIG{ALRM} = sub { die "Timeout Alarm" }; alarm $TIMEOUT; tie(*S2, "Net::SSLeay::Handle", $Server, $Port); $in = ; $in = while $in =~ /^220-/; if ($in !~ /^220 /) { alarm 0; push(@details, "${Server}: $in"); return 0; } $OurHostname = &hostname; print S2 "HELO $OurHostname\r\n"; $in = ; $in = while $in =~ /^250-/; if ($in !~ /^250 /) { alarm 0; push(@details, "${Server}: $in"); return 0; } print S2 "quit\r\n"; $in = ; if ($in !~ /^221 /) { alarm 0; push(@details, "${Server}: $in"); return 0; } $ServerOK = 1; alarm 0; # Cancel the alarm if ($EXPIREWARN) { my $ssl = Net::SSLeay::Handle::_get_ssl(\*S2); my $cert = Net::SSLeay::get_peer_certificate($ssl); my $servercertname = Net::SSLeay::X509_NAME_oneline(Net::SSLeay::X509_get_subject_name($cert)); my $signingcertname = Net::SSLeay::X509_NAME_oneline(Net::SSLeay::X509_get_issuer_name($cert)); my $notafter = Net::SSLeay::P_ASN1_UTCTIME_put2string (Net::SSLeay::X509_get_notAfter($cert)); my $notbefore = Net::SSLeay::P_ASN1_UTCTIME_put2string (Net::SSLeay::X509_get_notBefore($cert)); my $na_time = parsedate($notafter); my $nb_time = parsedate($notbefore); my $now = time; my $later = $now + (86400 * $EXPIREWARN); print STDERR "XXXXX\nnotbefore $notbefore\nnotafter $notafter\nna_time $na_time\nnb_time $nb_time\nnow $now\nlater $later\n" if $opt_v; if ( $now < $nb_time ) { push @details,"$Server: Certificate not valid until $notbefore\ncertificate: $servercertname\nCA certificate: $signingcertname"; $ServerOK = 0; } if ($now > $na_time) { push @details,"$Server: Certificate expired as of $notafter\ncertificate: $servercertname\nCA certificate: $signingcertname"; $ServerOK = 0; } elsif ($later > $na_time ) { push @details,"$Server: Certificate will expire at $notafter\ncertificate: $servercertname\nCA certificate: $signingcertname"; $ServerOK = 0; } } shutdown(\*S2, 1); close(S2); }; if ($EVAL_ERROR) { if ($EVAL_ERROR =~ /^Timeout Alarm/) { push(@details, "${Server}: Connection timed out"); return 0; } else { push(@details, "${Server}: $EVAL_ERROR"); return 0; } } return $ServerOK; } sub OpenSocket { # # Make a Berkeley socket connection between this program and a TCP port # on another (or this) host. Port can be a number or a named service # local($OtherHostname, $Port) = @_; local($OurHostname, $sockaddr, $name, $aliases, $proto, $type, $len, $ThisAddr, $that); $OurHostname = &hostname; ($name, $aliases, $proto) = getprotobyname('tcp'); ($name, $aliases, $Port) = getservbyname($Port, 'tcp') unless $Port =~ /^\d+$/; ($name, $aliases, $type, $len, $ThisAddr) = gethostbyname($OurHostname); ($name, $aliases, $type, $len, $OtherHostAddr) = gethostbyname($OtherHostname); my $that = sockaddr_in ($Port, $OtherHostAddr); $result = socket(S, &PF_INET, &SOCK_STREAM, $proto) || return undef; $result = connect(S, $that) || return undef; select(S); $| = 1; select(STDOUT); # set S to be un-buffered return 1; # success } mon-contrib-1.0+dfsg/monitors/smtp/smtp_rt/000077500000000000000000000000001160532374600210545ustar00rootroot00000000000000mon-contrib-1.0+dfsg/monitors/smtp/smtp_rt/smtp_rt.monitor000066400000000000000000000133741160532374600241650ustar00rootroot00000000000000From ctbates@tva.gov Mon Aug 23 06:55:41 1999 Date: Thu, 08 Jul 1999 11:03:40 -0400 From: Tom Bates To: mon@linux.kernel.org, meir@education.gov.il Subject: Repost of smtp_rt.monitor My previous attempt to post this did not make it out of our MS email system intact. Here it is again: I modified smpt.monitor to watch an email gateway between smpt and MS Exchange, but presumably it could watch any email gateway. smtp_rt.monitor sends an empty message to the monitored mailbox beyand the gateway (monitored_mailbox@yourdomain.com), which sends a return receipt back to a mailbox on the MON host, which has a .forward file piped to mail_handler (e.g., |/home/yourname/mail_handler) which handles the return receipt and lets the monitor know that the round-trip was successful. Tom Bates TVA =============.forward============== |/home/yourname/mail_handler =============end .forward============== =============mail_handler============== #!/usr/bin/perl @msg = ; $x = 0; while ($x < @msg) { if ($msg[$x] =~/^Subject:/) { $msg[$x] =~s/^Subject: Delivered: //; $timestamp = $msg[$x]; chop ($timestamp); } $x++; } open (OUTFILE, ">/tmp/$timestamp"); close (OUTFILE); =============end mail_handler============== =============smtp_rt.monitor============== #!/usr/bin/perl # smpt_rt.monitor # Tries to connect to a SMTP server, send a timestamped message, and # wait for the return receipt to arrive within the timeout period. # # Tom Bates # Tennessee Valley Authority # ctbates@tva.gov # # For use with "mon". # # Arguments are "-p port -t timeout host [host...]" # # Adapted from "smtp.monitor" , which was # Adapted from "http.monitor" by # Jim Trocki, trockij@transmeta.com # # http.monitor written by # # Jon Meek # American Cyanamid Company # Princeton, NJ # # $Id: smtp_rt.monitor,v 1.1.1.1 2005/02/18 17:52:24 trockij Exp $ # # Copyright (C) 1998, Jim Trocki # # 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; either version 2 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA # use Getopt::Std; use English; getopts ("p:t:"); $PORT = $opt_p || 25; $TIMEOUT = $opt_t || 30; $timestamp = substr int(time),0; @failures = (); foreach $host (@ARGV) { if (! &smtpGET($host, $PORT)) { push (@failures, $host); } } if (@failures == 0) { exit 0; } print "@failures\n"; exit 1; sub smtpGET { use Socket; use Sys::Hostname; my($Server, $Port) = @_; my($ServerOK, $TheContent); $ServerOK = 0; $TheContent = ''; $Path = '/'; ############################################################### eval { local $SIG{ALRM} = sub { die "Timeout Alarm" }; alarm $TIMEOUT; $result = &OpenSocket($Server, $Port); # Open a connection to the server if ($result == 0) { # Failure to open the socket return ''; } $in = ; $in = while $in =~ /^220-/; if ($in !~ /^220 /) { alarm 0; return 0; } print S "HELO monhost\r\n"; $in = ; $in = while $in =~ /^250-/; if ($in !~ /^250 /) { alarm 0; return 0; } print S "mail from: yourname\@monserver.yourdomain.com\r\n"; $in = ; $in = while $in =~ /^250-/; if ($in !~ /^250 /) { alarm 0; return 0; } print S "rcpt to: monitored_mailbox\@yourdomain.com\r\n"; $in = ; $in = while $in =~ /^250-/; if ($in !~ /^250 /) { alarm 0; return 0; } print S "data\r\n"; $in = ; $in = while $in =~ /^354-/; if ($in !~ /^354 /) { alarm 0; return 0; } print S "To: monitored_mailbox\@yourdomain.com\nFrom: mon_rt\@monserver.yourdomain.com\nSubject: MON_$timestamp\nReturn-Receipt-To: yourname\@monserver.yourdomain.com\n\n.\n"; $in = ; $in = while $in =~ /^250-/; if ($in !~ /^250 /) { alarm 0; return 0; } print S "quit\r\n"; $in = ; if ($in !~ /^221 /) { alarm 0; return 0; } $returning_file = 0; while ($returning_file == 0) { $returning_file = 1; sleep 5; open (TMPFILE, "/tmp/MON_$timestamp") or $returning_file = 0; } $ServerOK = 1; close(S); alarm 0; # Cancel the alarm }; if ($EVAL_ERROR and ($EVAL_ERROR eq 'Timeout Alarm')) { print "**** Time Out\n"; return 0; } return $ServerOK; } sub OpenSocket { # # Make a Berkeley socket connection between this program and a TCP port # on another (or this) host. Port can be a number or a named service # local($OtherHostname, $Port) = @_; local($OurHostname, $sockaddr, $name, $aliases, $proto, $type, $len, $ThisAddr, $that); $OurHostname = &hostname; ($name, $aliases, $proto) = getprotobyname('tcp'); ($name, $aliases, $Port) = getservbyname($Port, 'tcp') unless $Port =~ /^\d+$/; ($name, $aliases, $type, $len, $ThisAddr) = gethostbyname($OurHostname); ($name, $aliases, $type, $len, $OtherHostAddr) = gethostbyname($OtherHostname); $sockaddr = 'S n a4 x8'; # Format for packed network address $that = pack($sockaddr, &AF_INET, $Port, $OtherHostAddr); $result = socket(S, &PF_INET, &SOCK_STREAM, $proto) || return undef; $result = connect(S, $that) || return undef; select(S); $| = 1; select(STDOUT); # set S to be un-buffered return 1; # success } =============end smtp_rt.monitor============== mon-contrib-1.0+dfsg/monitors/smtp/smtp_rt/smtp_rt.monitor.README000066400000000000000000000050171160532374600251140ustar00rootroot00000000000000From ctbates@tva.gov Mon Aug 23 06:55:41 1999 Date: Thu, 08 Jul 1999 11:03:40 -0400 From: Tom Bates To: mon@linux.kernel.org, meir@education.gov.il Subject: Repost of smtp_rt.monitor My previous attempt to post this did not make it out of our MS email system intact. Here it is again: I modified smpt.monitor to watch an email gateway between smpt and MS Exchange, but presumably it could watch any email gateway. smtp_rt.monitor sends an empty message to the monitored mailbox beyand the gateway (monitored_mailbox@yourdomain.com), which sends a return receipt back to a mailbox on the MON host, which has a .forward file piped to mail_handler (e.g., |/home/yourname/mail_handler) which handles the return receipt and lets the monitor know that the round-trip was successful. Tom Bates TVA =============.forward============== |/home/yourname/mail_handler =============end .forward============== =============mail_handler============== #!/usr/bin/perl @msg = ; $x = 0; while ($x < @msg) { if ($msg[$x] =~/^Subject:/) { $msg[$x] =~s/^Subject: Delivered: //; $timestamp = $msg[$x]; chop ($timestamp); } $x++; } open (OUTFILE, ">/tmp/$timestamp"); close (OUTFILE); =============end mail_handler============== =============smtp_rt.monitor============== #!/usr/bin/perl # smpt_rt.monitor # Tries to connect to a SMTP server, send a timestamped message, and # wait for the return receipt to arrive within the timeout period. # # Tom Bates # Tennessee Valley Authority # ctbates@tva.gov # # For use with "mon". # # Arguments are "-p port -t timeout host [host...]" # # Adapted from "smtp.monitor" , which was # Adapted from "http.monitor" by # Jim Trocki, trockij@transmeta.com # # http.monitor written by # # Jon Meek # American Cyanamid Company # Princeton, NJ # # $Id: smtp_rt.monitor.README,v 1.1.1.1 2005/02/18 17:52:24 trockij Exp $ # # Copyright (C) 1998, Jim Trocki # # 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; either version 2 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software mon-contrib-1.0+dfsg/monitors/snmpvar/000077500000000000000000000000001160532374600200675ustar00rootroot00000000000000mon-contrib-1.0+dfsg/monitors/snmpvar/SNMPVAR-MOVED-TO-MAIN-MON-DISTRIBUTION000066400000000000000000000000001160532374600254040ustar00rootroot00000000000000mon-contrib-1.0+dfsg/monitors/snmpvar/ms-perfmib/000077500000000000000000000000001160532374600221305ustar00rootroot00000000000000mon-contrib-1.0+dfsg/monitors/snmpvar/ms-perfmib/perfmib-setup.cmd000066400000000000000000000014711160532374600254020ustar00rootroot00000000000000rem rem Easy setup for Microsoft NT/Win2K PERFMIB SNMP extensions rem rem Requires MS PERFMIB kit (from Server Resource Kit) rem rem See KB Article Q195336 for required update version rem (ftp://ftp.microsoft.com/bussys/winnt/winnt-public/reskit/nt40/i386/) rem rem See also http://snmpboy.msft.net/asp/perfmibhack.asp rem rem rem perf2mib perfmib.mib perfmib.ini System 1 ntsys Memory 2 mem Processor 3 CPU Server 4 server PhysicalDisk 5 pdisk LogicalDisk 6 ldisk "Paging File" 7 pagefile Telephony 8 telephony rem rem other potentially interesting chapters - include on line above if desired rem "RAS Port" 9 rasport rem "RAS Total" 10 rastot rem net stop SNMP regini perfmib.reg copy perfmib.dll %systemroot%\system32\perfmib.dll copy perfmib.ini %systemroot%\system32\perfmib.ini net start SNMP mon-contrib-1.0+dfsg/monitors/snmpvar/ucd-snmp/000077500000000000000000000000001160532374600216155ustar00rootroot00000000000000mon-contrib-1.0+dfsg/monitors/snmpvar/ucd-snmp/mqueue000077500000000000000000000002761160532374600230510ustar00rootroot00000000000000#!/usr/bin/perl require "find.pl"; # Traverse desired filesystems $counter = 0; &find('/var/spool/mqueue/'); sub wanted { /^qf.*$/ && $counter++; } chomp $counter; print "$counter"; mon-contrib-1.0+dfsg/monitors/snmpvar/ucd-snmp/snmpd.conf000066400000000000000000000007241160532374600236100ustar00rootroot00000000000000############################################################################### # # snmpd.conf # ############################################################################### [... bulk of config file omitted ...] ############################################################################### # Extension Execs ############################################################################### # Index 1 exec mqueue /usr/bin/perl /etc/snmp/mqueue # Index 2 # ... mon-contrib-1.0+dfsg/monitors/ssh/000077500000000000000000000000001160532374600171765ustar00rootroot00000000000000mon-contrib-1.0+dfsg/monitors/ssh/ssh/000077500000000000000000000000001160532374600177735ustar00rootroot00000000000000mon-contrib-1.0+dfsg/monitors/ssh/ssh/ssh.monitor000066400000000000000000000034211160532374600222010ustar00rootroot00000000000000#!/usr/bin/perl # # Connect to a remote SSH server using the 'ssh' command. # # $Id: ssh.monitor,v 1.1.1.1 2005/02/18 17:52:24 trockij Exp $ # # Written by Steven F. Siirila, sfs@umn.edu. # # Copyright (c) 2000 Regents of the University of Minnesota. # All rights reserved. # # Permission to use, copy, modify, and distribute this software and # documentation without fee is hereby granted, provided that the # University of Minnesota copyright notices and this permission notice # appear in all copies, and that the name University of Minnesota not # be used in advertising or publicity pertaining to this software and # documentation without specific, written prior permission. # # The University of Minnesota makes no representations about the # suitability of this software and documentation for any purpose. # It is provided ``as is'' without express or implied warranty. # foreach $host (@ARGV) { system("fping -q -r 3 -t 2000 $host 2>/dev/null"); $status = $? / 256; next if $status; # ignore hosts which are not pingable $errmsg = `ssh $host /usr/bin/true 2>&1`; chomp($errmsg); $rc = $?; if ($rc == 0) { next; } elsif ($rc == 0xff00) { &alert("ssh command failed"); } elsif ($rc > 0x80) { $rc >>= 8; &alert("exited with status $rc"); } elsif ($rc & 0x80) { $rc &= ~0x80; &alert("exited with coredump from signal $rc"); } else { &alert("exited with signal $rc"); } } exit 0 unless %failures; print join(' ', sort keys %failures), "\n"; foreach $id (sort keys %failures) { print $failures{$id}; } exit 1; sub alert { my($msg) = @_; $failures{$host} .= "${host}:"; $failures{$host} .= $errmsg if $errmsg; $failures{$host} .= "$msg\n"; }mon-contrib-1.0+dfsg/monitors/ssh/ssh/ssh.monitor.README000066400000000000000000000025721160532374600231430ustar00rootroot00000000000000Subject: UMN ssh.monitor Date: Fri, 16 Mar 2001 10:23:50 -0600 (CST) From: Steve Siirila To: mon@linux.kernel.org The monitor below assumes that an SSH authorized keys file is set up on any remote systems monitored which a null passphrase (under user monitor). This may not be acceptable for some sites. We generally further control SSH access by not denying connections (via hosts.allow) from all but certain hosts. #!/usr/bin/perl # # Connect to a remote SSH server using the 'ssh' command. # # $Id: ssh.monitor.README,v 1.1.1.1 2005/02/18 17:52:24 trockij Exp $ # # Written by Steven F. Siirila, sfs@umn.edu. # # Copyright (c) 2000 Regents of the University of Minnesota. # All rights reserved. # # Permission to use, copy, modify, and distribute this software and # documentation without fee is hereby granted, provided that the # University of Minnesota copyright notices and this permission notice # appear in all copies, and that the name University of Minnesota not # be used in advertising or publicity pertaining to this software and # documentation without specific, written prior permission. # # The University of Minnesota makes no representations about the # suitability of this software and documentation for any purpose. # It is provided ``as is'' without express or implied warranty. # mon-contrib-1.0+dfsg/monitors/ssl/000077500000000000000000000000001160532374600172025ustar00rootroot00000000000000mon-contrib-1.0+dfsg/monitors/ssl/ssl-cert-check000066400000000000000000000530061160532374600217400ustar00rootroot00000000000000#!/bin/bash # # Program: SSL Certificate Check # # Source code home: http://prefetch.net/code/ssl-cert-check # # Author: Matty < matty91 at gmail dot com > # # Current Version: 3.14 # # Revision History: # # Version 3.14 # - Fixed the Common Name parser to handle DN's where the CN is not the last item # eg. EmailAddr -- Jason Brothers # - Added the ability to grab the serial number -- Jason Brothers # - Added the "-b" option to print results without a header -- Jason Brothers # - Added the "-v" option for certificate validation -- Jason Brothers # # Version 3.13 # - Updated the subject line to include the hostname as well as # the common name embedded in the X509 certificate (if it's # available) -- idea proposed by Mike Burns # # Version 3.12 # - Updated the license to allow redistribution and modification # # Version 3.11 # - Added ability to comment out lines in files passed # to the "-f" option -- Brett Stauner # - Fixed comment next to file processing logic # # Version 3.10 # - Fixed POP3 port -- Simon Matter # # Version 3.9 # - Switched binary location logic to use which utility # # Version 3.8 # - Fixed display on 80 column displays # - Cleaned up the formatting # # Version 3.7 # - Fixed bug in NAGIOS tests -- Ben Allen # # Version 3.6 # - Added support for certificates stored in PKCS#12 databases -- Ken Gallo # - Cleaned up comments # - Adjusted variables to be more consistent # # Version 3.5 # - Added support for NAGIOS -- Quanah Gibson-Mount # - Added additional checks for mail -- Quanah Gibson-Mount # - Convert tabs to spaces -- Quanah Gibson-Mount # - Cleaned up usage() routine # - Added additional checks for openssl # # Version 3.4 # - Added a missing "{" to line 364 -- Ken Gallo # - Move mktemp to the start of the main body to avoid errors # - Adjusted default binary paths to make sure the script just works # w/ Solaris, BSD and Linux hosts # # Version 3.3 # - Added common name from X.509 certificate file to E-mail body / header -- Doug Curtis # - Fixed several documentation errors # - Use mktemp to create temporary files # - Convert printf, sed and awk to variables # - Check for printf, sed, awk and mktemp binaries # - Add additional logic to make sure mktemp returned a valid temporary file # # Version 3.2 # - Added option to list certificates in the file passed to "-f". # # Version 3.1 # - Added handling for starttls for smtp -- Marco Amrein # - Added handling for starttls for pop3 (without s) -- Marco Amrein # - Removed extra spacing at end of script # # Version 3.0 # - Added "-i" option to print certificate issuer # - Removed $0 from Subject line of outbound e-mails # - Fixed some typographical errors # - Removed redundant "-b" option # # Version 2.0 # - Fixed an issue with e-mails formatting incorrectly # - Added additional space to host column -- Darren-Perot Spruell # - Replaced GNU date dependency with CHRIS F. A. JOHNSON's # date2julian shell function. This routine can be found on # page 170 of Chris's book "Shell Scripting Recipes: A # Problem-Solution Approach," ISBN #1590594711. Julian function # was created based on a post to comp.unix.shell by Tapani Tarvainen. # - Cleaned up function descriptions # - Removed several lines of redundant code # - Adjusted the help message # # Version 1.1 # - Added "-c" flag to report expiration status of a PEM encoded # certificate -- Hampus Lundqvist # - Updated the prints messages to display the reason a connection # failed (connection refused, connection timeout, bad cert, etc) # - Updated the GNU date checking routines # - Added checks for each binary required # - Added checks for connection timeouts # - Added checks for GNU date # - Added a "-h" option # - Cleaned up the documentation # # Version 1.0 # Initial Release # # Last Updated: 05-06-2008 # # Purpose: # ssl-cert-check checks to see if a digital certificate in X.509 format # has expired. ssl-cert-check can be run in interactive and batch mode, # and provides facilities to alarm if a certificate is about to expire. # # License: # Copyright (C) 2007 Ryan Matteson # 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; either version 2 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # Requirements: # Requires openssl # # Installation: # Copy the shell script to a suitable location # # Tested platforms: # -- Solaris 9 using /bin/bash # -- Solaris 10 using /bin/bash # -- OS X 10.4.2 using /bin/sh # -- OpenBSD using /bin/sh # -- FreeBSD using /bin/sh # -- Redhat advanced server 3.0MU3 using /bin/sh # # Usage: # Refer to the usage() sub-routine, or invoke ssl-cert-check # with the "-h" option. # # Examples: # Please refer to the following site for documentation and # examples: # http://prefetch.net/articles/checkcertificate.html # PATH=/bin:/usr/bin:/usr/local/bin:/usr/local/ssl/bin:/usr/sfw/bin ; export PATH # Who to page when an expired certificate is detected (cmdline: -e) ADMIN="root" # Number of days in the warning threshhold (cmdline: -x) WARNDAYS=30 # If QUIET is set to TRUE, don't print anything on the console (cmdline: -q) QUIET="FALSE" # Don't send E-mail by default (cmdline: -a) ALARM="FALSE" # Don't run as a Nagios plugin by default (cmdline: -n) NAGIOS="FALSE" # NULL out the PKCSDBPASSWD variable for later use (cmdline: -k) PKCSDBPASSWD="" # Location of system binaries AWK=$(which awk) DATE=$(which date) GREP=$(which grep) OPENSSL=$(which openssl) PRINTF=$(which printf) SED=$(which sed) MKTEMP=$(which mktemp) if [ -f /usr/bin/mailx ] then MAIL="/usr/bin/mailx" else MAIL=$(which mail) fi # Return code used by nagios. Initialize to 0. RETCODE=0 # Set the default umask to be somewhat restrictive umask 077 ############################################################################# # Purpose: Convert a date from MONTH-DAY-YEAR to Julian format # Acknowledgements: Code was adapted from examples in the book # "Shell Scripting Recipes: A Problem-Solution Approach" # ( ISBN 1590594711 ) # Arguments: # $1 -> Month (e.g., 06) # $2 -> Day (e.g., 08) # $3 -> Year (e.g., 2006) ############################################################################# date2julian() { if [ "${1} != "" ] && [ "${2} != "" ] && [ "${3}" != "" ] then ## Since leap years add aday at the end of February, ## calculations are done from 1 March 0000 (a fictional year) d2j_tmpmonth=$((12 * ${3} + ${1} - 3)) ## If it is not yet March, the year is changed to the previous year d2j_tmpyear=$(( ${d2j_tmpmonth} / 12)) ## The number of days from 1 March 0000 is calculated ## and the number of days from 1 Jan. 4713BC is added echo $(( (734 * ${d2j_tmpmonth} + 15) / 24 - 2 * ${d2j_tmpyear} + ${d2j_tmpyear}/4 - ${d2j_tmpyear}/100 + ${d2j_tmpyear}/400 + $2 + 1721119 )) else echo 0 fi } ############################################################################# # Purpose: Convert a string month into an integer representation # Arguments: # $1 -> Month name (e.g., Sep) ############################################################################# getmonth() { case ${1} in Jan) echo 1 ;; Feb) echo 2 ;; Mar) echo 3 ;; Apr) echo 4 ;; May) echo 5 ;; Jun) echo 6 ;; Jul) echo 7 ;; Aug) echo 8 ;; Sep) echo 9 ;; Oct) echo 10 ;; Nov) echo 11 ;; Dec) echo 12 ;; *) echo 0 ;; esac } ############################################################################# # Purpose: Calculate the number of seconds between two dates # Arguments: # $1 -> Date #1 # $2 -> Date #2 ############################################################################# date_diff() { if [ "${1}" != "" ] && [ "${2}" != "" ] then echo $((${2} - ${1})) else echo 0 fi } ##################################################################### # Purpose: Print a line with the expiraton interval # Arguments: # $1 -> Hostname # $2 -> TCP Port # $3 -> Status of certification (e.g., expired or valid) # $4 -> Date when certificate will expire # $5 -> Days left until the certificate will expire # $6 -> Issuer of the certificate ##################################################################### prints() { if [ "${QUIET}" != "TRUE" ] && [ "${ISSUER}" = "TRUE" ] && [ "${VALIDATION}" != "TRUE" ] then MIN_DATE=$(echo $4 | ${AWK} '{ print $1, $2, $4 }') ${PRINTF} "%-35s %-17s %-8s %-11s %-4s %-30s\n" "$1:$2" "$6" "$3" "$MIN_DATE" "$5" elif [ "${QUIET}" != "TRUE" ] && [ "${ISSUER}" = "TRUE" ] && [ "${VALIDATION}" == "TRUE" ] then ${PRINTF} "%-35s %-35s %-32s %-17s\n" "$1:$2" "$7" "$8" "$6" elif [ "${QUIET}" != "TRUE" ] && [ "${VALIDATION}" != "TRUE" ] then MIN_DATE=$(echo $4 | ${AWK} '{ print $1, $2, $4 }') ${PRINTF} "%-47s %-12s %-12s %-4s %-30s\n" "$1:$2" "$3" "$MIN_DATE" "$5" elif [ "${QUIET}" != "TRUE" ] && [ "${VALIDATION}" == "TRUE" ] then ${PRINTF} "%-35s %-35s %-32s\n" "$1:$2" "$7" "$8" fi } #################################################### # Purpose: Print a heading with the relevant columns # Arguments: # None #################################################### print_heading() { if [ "${NOHEADER}" != "TRUE" ] then if [ "${QUIET}" != "TRUE" ] && [ "${ISSUER}" = "TRUE" ] && [ "${NAGIOS}" != "TRUE" ] && [ "${VALIDATION}" != "TRUE" ] then ${PRINTF} "\n%-35s %-17s %-8s %-11s %-4s\n" "Host" "Issuer" "Status" "Expires" "Days" echo "----------------------------------- ----------------- -------- ----------- ----" elif [ "${QUIET}" != "TRUE" ] && [ "${ISSUER}" = "TRUE" ] && [ "${NAGIOS}" != "TRUE" ] && [ "${VALIDATION}" == "TRUE" ] then ${PRINTF} "\n%-35s %-35s %-32s %-17s\n" "Host" "Common Name" "Serial #" "Issuer" echo "----------------------------------- ----------------------------------- -------------------------------- -----------------" elif [ "${QUIET}" != "TRUE" ] && [ "${NAGIOS}" != "TRUE" ] && [ "${VALIDATION}" != "TRUE" ] then ${PRINTF} "\n%-47s %-12s %-12s %-4s\n" "Host" "Status" "Expires" "Days" echo "----------------------------------------------- ------------ ------------ ----" elif [ "${QUIET}" != "TRUE" ] && [ "${NAGIOS}" != "TRUE" ] && [ "${VALIDATION}" == "TRUE" ] then ${PRINTF} "\n%-35s %-35s %-32s\n" "Host" "Common Name" "Serial #" echo "----------------------------------- ----------------------------------- --------------------------------" fi fi } ########################################## # Purpose: Describe how the script works # Arguments: # None ########################################## usage() { echo "Usage: $0 [ -e email address ] [ -x days ] [-q] [-a] [-b] [-h] [-i] [-n] [-v]" echo " { [ -s common_name ] && [ -p port] } || { [ -f cert_file ] } || { [ -c certificate file ] }" echo "" echo " -a : Send a warning message through E-mail" echo " -b : Will not print header" echo " -c cert file : Print the expiration date for the PEM or PKCS12 formatted certificate in cert file" echo " -e E-mail address : E-mail address to send expiration notices" echo " -f cert file : File with a list of FQDNs and ports" echo " -h : Print this screen" echo " -i : Print the issuer of the certificate" echo " -k password : PKCS12 file password" echo " -n : Run as a Nagios plugin" echo " -p port : Port to connect to (interactive mode)" echo " -s commmon name : Server to connect to (interactive mode)" echo " -q : Don't print anything on the console" echo " -v : Only print validation data" echo " -x days : Certificate expiration interval (eg. if cert_date < days)" echo "" } ########################################################################## # Purpose: Connect to a server ($1) and port ($2) to see if a certificate # has expired # Arguments: # $1 -> Server name # $2 -> TCP port to connect to ########################################################################## check_server_status() { if [ "_${2}" = "_smtp" -o "_${2}" = "_25" ] then TLSFLAG="-starttls smtp" elif [ "_${2}" = "_pop3" -o "_${2}" = "_110" ] then TLSFLAG="-starttls pop3" else TLSFLAG="" fi echo "" | ${OPENSSL} s_client -connect ${1}:${2} ${TLSFLAG} 2> ${ERROR_TMP} 1> ${CERT_TMP} if ${GREP} -i "Connection refused" ${ERROR_TMP} > /dev/null then prints ${1} ${2} "Connection refused" "Unknown" elif ${GREP} -i "gethostbyname failure" ${ERROR_TMP} > /dev/null then prints ${1} ${2} "Cannot resolve domain" "Unknown" elif ${GREP} -i "Operation timed out" ${ERROR_TMP} > /dev/null then prints ${1} ${2} "Operation timed out" "Unknown" elif ${GREP} -i "ssl handshake failure" ${ERROR_TMP} > /dev/null then prints ${1} ${2} "SSL handshake failed" "Unknown" elif ${GREP} -i "connect: Connection timed out" ${ERROR_TMP} > /dev/null then prints ${1} ${2} "Connection timed out" "Unknown" else check_file_status ${CERT_TMP} $1 $2 fi } ##################################################### ### Check the expiration status of a certificate file ### Accepts three parameters: ### $1 -> certificate file to process ### $2 -> Server name ### $3 -> Port number of certificate ##################################################### check_file_status() { CERTFILE=${1} HOST=${2} PORT=${3} ### Check to make sure the certificate file exists if [ ! -r ${CERTFILE} ] then echo "ERROR: The file named ${CERTFILE} is unreadable or doesn't exist" RETCODE=1 return fi ### Grab the expiration date from the X.509 certificate if [ "${PKCSDBPASSWD}" != "" ] then # Extract the certificate from the PKCS#12 database, and # send the informational message to /dev/null ${OPENSSL} pkcs12 -nokeys -in ${CERTFILE} \ -out ${CERT_TMP} -password pass:${PKCSDBPASSWD} 2> /dev/null # Extract the expiration date from the certificate CERTDATE=$(${OPENSSL} x509 -in ${CERT_TMP} -enddate -noout | \ ${SED} 's/notAfter\=//') # Extract the issuer from the certificate CERTISSUER=$(${OPENSSL} x509 -in ${CERT_TMP} -issuer -noout | \ ${AWK} 'BEGIN {RS="/" } $0 ~ /^O=/ \ { print substr($0,3,17)}') ### Grab the common name (CN) from the X.509 certificate COMMONNAME=$(${OPENSSL} x509 -in ${CERT_TMP} -subject -noout | \ ${SED} -e 's/.*CN=//' | \ ${SED} -e 's/\/.*//') ### Grab the serial number from the X.509 certificate SERIAL=$(${OPENSSL} x509 -in ${CERT_TMP} -serial -noout | \ ${SED} -e 's/serial=//') else # Extract the expiration date from the ceriticate CERTDATE=$(${OPENSSL} x509 -in ${CERTFILE} -enddate -noout | \ ${SED} 's/notAfter\=//') # Extract the issuer from the certificate CERTISSUER=$(${OPENSSL} x509 -in ${CERTFILE} -issuer -noout | \ ${AWK} 'BEGIN {RS="/" } $0 ~ /^O=/ { print substr($0,3,17)}') ### Grab the common name (CN) from the X.509 certificate COMMONNAME=$(${OPENSSL} x509 -in ${CERTFILE} -subject -noout | \ ${SED} -e 's/.*CN=//' | \ ${SED} -e 's/\/.*//') ### Grab the serial number from the X.509 certificate SERIAL=$(${OPENSSL} x509 -in ${CERT_TMP} -serial -noout | \ ${SED} -e 's/serial=//') fi ### Split the result into parameters, and pass the relevant pieces to date2julian set -- ${CERTDATE} MONTH=$(getmonth ${1}) # Convert the date to seconds, and get the diff between NOW and the expiration date CERTJULIAN=$(date2julian ${MONTH#0} ${2#0} ${4}) CERTDIFF=$(date_diff ${NOWJULIAN} ${CERTJULIAN}) if [ ${CERTDIFF} -lt 0 ] then if [ "${ALARM}" = "TRUE" ] then echo "The SSL certificate for ${HOST} \"(CN: ${COMMONNAME})\" has expired!" \ | ${MAIL} -s "Certificate for ${HOST} \"(CN: ${COMMONNAME})\" has expired!" ${ADMIN} fi prints ${HOST} ${PORT} "Expired" "${CERTDATE}" "${CERTDIFF}" "${CERTISSUER}" "${COMMONNAME}" "${SERIAL}" RETCODE=2 elif [ ${CERTDIFF} -lt ${WARNDAYS} ] then if [ "${ALARM}" = "TRUE" ] then echo "The SSL certificate for ${HOST} \"(CN: ${COMMONNAME})\" will expire on ${CERTDATE}" \ | ${MAIL} -s "Certificate for ${HOST} \"(CN: ${COMMONNAME})\" will expire in ${WARNDAYS}-days or less" ${ADMIN} fi prints ${HOST} ${PORT} "Expiring" "${CERTDATE}" "${CERTDIFF}" "${CERTISSUER}" "${COMMONNAME}" "${SERIAL}" RETCODE=1 else prints ${HOST} ${PORT} "Valid" "${CERTDATE}" "${CERTDIFF}" "${CERTISSUER}" "${COMMONNAME}" "${SERIAL}" RETCODE=0 fi } ################################# ### Start of main program ################################# while getopts abinve:f:c:hk:p:s:qx: option do case "${option}" in a) ALARM="TRUE";; b) NOHEADER="TRUE";; c) CERTFILE=${OPTARG};; e) ADMIN=${OPTARG};; f) SERVERFILE=$OPTARG;; h) usage exit 1;; i) ISSUER="TRUE";; k) PKCSDBPASSWD=${OPTARG};; n) NAGIOS="TRUE";; p) PORT=$OPTARG;; s) HOST=$OPTARG;; q) QUIET="TRUE";; v) VALIDATION="TRUE";; x) WARNDAYS=$OPTARG;; \?) usage exit 1;; esac done ### Check to make sure a openssl utility is available if [ ! -f ${OPENSSL} ] then echo "ERROR: The openssl binary does not exist in ${OPENSSL}." echo "FIX: Please modify the \${OPENSSL} variable in the program header." exit 1 fi ### Check to make sure a date utility is available if [ ! -f ${DATE} ] then echo "ERROR: The date binary does not exist in ${DATE} ." echo "FIX: Please modify the \${DATE} variable in the program header." exit 1 fi ### Check to make sure a grep utility is available if [ ! -f ${GREP} ] then echo "ERROR: The grep binary does not exist in ${GREP} ." echo "FIX: Please modify the \${GREP} variable in the program header." exit 1 fi ### Check to make sure the mktemp and printf utilities are available if [ ! -f ${MKTEMP} ] || [ ! -f ${PRINTF} ] then echo "ERROR: Unable to locate the mktemp or printf binary." echo "FIX: Please modify the \${MKTEMP} and \${PRINTF} variables in the program header." exit 1 fi ### Check to make sure the sed and awk binaries are available if [ ! -f ${SED} ] || [ ! -f ${AWK} ] then echo "ERROR: Unable to locate the sed or awk binary." echo "FIX: Please modify the \${SED} and \${AWK} variables in the program header." exit 1 fi ### CHeck to make sure a mail client is available it automated notifcations are requested if [ "${ALARM}" = "TRUE" ] && [ ! -f ${MAIL} ] then echo "ERROR: You enabled automated alerts, but the mail binary could not be found." echo "FIX: Please modify the ${MAIL} variable in the program header." exit 1 fi # Place to stash temporary files CERT_TMP=$($MKTEMP /var/tmp/cert.XXXXXX) ERROR_TMP=$($MKTEMP /var/tmp/error.XXXXXX) ### Baseline the dates so we have something to compare to MONTH=$(${DATE} "+%m") DAY=$(${DATE} "+%d") YEAR=$(${DATE} "+%Y") NOWJULIAN=$(date2julian ${MONTH#0} ${DAY#0} ${YEAR}) ### Touch the files prior to using them if [ ! -z "${CERT_TMP}" ] && [ ! -z "${ERROR_TMP}" ] then touch ${CERT_TMP} ${ERROR_TMP} else echo "ERROR: Problem creating temporary files" echo "FIX: Check that mktemp works on your system" exit 1 fi ### If a HOST and PORT were passed on the cmdline, use those values if [ "${HOST}" != "" ] && [ "${PORT}" != "" ] then print_heading check_server_status "${HOST}" "${PORT}" ### If a file is passed to the "-f" option on the command line, check ### each certificate or server / port combination in the file to see if ### they are about to expire elif [ -f "${SERVERFILE}" ] then print_heading while read HOST PORT do if [ "${HOST:0:1}" = "#" ] then : elif [ "$PORT" = "FILE" ] then check_file_status ${HOST} "FILE" "${HOST}" else check_server_status "${HOST}" "${PORT}" fi done < ${SERVERFILE} ### Check to see if the certificate in CERTFILE is about to expire elif [ "${CERTFILE}" != "" ] then print_heading check_file_status ${CERTFILE} "FILE" "${CERTFILE}" ### There was an error, so print a detailed usage message and exit else usage exit 1 fi ### Remove the temporary files rm -f ${CERT_TMP} ${ERROR_TMP} ### Exit with a success indicator if [ "${NAGIOS}" = "TRUE" ]; then exit $RETCODE else exit 0 fi mon-contrib-1.0+dfsg/monitors/sybase/000077500000000000000000000000001160532374600176675ustar00rootroot00000000000000mon-contrib-1.0+dfsg/monitors/sybase/sybase/000077500000000000000000000000001160532374600211555ustar00rootroot00000000000000mon-contrib-1.0+dfsg/monitors/sybase/sybase/sybase.cf000066400000000000000000000022301160532374600227520ustar00rootroot00000000000000# # sybase.cf - configuration file for sybase.monitor # # Format: # # SERVER servername username password # database dbusage minfree # # servername name of the Sybase server, as used in the "interfaces" file # valid for all entries until next SERVER statement # # database name of the database to check, e.g. "master" # NB: case sensitive even if your Sybase installation is not! # # dbusage "data_only", "log_only" or "data_and_log" # must match actual usages, otherwise will not be compared # # minfree minimum amount of free space in the database, as "xxxMB" # SERVER devdb sa sapassword warehouse data_only 200MB warehouse log_only 100MB tempdb data_and_log 50MB SERVER proddb sa sapassword budget data_only 10MB budget log_only 20MB warehouse data_only 200MB warehouse log_only 200MB personnel data_only 10MB personnel log_only 5MB sybsecurity data_only 20MB sybsecurity log_only 10MB tempdb data_and_log 50MB master data_and_log 5MB mon-contrib-1.0+dfsg/monitors/sybase/sybase/sybase.monitor000077500000000000000000000146611160532374600240670ustar00rootroot00000000000000#!/usr/bin/perl # ##################################################################### ## ## ## sybase.monitor Version 1.1.0 ## ## 1999-09-13 ## ## Copyright (C) 1999 ## ## Peter Holzleitner (P.Holzleitner@computer.org) ## ## ## ##################################################################### # # A MON plug-in monitor to determine if a Sybase database server is # operational and whether there is enough free space in the database(s). # # Arguments: # # [-username=uid] [-password=pwd] [-config=configfile] [-list] serverlist # # Note that the server names correspond to the entries in the Sybase # "interfaces" file and may be different from the DNS hostnames. # The server name lookup is case sensitive in Sybase. # # Requirements: # # This monitor requires the perl5 DBI and DBD::Sybase modules, # available from CPAN (http://www.cpan.org) # # 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; either version 2 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software Foundation, # Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA # # History: # # 1.1.0 add check for infected and log-suspended processes # 1.0.0 initial release use DBI; use Getopt::Long; sub readcf; GetOptions( \%opt, "username=s", "password=s", "config=s", "list" ); die "no host arguments\n" if (@ARGV == 0); $RET = 0; @ERRS = (); @SERVERS = (); $CONFIG = $opt{"config"} || (-d "/etc/mon" ? "/etc/mon" : "/usr/lib/mon/etc") . "/sybase.cf"; readcf ($CONFIG) || die "could not read config: $!\n"; # # SQL text of the queries to be executed # $free_q = q{ select dbname = d.name, usage = vl.name, free_M = convert(int, sum(curunreservedpgs(u.dbid, u.lstart, u.unreservedpgs)) / (select 1048576. / low from master.dbo.spt_values where number = 1 and type = 'E') ) from master.dbo.sysdatabases d, master.dbo.syslogins l, master.dbo.sysusages u, master.dbo.sysdevices v, master.dbo.spt_values vl where d.suid = l.suid and d.dbid = u.dbid and v.low <= u.vstart and u.vstart <= v.high and vl.type = 'S' and vl.number = u.segmap & 7 group by d.name, vl.name }; $proc_q = q{ select p.spid, p.status, p.hostname, p.program_name, d.name as dbname, l.name as username from master..sysprocesses p, master..syslogins l, master..sysdatabases d where p.suid = l.suid and p.dbid = d.dbid and p.status in ('infected', 'log suspend') }; foreach $server (@ARGV) { next if (!defined $UID{$server}); # need credentials from cfg file! # # log in to database server # if(!defined($dbh = DBI->connect("dbi:Sybase:server=$server", $UID{"$server"}, $PWD{"$server"}, {PrintError => 0, RaiseError => 0, AutoCommit => 1}) )) { $RET = ($RET == 1) ? 1 : 2; push (@SERVERS, $server); push (@ERRS, "could not connect to $server: " . $DBI::errstr); next; } # # query free space on databases, compare to limits read from cfg file # if(!defined($sth = $dbh->prepare($free_q)) or !defined($sth->execute) ) { $RET = ($RET == 1) ? 1 : 2; push (@SERVERS, $server); push (@ERRS, "could not execute query on $server: " . $DBI::errstr); $sth->finish; $dbh->disconnect; next; } while (($database, $dbusage, $free) = $sth->fetchrow_array) { $required = $REQUIRED{$server}{$database}{$dbusage}; if ($required eq '') { $err = '?'; write if ($opt{"list"}); } else { $err = $free < $required ? 'LOW!' : 'ok'; write if ($opt{"list"}); if ( $free < $required ) { push (@SERVERS, $server); push (@ERRS, sprintf ("%dMB free on %s (%s)", $free, $database, $dbusage)); $RET = 1; } } } $sth->finish; # # query for un-healthy processes # if(!defined($sth = $dbh->prepare($proc_q)) or !defined($sth->execute) ) { $RET = ($RET == 1) ? 1 : 2; push (@SERVERS, $server); push (@ERRS, "could not execute query on $server: " . $DBI::errstr); $sth->finish; $dbh->disconnect; next; } $phdr = 0; while (($spid, $stat, $hst, $prg, $db, $usr) = $sth->fetchrow_array) { if($phdr == 0) { push (@SERVERS, $server); push (@ERRS, sprintf (" spid status clienthost clientprog dbname username")); $phdr = 1; } push (@ERRS, sprintf ("%5d %-12.12s %-10.10s %-14.14s %-12.12s %s", $spid, $stat, $hst, $prg, $db, $usr)); $RET = 1; } $sth->finish; # # disconnect from this server # $dbh->disconnect; } if ($RET) { print "@SERVERS\n"; print "\n"; print join("\n", @ERRS), "\n"; } exit $RET; # # read configuration file # sub readcf { my ($f) = @_; my ($l, $tag, $server, $uid, $pwd, $database, $dbusage, $required); open (CF, $f) || return undef; while () { next if (/^\s*#/ || /^\s*$/); chomp; if (/^SERVER/) { ($tag, $server, $uid, $pwd) = split; $UID{"$server"} = $uid; $PWD{"$server"} = $pwd; next; } ($database, $dbusage, $required) = split; $dbusage =~ s/_/ /g; $required =~ /^(\d+)mb/i; $required = $1; if (!defined ($REQUIRED{$server}{$database}{$dbusage} = $required)) { die "error in free space spec, config $f, line $.\n"; } } close (CF); } format STDOUT_TOP = Server Database Usage MB free Status -------------------------------------------------------------------------- . format STDOUT = @<<<<<<<<<<<<<< @<<<<<<<<<<<<<<<<<<<<<< @<<<<<<<<<<<<< @>>>>>>> @<<<<< $server, $database, $dbusage, $free, $err . mon-contrib-1.0+dfsg/monitors/sybase/sybase/sybasemon.README000066400000000000000000000036751160532374600240470ustar00rootroot00000000000000##################################################################### ## ## ## sybase.monitor Version 1.1.0 ## ## 1999-09-13 ## ## Copyright (C) 1999 ## ## Peter Holzleitner (P.Holzleitner@computer.org) ## ## ## ##################################################################### # # A MON plug-in monitor to determine if a Sybase database server is # operational and whether there is enough free space in the database(s). # # Arguments: # # [-username=uid] [-password=pwd] [-config=configfile] [-list] serverlist # # Note that the server names correspond to the entries in the Sybase # "interfaces" file and may be different from the DNS hostnames. # The server name lookup is case sensitive in Sybase. # # Requirements: # # This monitor requires the perl5 DBI and DBD::Sybase modules, # available from CPAN (http://www.cpan.org) # # 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; either version 2 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software Foundation, # Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA # # History: # # 1.1.0 add check for infected and log-suspended processes # 1.0.0 initial release mon-contrib-1.0+dfsg/monitors/tcp/000077500000000000000000000000001160532374600171675ustar00rootroot00000000000000mon-contrib-1.0+dfsg/monitors/tcp/tcpch/000077500000000000000000000000001160532374600202705ustar00rootroot00000000000000mon-contrib-1.0+dfsg/monitors/tcp/tcpch/tcpch.monitor000077500000000000000000000132461160532374600230130ustar00rootroot00000000000000#!/usr/bin/perl -w # # try to connect to a particular # port on a bunch of hosts. For use with "mon". # # Options are # -p # -t (default 15) # -s # -e # -q # -d # without /-s/-e/-q/, just checks that the socket can be opened # and closed. # cheap transformations done on send/quit/delim strings - \r and \n are # converted to CR and LF. \\ is not supported - no escape possible. # sample usage: # # smtp: tcpch.monitor -p 25 -e '^220\b' -q 'QUIT\r\n' # web: tcpch.monitor -p 80 -s 'GET / HTTP/1.0\r\n' -e '^HTTP.*200 OK' # # Jim Trocki, trockij@transmeta.com # updated August 2000 by Ed Ravin for send/expect/quit # # $Id: tcpch.monitor,v 1.1.1.1 2005/02/18 17:52:23 trockij Exp $ # # Copyright (C) 1998, Jim Trocki # # 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; either version 2 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA # use Getopt::Std; use Socket; my %opt; getopts ("d:p:t:s:e:q:", \%opt); $USAGE= "Usage: tcpch.monitor -p port [-t timeout] [-s sendstr] [-e regexp] [-q quitstr] [-d line-delim]\n"; my $PORT = $opt{"p"} || undef; my $TIMEOUT = $opt{"t"} || 15; my $SEND= $opt{"s"} || undef; my $EXPECT= $opt{"e"} || undef; my $QUITSTR=$opt{"q"} || undef; my $DELIM= $opt{"d"} || "\n"; if ($DELIM) { $DELIM=~ s/\\n/\n/g; $DELIM=~ s/\\r/\r/g; } my @failures = (); my @detail = (); my $ALARM = 0; sub checkbuf # buffer, regexp { my ($buffer, $regexp)= @_; return $buffer =~ /$regexp/ if ($DELIM eq ''); my @lines= split($DELIM, $buffer); foreach my $line (@lines) { if ($line =~ /$regexp/) { return 1; } } return 0; } die $USAGE unless (@ARGV > 0); die "$0: missing port number\n" unless defined $PORT; foreach my $host (@ARGV) { my $pro = getprotobyname ('tcp'); if (!defined $pro) { die "(local err) could not getprotobyname\n"; } if (!defined socket (S, PF_INET, SOCK_STREAM, $pro)) { die "(local err) could not create socket: $!\n"; } my $a = inet_aton ($host); if (!defined $a) { push @failures, $host; push @detail, "(local err) $host could not inet_aton"; close (S); next; } my $sin = sockaddr_in ($PORT, $a); if (!defined $sin) { push @failures, $host; push @detail, "(local err) $host could not sockaddr_in"; close (S); next; } my $r; eval { local $SIG{"ALRM"} = sub { die "alarm\n" }; alarm $TIMEOUT; $r = connect (S, $sin); alarm 0; }; if ($@) { push @failures, $host; if ($@ eq "alarm\n") { push @detail, "$host timeout on connect"; } else { push @detail, "$host interrupted syscall on connect: $!"; } close (S); next; } if (!defined $r) { push @failures, $host; push @detail, "$host: could not connect: $!"; close (S); next; } select S; $|= 1; select STDOUT; if (defined($SEND)) { my $rc= undef; $SEND=~ s/\\n/\n/g; $SEND=~ s/\\r/\r/g; eval { local $SIG{"ALRM"} = sub { die "alarm\n" }; alarm $TIMEOUT; $rc= send S, $SEND, 0; alarm 0; }; if ($@) { push @failures, $host; if ($@ eq "alarm\n") { push @detail, "$host timeout on write"; } else { push @detail, "$host interrupted syscall on write: $!"; } } if (! $rc) { push @failures, $host; push @detail, "$host: write failed: $!"; close (S); next; } } if (defined($EXPECT)) { # read and match my $rc= undef; my $alldata= ""; eval { local $SIG{"ALRM"} = sub { die "alarm\n" }; alarm $TIMEOUT; $rc= recv S, $rxdata, 1024, 0; $alldata= $alldata . $rxdata; while ( !checkbuf($alldata, $EXPECT)) { $rc= recv S, $rxdata, 1024, 0; $alldata= $alldata . $rxdata; } alarm 0; }; if ($@) { push @failures, $host; if ($@ eq "alarm\n") { push @detail, "$host timeout on read"; } else { push @detail, "$host interrupted syscall on read: $!"; } } if ($rc) { push @failures, $host; push @detail, "$host: recv failed : $!"; close (S); next; } if (! checkbuf($alldata, $EXPECT)) { push @failures, $host; push @detail, "$host: did not recv expected response"; close (S); next; } } if (defined($QUITSTR)) { my $rc= undef; $QUITSTR=~ s/\\n/\n/g; $QUITSTR=~ s/\\r/\r/g; eval { local $SIG{"ALRM"} = sub { die "alarm\n" }; alarm $TIMEOUT; $rc= send S, $QUITSTR, 0; alarm 0; }; if ($@) { push @failures, $host; if ($@ eq "alarm\n") { push @detail, "$host timeout writing quitstr"; } else { push @detail, "$host interrupted syscall writing quitstr: $!"; } } if (! $rc) { push @failures, $host; push @detail, "$host: quit write failed: $!"; close (S); next; } } if (!defined close (S)) { push @failures, $host; push @detail, "$host: could not close socket: $!"; next; } } if (@failures == 0) { exit 0; } print "@failures\n"; print "\n", join ("\n", @detail), "\n"; exit 1; mon-contrib-1.0+dfsg/monitors/tcp/tcpch/tcpch.monitor.README000077500000000000000000000025451160532374600237470ustar00rootroot00000000000000Subject: tcpch.monitor - tcp ports with rudimentary chat To: mon@linux.kernel.org Date: Sat, 22 Sep 2001 01:34:18 -0400 (EDT) From: Ed Ravin Attached is tcpch.monitor, which is like the regular tcp.monitor included with mon except that it has some rudimentary "chat script" abilities. The code is rather rough since this is the first cut, but it seems to work so I thought I would pass it around. This monitor can be used to test arbitrary TCP services, though it daemons that communicate in ASCII. You can supply a "send string", data that gets sent as soon as the socket is open, a regexp to parse for the response from the server, and a "quit string" that gets sent before closing the socket (so to avoid error messages from some daemons that are fussy). # Options are # -p # -t (default 15) # -s # -e # -q # -d # without /-s/-e/-q/, just checks that the socket can be opened # and closed. # smtp: tcpch.monitor -p 25 -e '^220\b' -q 'QUIT\r\n' # web: tcpch.monitor -p 80 -s 'GET / HTTP/1.0\r\n' -e '^HTTP.*200 OK' Known bugs: -t timeout actually specifies all timeouts, not just connect. mon-contrib-1.0+dfsg/monitors/tftp/000077500000000000000000000000001160532374600173565ustar00rootroot00000000000000mon-contrib-1.0+dfsg/monitors/tftp/tftp.monitor000077500000000000000000000060761160532374600217600ustar00rootroot00000000000000#!/usr/bin/perl -w # # This TFTP test script will attempt to fetch a file from a tftp server, # and will verify it receives a non-empty file. # # Requires Net::TFTP # # Arguments: '-f filename hostname [...]' # # Author: David Nolan, Carnegie Mellon University, Computing Services # Contact: net-dev@andrew.cmu.edu # # Copyright (c) 2002 Carnegie Mellon University. All rights reserved. # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions are met: # # 1. Redistributions of source code must retain the above copyright notice, # this list of conditions and the following disclaimer. # # 2. Redistributions in binary form must reproduce the above copyright notice, # this list of conditions and the following disclaimer in the # documentation and/or other materials provided with the distribution. # # 3. The name "Carnegie Mellon University" must not be used to endorse or # promote products derived from this software without prior written # permission. For permission or any legal details, please contact: # Office of Technology Transfer # Carnegie Mellon University # 5000 Forbes Avenue # Pittsburgh, PA 15213-3890 # (412) 268-4387, fax: (412) 268-7395 # tech-transfer@andrew.cmu.edu # # 4. Redistributions of any form whatsoever must retain the following # acknowledgment: "This product includes software developed by Computing # Services at Carnegie Mellon University (http://www.cmu.edu/computing/)." # # CARNEGIE MELLON UNIVERSITY DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS # SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, # IN NO EVENT SHALL CARNEGIE MELLON UNIVERSITY BE LIABLE FOR ANY SPECIAL, # INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM # LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE # OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR # PERFORMANCE OF THIS SOFTWARE. use Net::TFTP; use Getopt::Std; getopt('f'); if (!defined $opt_f) { print "\nNo file to fetch, aborting.\n"; exit 0; } foreach $host (@ARGV) { eval { if (-f "/tmp/tftp.$$") { unlink "/tmp/tftp.$$"; } my $tftp = Net::TFTP->new($host, BlockSize => 1024); $tftp->ascii; $tftp->get($opt_f, "/tmp/tftp.$$"); my $err = $tftp->error; if ($err) { push @failures, $host; push @longerr, "$host: TFTP error $err"; } else { my ($dev,$ino,$mode,$nlink,$uid,$gid,$rdev,$size,$atime,$mtime,$ctime,$blksize,$blocks) = stat("/tmp/tftp.$$"); if (!$size) { push @failures, $host; push @longerr, "$host: Zero length file received"; } } }; if ($EVAL_ERROR && ($EVAL_ERROR =~ /Timeout/ )) { push @failures, $host; push @longerr, "$host: Request timed out."; } elsif ($EVAL_ERROR) { push @longerr, "$host: $EVAL_ERROR"; push @failures, $host; } } if (-f "/tmp/tftp.$$") { unlink "/tmp/tftp.$$"; } if (!@failures) { exit 0; } print join(" ", @failures),"\n"; print join("\n", @longerr), "\n"; exit scalar @failures; mon-contrib-1.0+dfsg/monitors/tftp/tftp.monitor.README000066400000000000000000000004471160532374600227050ustar00rootroot00000000000000# This TFTP test script will attempt to fetch a file from a tftp server, # and will verify it receives a non-empty file. # # Requires Net::TFTP # # Arguments: '-f filename hostname [...]' # # Author: David Nolan, Carnegie Mellon University, Computing Services # Contact: net-dev@andrew.cmu.edu mon-contrib-1.0+dfsg/monitors/udp/000077500000000000000000000000001160532374600171715ustar00rootroot00000000000000mon-contrib-1.0+dfsg/monitors/udp/udp.monitor000077500000000000000000000063151160532374600214020ustar00rootroot00000000000000#!/usr/bin/perl -w # # try to connect to a particular # port on a bunch of hosts. For use with "mon". # # Arguments are "[-p port] [-t timeout] [-r local-port] host [host...]" # # David Nolan, vitroth@cmu.edu # based on tcp.monitor by Jim Trocki, trockij@transmeta.com # # $Id: udp.monitor,v 1.1 2005/02/19 17:43:21 vitroth Exp $ # # Copyright (C) 1998, Jim Trocki # # 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; either version 2 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA # use Getopt::Std; use Socket; use Sys::Hostname; my %opt; getopts ("p:r:t:", \%opt); my $PORT = $opt{"p"} || 23; my $TIMEOUT = $opt{"t"} || 10; my $RECVPORT = $opt{"r"}; my @failures = (); my @detail = (); my $ALARM = 0; foreach my $host (@ARGV) { my $pro = getprotobyname ('udp'); if (!defined $pro) { die "could not getprotobyname\n"; } if (!defined socket (S, PF_INET, SOCK_DGRAM, $pro)) { die "could not create socket: $!\n"; } my $a = inet_aton ($host); if (!defined $a) { push @failures, $host; push @detail, "$host could not inet_aton"; close (S); next; } my $sin = sockaddr_in ($PORT, $a); if (!defined $sin) { push @failures, $host; push @detail, "$host could not sockaddr_in"; close (S); next; } if (defined $RECVPORT) { $iaddr = gethostbyname(hostname()); $paddr = sockaddr_in($RECVPORT, $iaddr); $res = bind(S, $paddr); if (!$res) { push @failures, $host; push @detail, "$host: Could not bind to local port $RECVPORT"; close (S); next; } } my ($r, $from); eval { local $SIG{"ALRM"} = sub { die "alarm\n" }; alarm $TIMEOUT; send (S, "", 0, $sin); $from = recv(S, $r, 1, 0); alarm 0; }; if ($@) { push @failures, $host; if ($@ eq "alarm\n") { push @detail, "$host timeout"; } else { push @detail, "$host interrupted syscall: $!"; } close (S); next; } if (!defined $r) { push @failures, $host; push @detail, "$host no udp response packet received: $!"; close (S); next; } my ($fromport, $fromaddr) = sockaddr_in($from); if ($fromport != $PORT || $fromaddr ne $a) { push @failures, $host; my $fromhost = gethostbyaddr($fromaddr, AF_INET); push @detail, "response received from $fromhost:$fromport, instead of $host:$PORT"; next; } if (!defined close (S)) { push @failures, $host; push @detail, "$host could not close socket: $!"; next; } } if (@failures == 0) { exit 0; } print join (" ", sort @failures), "\n"; print "\n", join ("\n", @detail), "\n"; exit 1;