Skip to content

Instantly share code, notes, and snippets.

@furu-nob
Created August 12, 2016 04:34
Show Gist options
  • Save furu-nob/e9a9e8afd6c61fa9caaeaa8d97907e50 to your computer and use it in GitHub Desktop.
Save furu-nob/e9a9e8afd6c61fa9caaeaa8d97907e50 to your computer and use it in GitHub Desktop.
Nagios check_milter.pl
#!/usr/bin/env perl
##############################################################################
# Program to check to make sure milter is running and report back to nrpe
# for nagios. The defalt port here is for DKIM which is commonly found on
# port 8891 and default host is localhost
# Created: 2015-06-18
# Version: 1.0.1
# Author: Alex Schuilenburg
##############################################################################
use English qw( -no_match_vars );
use Getopt::Long;
use Pod::Usage;
use Time::HiRes;
use Net::Milter;
use strict;
use warnings;
my $timeout = 10;
my $warn = $timeout / 3;
my $crit = $timeout / 2;
my $milter_host = '127.0.0.1';
my $milter_port = 8891;
my $VERSION = '1.0.1';
Getopt::Long::Configure( 'bundling', 'gnu_compat', );
GetOptions( 'man' => sub { pod2usage(-verbose => 2) },
'host|H=s' => \$milter_host,
'port|p=s' => \$milter_port,
'timeout|t=i' => \$timeout,
'warning|w=s' => \$warn,
'critical|c=s' => \$crit,
'version|V' => sub { VersionMessage() },
'help|h' => sub { pod2usage(1) },
);
#Make sure milter_port exists and if not give back a nagios error
if (($milter_port !~ /^\d+$/) || ($milter_port < 1) || ($milter_port > 65535)) {
print "Invalid socket number $milter_port.\n";
exit 1;
}
if ($warn !~ /^(\d*\.\d+|\d+\.?\d*)$/) {
printf "Invalid warning parameter %s\n", $warn;
exit 1;
}
if ($crit !~ /^(\d*\.\d+|\d+\.?\d*)$/) {
printf "Invalid critical parameter %s\n", $crit;
exit 1;
}
#Timer operation. Times out after $timeout seconds.
my $start_time = Time::HiRes::time;
eval {
#Set the alarm and set the timeout
local $SIG{ALRM} = sub { die "alarm\n" };
alarm $timeout;
# Attempt to connect
my $milter = new Net::Milter;
if (not $milter->open($milter_host,$milter_port,'tcp')) {
exit 1;
}
my ($milter_version,$returned_actions_ref,$returned_protocol_ref) = $milter->protocol_negotiation(
SMFIP_NOBODY => 1,
SMFIP_NOEOH => 1,
SMFIP_NOCONNECT => 1,
SMFIF_ADDHDRS => 1,
SMFIF_CHGBODY => 0,
);
if (not defined $milter_version) {
print "Connot negotiate with milter\n";
exit 1;
}
if ($milter_version < 1) {
print "Expected milter version greater than 1\n";
exit 1;
}
my (@results) = $milter->send_helo('localhost');
if (($#results != 0) || (${$results[0]}{action} ne 'continue')) {
print "Expected 'continue' response to HELO\n";
exit 1;
}
$milter->send_quit();
alarm 0;
};
my $elapsed_time = Time::HiRes::time - $start_time;
#Test return value and exit if eval caught the alarm
if ($EVAL_ERROR) {
if ( $EVAL_ERROR eq "alarm\n" ) {
print "Operation timed out after $timeout seconds.\n";
exit 2;
}
else {
print "An unknown error has occured: $EVAL_ERROR \n";
exit 3;
}
}
# Check for critical
if ($elapsed_time > $crit) {
printf "CRITICAL: Response time is %.3f\n", $elapsed_time;
exit 1;
}
# Check for warning
if ($elapsed_time > $warn) {
printf "WARNING: Response time is %.3f\n", $elapsed_time;
exit 1;
}
#Give Nagios OK
printf "OK - %.3fs response time|time=%.6fs;%.6f;%.6f;;\n",
$elapsed_time, $elapsed_time, $warn, $crit;
exit 0;
#Version message information displayed in both --version and --help
sub main::VersionMessage {
print <<"EOF";
This is version $VERSION of check_milter.
Copyright (c) 2015 Alex Schuilenburg (alexs\@ecoscentric.com).
All rights reserved.
This module is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License.
See http://www.fsf.org/licensing/licenses/gpl.html
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.
EOF
exit 1;
}
__END__
=head1 NAME
check_milter - Checks the status of the Mail filter server
=head1 VERSION
This documentation refers to check_milter version 1.0.1
=head1 USAGE
check_milter.pl
=head1 REQUIRED ARGUMENTS
None
=head1 OPTIONS
--port (-p) Set the port number for the milter server
--host (-H) Set the host name of the milter server
--timeout (-t) Sets the timeout, defaults to 10 seconds.
--warning= (-w) Sets the warning period for the response time
--critical= (-c) Sets the critical period for the response time
--version (-V) Display current version and exit
--help (-h) Display help message and exit
--man Display man page and exit
=head1 DESCRIPTION
This is a Nagios plugin that checks the status of a milter server that has been
configured to listen on a tcp socket. It connects to a running milter server
and performs a HELO check for 'localhost' and expects a 'continue' result.
It will return the appropriate NAGIOS/NRPE response on success/failure.
=head1 DIAGNOSTICS
=head2 IO::Socket::INET: connect: Connection refused
The milter tcp port in not accepting incoming connections.
The defaults may not be the number and host of the server you wish to check.
Change variable $milter_port and/or $milter_host to fix this issue or add the
-p and/or -h parameters to specify the correct port and/or host respectively.
=head1 CONFIGURATION AND ENVIRONMENT
check_milter must be available on the system being checked.
=head1 DEPENDENCIES
check_milter depends on the following modules:
Getopt::Std Standard Perl 5.8 module
Time::HiRes Standard Perl 5.8 module
Net::Milter Available from CPAN
=head1 INCOMPATIBILITIES
None known yet.
=head1 BUGS AND LIMITATIONS
No known bugs. If you encounter any let me know.
([email protected])
Currently only tcp sockets are supported. This can easily be extended to
check milter servers on UNIX sockets - I just wrote what my systems use.
=head1 AUTHOR
Alex Schuilenburg ([email protected])
=head1 LICENCE AND COPYRIGHT
Copyright (c) 2015 Alex Schuilenburg ([email protected])
All rights reserved.
This module is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License.
See L<http://www.fsf.org/licensing/licenses/gpl.html>.
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.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment