Showing posts with label nagios. Show all posts
Showing posts with label nagios. Show all posts

Monday, March 04, 2013

Use perl to check spamhaus status in Nagios

We had an issue where something on our internal network was tripping a SMTP spam filter at spamhaus.org.  We thought we fixed it once only to be bitten again a few months later and payslips from our payrol system were bouncing (bad).  As well as actually investigating the root cause, we created a nagios check to check spamhaus programatically.  Creating a custom nagios check is well documented on the nagios website.

#!/usr/bin/perl
#
# Quick perl script to check spamhaus to see if we're blocked again, see https://rt.wilderness.org.au:444/rt/Ticket/Display.html?id=73259
#
# This script returns values consistent with the nagios return code specification at http://nagiosplug.sourceforge.net/developer-guidelines.html#AEN76
# 0     OK          The plugin was able to check the service and it appeared to be functioning properly
# 1     Warning     The plugin was able to check the service, but it appeared to be above some "warning" threshold or did not appear to be working properly
# 2     Critical    The plugin detected that either the service was not running or it was above some "critical" threshold
# 3     Unknown     Invalid command line arguments were supplied to the plugin or low-level failures internal to the plugin 
#                       (such as unable to fork, or open a tcp socket) that prevent it from performing the specified operation. Higher-level errors 
#                       (such as name resolution errors, socket timeouts, etc) are outside of the control of plugins and should generally NOT be reported as UNKNOWN states.

use strict;
my $our_external_ip = "xxx.xxx.xxx.xxx"; 
my $exit_value=3;

# run the wget command and save it's output to the $results variable.
my $results=`/usr/bin/wget --random-wait -U mozilla -O /tmp/spamcheck.dat -o /tmp/spamcheck.log http://www.spamhaus.org/query/ip/$our_external_ip && grep $our_external_ip /tmp/spamcheck.dat`; 
chomp($results); 
#print $results."\n";

# check to see if we score RED ie; we're on a blocklist
if ($results =~ m/red/) {
    print "ALERT: Block found.  Check http://www.spamhaus.org/query/ip/$our_external_ip\n";
    $exit_value=2;
} 

# if we got this far, we saw no RED.  Check to see we at least get one GREEN.
elsif ($results =~ m/green/) {
    print "OK; We got a green and no red.\n";
    $exit_value=0; 
} 

# ALERT: We got no red AND no green; therefore there bust be some issue somewhere!
else {
    print "ALERT: No valid return codes detected; page-load/dns/internet/scripting issue?\n";
    $exit_value=3; 
}

#print "\nPerl hopes it's returning a \$exit_value of $exit_value\n\n";
exit $exit_value;

note that /tmp/spamcheck.* will need to be globally writable.

That then results in a nice web gui telling us all isn't well (again).  Happy with my work i told my boss who said "i don't like it, i want it to say OK", to which i replied, "i can do that ;)", and now you can too.  Happy automation :)