783 lines
24 KiB
Perl
Executable File
783 lines
24 KiB
Perl
Executable File
#!/usr/bin/perl
|
|
use strict;
|
|
use POSIX qw(strftime);
|
|
my $VERSION = '0.7.3';
|
|
my $COPYRIGHT = 'Copyright (C) 2005-2011 Jonathan Buhacoff <jonathan@buhacoff.net>';
|
|
my $LICENSE = 'http://www.gnu.org/licenses/gpl.txt';
|
|
my %status = ( 'OK' => 0, 'WARNING' => 1, 'CRITICAL' => 2, 'UNKNOWN' => 3 );
|
|
|
|
# look for required modules
|
|
exit $status{UNKNOWN} unless load_modules(qw/Getopt::Long Net::SMTP/);
|
|
|
|
BEGIN {
|
|
if( grep { /^--hires$/ } @ARGV ) {
|
|
eval "use Time::HiRes qw(time);";
|
|
warn "Time::HiRes not installed\n" if $@;
|
|
}
|
|
}
|
|
|
|
Getopt::Long::Configure("bundling");
|
|
my $verbose = 0;
|
|
my $help = "";
|
|
my $help_usage = "";
|
|
my $show_version = "";
|
|
my $smtp_server = "";
|
|
my $default_smtp_port = "25";
|
|
my $default_smtp_ssl_port = "465";
|
|
my $default_smtp_tls_port = "587";
|
|
my $smtp_port = "";
|
|
my @mailto = ();
|
|
my $mailfrom = "";
|
|
my @header = ();
|
|
my $body = "";
|
|
my $stdin = "";
|
|
my $template = "";
|
|
my $expect_response = "250";
|
|
my $warntime = 15;
|
|
my $criticaltime = 30;
|
|
my $timeout = 60;
|
|
my $tls = 0;
|
|
my $ssl = 0;
|
|
my $auth_method = undef;
|
|
my $username = "";
|
|
my $password = "";
|
|
my $time_hires = "";
|
|
my $mx_lookup = 0;
|
|
my $ok;
|
|
$ok = Getopt::Long::GetOptions(
|
|
"V|version"=>\$show_version,
|
|
"v|verbose+"=>\$verbose,"h|help"=>\$help,"usage"=>\$help_usage,
|
|
"w|warning=i"=>\$warntime,"c|critical=i"=>\$criticaltime,"t|timeout=i"=>\$timeout,
|
|
# smtp settings
|
|
"H|hostname=s"=>\$smtp_server,"p|port=i"=>\$smtp_port,
|
|
"mailto=s"=>\@mailto, "mailfrom=s",\$mailfrom,
|
|
"header=s"=>\@header, "body=s"=>\$body, "stdin"=>\$stdin,
|
|
"template!"=>\$template,
|
|
# SSL/TLS/auth options
|
|
"tls!"=>\$tls, "ssl!"=>\$ssl, "auth=s"=>\$auth_method,
|
|
"U|username=s"=>\$username,"P|password=s"=>\$password,
|
|
# Server response
|
|
"E|expect-response=s"=>\$expect_response,
|
|
# Time
|
|
"hires"=>\$time_hires,
|
|
);
|
|
|
|
if( $show_version ) {
|
|
print "$VERSION\n";
|
|
if( $verbose ) {
|
|
print "Default warning threshold: $warntime seconds\n";
|
|
print "Default critical threshold: $criticaltime seconds\n";
|
|
print "Default timeout: $timeout seconds\n";
|
|
}
|
|
exit $status{UNKNOWN};
|
|
}
|
|
|
|
if( $help ) {
|
|
exec "perldoc", $0 or print "Try `perldoc $0`\n";
|
|
exit $status{UNKNOWN};
|
|
}
|
|
|
|
if( $smtp_server eq "" && scalar(@mailto) == 1 ) {
|
|
# no SMTP server specified but one mailto address given means we can look up the MX record
|
|
$mx_lookup = 1;
|
|
}
|
|
|
|
my @required_module = ();
|
|
push @required_module, 'Net::SMTP::SSL' if $ssl;
|
|
push @required_module, ('MIME::Base64','Authen::SASL') if $ssl && $username;
|
|
push @required_module, 'Net::SMTP::TLS' if $tls;
|
|
push @required_module, 'Net::SMTP_auth' if $auth_method and not $tls; # whereas if auth_method and tls we use TLS_auth, which is included in this script!
|
|
push @required_module, 'Text::Template' if $template;
|
|
push @required_module, 'Net::DNS' if $mx_lookup;
|
|
push @required_module, 'Email::Address' if $mx_lookup;
|
|
exit $status{UNKNOWN} unless load_modules(@required_module);
|
|
|
|
|
|
# split up @mailto if commas were used instead of multiple options
|
|
@mailto = split(/,/,join(',',@mailto));
|
|
|
|
if( $help_usage ||
|
|
(
|
|
($smtp_server eq "" && !$mx_lookup) || scalar(@mailto)==0 || $mailfrom eq ""
|
|
)
|
|
) {
|
|
print "Usage: $0 [-H host [-p port]] --mailto recipient\@your.net [--mailto recipient2\@your.net ...] --mailfrom sender\@your.net --body 'some text' [-w <seconds>] [-c <seconds>]\n";
|
|
exit $status{UNKNOWN};
|
|
}
|
|
|
|
# initialize
|
|
my $report = new PluginReport;
|
|
my $time_start = time;
|
|
my $actual_response = undef;
|
|
my @warning = ();
|
|
my @critical = ();
|
|
|
|
my $smtp_debug = 0;
|
|
$smtp_debug = 1 if $verbose >= 3;
|
|
|
|
# default date and message id headers
|
|
push @header, default_date_header() unless find_header("Date",@header);
|
|
push @header, default_messageid_header() unless find_header("Message-ID",@header);
|
|
|
|
# look up MX server if necessary
|
|
if( $mx_lookup ) {
|
|
my $addr = Email::Address->new( undef, $mailto[0] );
|
|
my $mx_domain = $addr->host;
|
|
print "MX lookup " . $mx_domain . "\n" if $verbose > 1;
|
|
my $res = Net::DNS::Resolver->new;
|
|
my @mx = Net::DNS::mx($res, $mx_domain);
|
|
if( @mx ) {
|
|
# use the first server
|
|
foreach my $rr (@mx) {
|
|
print "pref : " . $rr->preference . " exchange: " . $rr->exchange . "\n" if $verbose > 2;
|
|
}
|
|
$smtp_server = $mx[0]->exchange;
|
|
print "smtp server: $smtp_server\n" if $verbose;
|
|
}
|
|
else {
|
|
print "SMTP SEND CRITICAL - Cannot find MX records for $mx_domain\n";
|
|
exit $status{CRITICAL};
|
|
}
|
|
}
|
|
|
|
# connect to SMTP server
|
|
# create the smtp handle using Net::SMTP, Net::SMTP::SSL, Net::SMTP::TLS, or an authentication variant
|
|
my $smtp;
|
|
eval {
|
|
if( $tls and $auth_method ) {
|
|
$smtp_port = $default_smtp_tls_port unless $smtp_port;
|
|
$smtp = TLS_auth->new($smtp_server, Timeout=>$timeout, Port=>$smtp_port, User=>$username, Password=>$password, Auth_Method=>$auth_method);
|
|
if( $smtp ) {
|
|
my $message = oneline($smtp->message());
|
|
die "cannot connect with TLS/$auth_method: $message" if $smtp->code() =~ m/53\d/;
|
|
}
|
|
}
|
|
elsif( $tls ) {
|
|
$smtp_port = $default_smtp_tls_port unless $smtp_port;
|
|
$smtp = Net::SMTP::TLS->new($smtp_server, Timeout=>$timeout, Port=>$smtp_port, User=>$username, Password=>$password);
|
|
if( $smtp ) {
|
|
my $message = oneline($smtp->message());
|
|
die "cannot connect with TLS: $message" if $smtp->code() =~ m/53\d/;
|
|
}
|
|
}
|
|
elsif( $ssl ) {
|
|
$smtp_port = $default_smtp_ssl_port unless $smtp_port;
|
|
$smtp = Net::SMTP::SSL->new($smtp_server, Port => $smtp_port, Timeout=>$timeout,Debug=>$smtp_debug);
|
|
if( $smtp && $username ) {
|
|
$smtp->auth($username, $password);
|
|
my $message = oneline($smtp->message());
|
|
die "cannot connect with SSL/password: $message" if $smtp->code() =~ m/53\d/;
|
|
}
|
|
}
|
|
elsif( $auth_method ) {
|
|
$smtp_port = $default_smtp_port unless $smtp_port;
|
|
$smtp = Net::SMTP_auth->new($smtp_server, Port=>$smtp_port, Timeout=>$timeout,Debug=>$smtp_debug);
|
|
if( $smtp ) {
|
|
$smtp->auth($auth_method, $username, $password);
|
|
my $message = oneline($smtp->message());
|
|
die "cannot connect with SSL/$auth_method: $message" if $smtp->code() =~ m/53\d/;
|
|
}
|
|
}
|
|
else {
|
|
$smtp_port = $default_smtp_port unless $smtp_port;
|
|
$smtp = Net::SMTP->new($smtp_server, Port=>$smtp_port, Timeout=>$timeout,Debug=>$smtp_debug);
|
|
if( $smtp && $username ) {
|
|
$smtp->auth($username, $password);
|
|
my $message = oneline($smtp->message());
|
|
die "cannot connect with password: $message" if $smtp->code() =~ m/53\d/;
|
|
}
|
|
}
|
|
};
|
|
if( $@ ) {
|
|
$@ =~ s/\n/ /g; # the error message can be multiline but we want our output to be just one line
|
|
print "SMTP SEND CRITICAL - $@\n";
|
|
exit $status{CRITICAL};
|
|
}
|
|
unless( $smtp ) {
|
|
print "SMTP SEND CRITICAL - Could not connect to $smtp_server port $smtp_port\n";
|
|
exit $status{CRITICAL};
|
|
}
|
|
my $time_connected = time;
|
|
|
|
# add the monitored server's banner to the report
|
|
if( $tls ) {
|
|
$report->{banner} = "";
|
|
}
|
|
elsif( $ssl ) {
|
|
$report->{banner} = $smtp->banner || "";
|
|
chomp $report->{banner};
|
|
}
|
|
else {
|
|
$report->{banner} = $smtp->banner || "";
|
|
chomp $report->{banner};
|
|
}
|
|
|
|
|
|
# send email
|
|
if( $stdin ) {
|
|
$body = "";
|
|
while(<STDIN>) {
|
|
$body .= $_;
|
|
}
|
|
}
|
|
|
|
# if user wants to use template substitutions, this is the place to process body and headers
|
|
if( $template ) {
|
|
foreach my $item (@header,$body) {
|
|
my $t = Text::Template->new(TYPE=>'STRING',SOURCE=>$item,PACKAGE=>'SmtpMessageTemplate');
|
|
$item = $t->fill_in(PREPEND=>q{package SmtpMessageTemplate;});
|
|
# print "item: $item\n";
|
|
}
|
|
}
|
|
|
|
|
|
$smtp->mail($mailfrom);
|
|
foreach( @mailto ) {
|
|
# the two SMTP modules have different error reporting mechanisms:
|
|
if( $tls ) {
|
|
# Net::SMTP::TLS croaks when the recipient is rejected
|
|
eval {
|
|
$smtp->to($_);
|
|
};
|
|
if( $@ ) {
|
|
print "SMTP SEND CRITICAL - Could not send to $_\n";
|
|
print "Reason: $@\n" if $verbose;
|
|
exit $status{CRITICAL};
|
|
}
|
|
}
|
|
else {
|
|
# Net::SMTP returns false when the recipient is rejected
|
|
my $to_returned = $smtp->to($_);
|
|
if( !$to_returned ) {
|
|
print "SMTP SEND CRITICAL - Could not send to $_\n";
|
|
print "Reason: Recipient rejected or authentication failed\n" if $verbose;
|
|
exit $status{CRITICAL};
|
|
}
|
|
}
|
|
}
|
|
|
|
# Net::SMTP::TLS doesn't implement code() so we need to wrap calls in eval to get our error messages
|
|
|
|
# start data transfer (expect response 354)
|
|
$smtp->data();
|
|
|
|
# send data
|
|
$smtp->datasend("To: ".join(", ",@mailto)."\n");
|
|
$smtp->datasend("From: $mailfrom\n");
|
|
foreach( @header ) {
|
|
$smtp->datasend("$_\n");
|
|
}
|
|
$smtp->datasend("\n");
|
|
$smtp->datasend($body);
|
|
$smtp->datasend("\n");
|
|
|
|
eval {
|
|
# end data transfer (expect response 250)
|
|
$smtp->dataend();
|
|
};
|
|
if( $@ ) {
|
|
$actual_response = $tls ? get_tls_error($@) : $smtp->code();
|
|
}
|
|
else {
|
|
$actual_response = $tls ? "250" : $smtp->code(); # no error means we got 250
|
|
}
|
|
|
|
eval {
|
|
# disconnect from SMTP server (expect response 221)
|
|
$smtp->quit();
|
|
};
|
|
if( $@ ) {
|
|
push @warning, "Error while disconnecting from $smtp_server";
|
|
}
|
|
|
|
# calculate elapsed time and issue warnings
|
|
my $time_end = time;
|
|
my $elapsedtime = $time_end - $time_start;
|
|
$report->{seconds} = $elapsedtime;
|
|
|
|
push @warning, "connection time more than $warntime" if( $time_connected - $time_start > $warntime );
|
|
push @critical, "connection time more than $criticaltime" if( $time_connected - $time_start > $criticaltime );
|
|
push @critical, "response was $actual_response but expected $expect_response" if ( $actual_response ne $expect_response );
|
|
|
|
# print report and exit with known status
|
|
my $perf_data = "elapsed=".$report->{seconds}."s;$warntime;$criticaltime"; # TODO: need a component for safely generating valid perf data format. for notes on the format, see http://www.perfparse.de/tiki-view_faq.php?faqId=6 and http://nagiosplug.sourceforge.net/developer-guidelines.html#AEN185
|
|
my $short_report = $report->text(qw/seconds/) . " | $perf_data";
|
|
my $long_report = join("", map { "$_: $report->{$_}\n" } qw/banner/ );
|
|
if( scalar @critical ) {
|
|
my $crit_alerts = join(", ", @critical);
|
|
print "SMTP SEND CRITICAL - $crit_alerts; $short_report\n";
|
|
print $long_report if $verbose;
|
|
exit $status{CRITICAL};
|
|
}
|
|
if( scalar @warning ) {
|
|
my $warn_alerts = join(", ", @warning);
|
|
print "SMTP SEND WARNING - $warn_alerts; $short_report\n";
|
|
print $long_report if $verbose;
|
|
exit $status{WARNING};
|
|
}
|
|
print "SMTP SEND OK - $short_report\n";
|
|
print $long_report if $verbose;
|
|
exit $status{OK};
|
|
|
|
|
|
# utility to load required modules. exits if unable to load one or more of the modules.
|
|
sub load_modules {
|
|
my @missing_modules = ();
|
|
foreach( @_ ) {
|
|
eval "require $_";
|
|
push @missing_modules, $_ if $@;
|
|
}
|
|
if( @missing_modules ) {
|
|
print "Missing perl modules: @missing_modules\n";
|
|
return 0;
|
|
}
|
|
return 1;
|
|
}
|
|
|
|
# utility to extract error codes out of Net::SMTP::TLS croak messages
|
|
sub get_tls_error {
|
|
my ($errormsg) = @_;
|
|
$errormsg =~ m/: (\d+) (.+)/;
|
|
my $code = $1;
|
|
return $code;
|
|
}
|
|
|
|
# looks for a specific header in a list of headers; returns true if found
|
|
sub find_header {
|
|
my ($name, @list) = @_;
|
|
return scalar grep { m/^$name: /i } @list;
|
|
}
|
|
|
|
# RFC 2822 date header
|
|
sub default_date_header {
|
|
return strftime "Date: %a, %e %b %Y %H:%M:%S %z (%Z)", gmtime;
|
|
}
|
|
|
|
# RFC 2822 message id header
|
|
sub default_messageid_header {
|
|
my $random = randomstring(16,qw/0 1 2 3 4 5 6 7 8 9 a b c d e f g h i j k l m n o p q r s t u v w x y z/);
|
|
my $hostname = `hostname`;
|
|
chomp $hostname;
|
|
return "Message-ID: <".time.".".$random.".checksmtpsend@".$hostname.">";
|
|
}
|
|
|
|
# returns a random string of specified length using characters from specified set
|
|
sub randomstring {
|
|
my ($length,@set) = @_;
|
|
my $size = scalar @set;
|
|
my $string = "";
|
|
while($length--) {
|
|
$string .= $set[int(rand($size))];
|
|
}
|
|
return $string;
|
|
}
|
|
|
|
# replaces all newlines in the input string with spaces
|
|
sub oneline {
|
|
my ($input) = @_;
|
|
$input =~ s/[\r\n]+/ /g;
|
|
return $input;
|
|
}
|
|
|
|
# NAME
|
|
# PluginReport
|
|
# SYNOPSIS
|
|
# $report = new PluginReport;
|
|
# $report->{label1} = "value1";
|
|
# $report->{label2} = "value2";
|
|
# print $report->text(qw/label1 label2/);
|
|
package PluginReport;
|
|
|
|
sub new {
|
|
my ($proto,%p) = @_;
|
|
my $class = ref($proto) || $proto;
|
|
my $self = bless {}, $class;
|
|
$self->{$_} = $p{$_} foreach keys %p;
|
|
return $self;
|
|
}
|
|
|
|
sub text {
|
|
my ($self,@labels) = @_;
|
|
my @report = map { "$self->{$_} $_" } grep { defined $self->{$_} } @labels;
|
|
my $text = join(", ", @report);
|
|
return $text;
|
|
}
|
|
|
|
package SmtpMessageTemplate;
|
|
|
|
sub trim {
|
|
my ($text) = @_;
|
|
$text =~ s/^\s*//;
|
|
$text =~ s/\s*$//;
|
|
return $text;
|
|
}
|
|
|
|
# NAME
|
|
# TLS_auth
|
|
# SYNOPSYS
|
|
#
|
|
# Based on contribution by Brad Guillory
|
|
package TLS_auth;
|
|
#use Net::SMTP::TLS;
|
|
our @ISA = qw(Net::SMTP::TLS);
|
|
use Carp;
|
|
sub new {
|
|
my ($proto,$server,%p) = @_;
|
|
my $class = ref($proto) || $proto;
|
|
#my $self = bless {}, $class;
|
|
no strict 'refs';
|
|
no warnings 'once';
|
|
*Net::SMTP::TLS::login = *TLS_auth::login; # override parent's login with ours so when it's called in the constructor, our overriden version will be used
|
|
my $self = Net::SMTP::TLS->new($server,%p);
|
|
return $self;
|
|
}
|
|
|
|
|
|
sub login {
|
|
my ($self) = @_;
|
|
my $type = $self->{features}->{AUTH};
|
|
if(not $type){
|
|
die "Server did not return AUTH in capabilities\n"; # croak
|
|
}
|
|
# print "Feature: $type\nAuth Method: $self->{Auth_Method}\n";
|
|
if($type =~ /CRAM\-MD5/ and $self->{Auth_Method} =~ /CRAM\-MD5/i){
|
|
$self->auth_MD5();
|
|
}elsif($type =~ /LOGIN/ and $self->{Auth_Method} =~ /LOGIN/i){
|
|
$self->auth_LOGIN();
|
|
}elsif($type =~ /PLAIN/ and $self->{Auth_Method} =~ /PLAIN/i){
|
|
#print "Calling auth_PLAIN\n";
|
|
$self->auth_PLAIN();
|
|
}else{
|
|
die "Unsupported Authentication mechanism: $self->{Auth_Method}\n"; # croak
|
|
}
|
|
}
|
|
|
|
|
|
package main;
|
|
1;
|
|
|
|
__END__
|
|
|
|
=pod
|
|
|
|
=head1 NAME
|
|
|
|
check_smtp_send - connects to an SMTP server and sends a message
|
|
|
|
=head1 SYNOPSIS
|
|
|
|
check_smtp_send -vV
|
|
check_smtp_send -?
|
|
check_smtp_send --help
|
|
|
|
=head1 OPTIONS
|
|
|
|
=over
|
|
|
|
=item --warning <seconds>
|
|
|
|
Warn if it takes longer than <seconds> to connect to the SMTP server. Default is 15 seconds.
|
|
Also known as: -w <seconds>
|
|
|
|
=item --critical <seconds>
|
|
|
|
Return a critical status if it takes longer than <seconds> to connect to the SMTP server. Default is 30 seconds.
|
|
Also known as: -c <seconds>
|
|
|
|
=item --timeout <seconds>
|
|
|
|
Abort with critical status if it takes longer than <seconds> to connect to the SMTP server. Default is 60 seconds.
|
|
The difference between timeout and critical is that, with the default settings, if it takes 45 seconds to
|
|
connect to the server then the connection will succeed but the plugin will return CRITICAL because it took longer
|
|
than 30 seconds.
|
|
Also known as: -t <seconds>
|
|
|
|
=item --hostname <server>
|
|
|
|
Address or name of the SMTP server. Examples: mail.server.com, localhost, 192.168.1.100
|
|
|
|
If not provided, and if there is only one --mailto address, the script will automatically look up the MX record
|
|
for the --mailto address and use that as the hostname. You can use this to check that your MX records are correct.
|
|
When omitting the --hostname option, it doesn't really make sense to specify --port, --username, or --password
|
|
but you can still do so and they will have their normal effect. To look up the MX records you need to have the
|
|
module Net::DNS and Email::Address installed.
|
|
|
|
Also known as: -H <server>
|
|
|
|
=item --port <number>
|
|
|
|
Service port on the SMTP server. Default is 25 for regular SMTP, 465 for SSL, and 587 for TLS.
|
|
Also known as: -p <number>
|
|
|
|
=item --tls
|
|
|
|
=item --notls
|
|
|
|
Enable TLS/AUTH protocol. Requires Net::SMTP::TLS, availble on CPAN.
|
|
|
|
When using this option, the default port is 587.
|
|
You can specify a port from the command line using the --port option.
|
|
|
|
Use the notls option to turn off the tls option.
|
|
|
|
Also, you may need to fix your copy of Net::SMTP::TLS. Here is the diff against version 0.12:
|
|
|
|
254c254
|
|
< $me->_command(sprintf("AUTH PLAIN %S",
|
|
---
|
|
> $me->_command(sprintf("AUTH PLAIN %s",
|
|
|
|
|
|
=item --ssl
|
|
|
|
=item --nossl
|
|
|
|
Enable SSL protocol. Requires Net::SMTP::SSL and Authen::SASL, availble on CPAN.
|
|
|
|
When using this option, the default port is 465. You can override with the --port option.
|
|
|
|
Use the nossl option to turn off the ssl option.
|
|
|
|
=item --auth <method>
|
|
|
|
Enable authentication with Net::SMTP_auth (sold separately).
|
|
For example, try using --auth PLAIN or --auth CRAM-MD5.
|
|
|
|
=item --username <username>
|
|
|
|
=item --password <password>
|
|
|
|
Username and password to use when connecting to SMTP server.
|
|
Also known as: -U <username> -P <password>
|
|
|
|
=item --body <message>
|
|
|
|
Use this option to specify the body of the email message. If you need newlines in your message,
|
|
you might need to use the --stdin option instead.
|
|
|
|
=item --header <header>
|
|
|
|
Use this option to set an arbitrary header in the message. You can use it multiple times.
|
|
|
|
=item --stdin
|
|
|
|
Grab the body of the email message from stdin.
|
|
|
|
=item --mailto recipient@your.net
|
|
|
|
You can send a message to multiple recipients by repeating this option or by separating
|
|
the email addresses with commas (no whitespace allowed):
|
|
|
|
$ check_smtp_send -H mail.server.net --mailto recipient@your.net,recipient2@your.net --mailfrom sender@your.net
|
|
|
|
SMTP SEND OK - 1 seconds
|
|
|
|
=item --mailfrom sender@your.net
|
|
|
|
Use this option to set the "from" address in the email.
|
|
|
|
=item --template
|
|
|
|
=item --notemplate
|
|
|
|
Enable (or disable) processing of message body and headers. Requires Text::Template.
|
|
|
|
Use this option to apply special processing to your message body and headers that allows you to use the
|
|
results of arbitrary computations in the text. For example, you can use this feature to send a message
|
|
containing the hostname of the machine that sent the message without customizing the plugin configuration
|
|
on each machine.
|
|
|
|
When you enable the --template option, the message body and headers are parsed by
|
|
Text::Template. Even a message body provided using the --stdin option will be parsed.
|
|
See the Text::Template manual for more information, but in general any expression
|
|
written in Perl will work.
|
|
|
|
There is one convenience function provided to you, trim, which will remove leading and trailing whitespace
|
|
from its parameter. Here's an example:
|
|
|
|
check_smtp_send -H mail.server.net --mailto recipient@your.net --mailfrom sender@your.net
|
|
--template --body 'hello, this message is from {use Sys::Hostname; hostname}'
|
|
--header 'Subject: test message from {trim(`whoami`)}'
|
|
|
|
|
|
=item --expect-response <code>
|
|
|
|
Use this option to specify which SMTP response code should be expected from the server
|
|
after the SMTP dialog is complete. The default is 250 (message accepted).
|
|
|
|
Also known as: -E <code>
|
|
|
|
=item --hires
|
|
|
|
Use the Time::HiRes module to measure time, if available.
|
|
|
|
=item --verbose
|
|
|
|
Display additional information. Useful for troubleshooting.
|
|
|
|
One --verbose will show extra information for OK, WARNING, and CRITICAL status.
|
|
|
|
Use one --verbose together with --version to see the default warning and critical timeout values.
|
|
|
|
Three --verbose (or -vvv) will show debug information, unless you're using --tls because Net::SMTP::TLS
|
|
does not have a Debug feature.
|
|
|
|
Also known as: -v
|
|
|
|
=item --version
|
|
|
|
Display plugin version and exit.
|
|
Also known as: -V
|
|
|
|
=item --help
|
|
|
|
Display this documentation and exit. Does not work in the ePN version.
|
|
Also known as: -h
|
|
|
|
=item --usage
|
|
|
|
Display a short usage instruction and exit.
|
|
|
|
=back
|
|
|
|
=head1 EXAMPLES
|
|
|
|
=head2 Send a message with custom headers
|
|
|
|
$ check_smtp_send -H mail.server.net --mailto recipient@your.net --mailfrom sender@your.net
|
|
--body 'Homeruns 5' --header 'Subject: Hello, world!' --header 'X-Your-Header: Yes'
|
|
|
|
SMTP SEND OK - 1 seconds
|
|
|
|
=head1 EXIT CODES
|
|
|
|
Complies with the Nagios plug-in specification:
|
|
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 the plugin was unable to check the status of the given hosts/service
|
|
|
|
=head1 NAGIOS PLUGIN NOTES
|
|
|
|
Nagios plugin reference: http://nagiosplug.sourceforge.net/developer-guidelines.html
|
|
|
|
This plugin does NOT use Nagios DEFAULT_SOCKET_TIMEOUT (provided by utils.pm as $TIMEOUT) because
|
|
the path to utils.pm must be specified completely in this program and forces users to edit the source
|
|
code if their install location is different (if they realize this is the problem). You can view
|
|
the default timeout for this module by using the --verbose and --version options together. The
|
|
short form is -vV.
|
|
|
|
Other than that, it attempts to follow published guidelines for Nagios plugins.
|
|
|
|
=head1 CHANGES
|
|
|
|
Wed Oct 29 14:05:00 PST 2005
|
|
+ version 0.1
|
|
|
|
Wed Nov 9 15:01:48 PST 2005
|
|
+ now using an inline PluginReport package to generate the report
|
|
+ added stdin option
|
|
+ copyright notice and GNU GPL
|
|
+ version 0.2
|
|
|
|
Thu Apr 20 16:00:00 PST 2006 (by Geoff Crompton <geoff.crompton@strategicdata.com.au>)
|
|
+ added bailing if the $smtp->to() call fails
|
|
+ added support for mailto recipients separated by commas
|
|
+ version 0.2.1
|
|
|
|
Tue Apr 24 21:17:53 PDT 2007
|
|
+ moved POD text to separate file in order to accomodate the new embedded-perl Nagios feature
|
|
+ version 0.2.3
|
|
|
|
Fri Apr 27 20:26:42 PDT 2007
|
|
+ documentation now mentions every command-line option accepted by the plugin, including abbreviations
|
|
+ version 0.3
|
|
|
|
Sun Oct 21 10:34:14 PDT 2007
|
|
+ added support for TLS and authentication via the Net::SMTP::TLS module. see --tls option.
|
|
+ version 0.4
|
|
|
|
Sun Oct 21 13:54:26 PDT 2007
|
|
+ added support for SSL via the Net::SMTP::SSL module. see --ssl option.
|
|
+ port is no longer a required option. defaults to 25 for regular smtp, 465 for ssl, and 587 for tls.
|
|
+ added port info to the "could not connect" error message
|
|
+ version 0.4.1
|
|
|
|
Tue Dec 4 07:42:32 PST 2007
|
|
+ added --usage option because the official nagios plugins have both --help and --usage
|
|
+ added --timeout option to match the official nagios plugins
|
|
+ fixed some minor pod formatting issues for perldoc
|
|
+ version 0.4.2
|
|
|
|
Mon Feb 11 19:09:37 PST 2008
|
|
+ fixed a bug for embedded perl version, variable "%status" will not stay shared in load_modules
|
|
+ version 0.4.3
|
|
|
|
Mon May 26 09:12:14 PDT 2008
|
|
+ fixed warning and critical messages to use "more than" or "less than" instead of the angle brackets, to make them more web friendly
|
|
+ version 0.4.4
|
|
|
|
Wed Jul 2 07:12:35 PDT 2008
|
|
+ added --expect-response option submitted by Christian Kauhaus <kc@gocept.com>
|
|
+ added support for authentication via Net::SMTP_auth. see --auth option.
|
|
+ version 0.4.5
|
|
|
|
Sun Oct 5 15:18:23 PDT 2008
|
|
+ added error handling for smtp server disconnects ungracefully during QUIT (gmail.com does)
|
|
+ version 0.4.6
|
|
|
|
Thu Oct 1 12:09:35 PDT 2009
|
|
+ added --template option to allow arbitrary substitutions for body and headers, and provided one convenience function for trimming strings
|
|
+ added performance data for use with PNP4Nagios!
|
|
+ version 0.5.0
|
|
|
|
Thu Oct 8 11:17:04 PDT 2009
|
|
+ added more detailed error messages when using --verbose
|
|
+ version 0.5.1
|
|
|
|
Tue Feb 9 12:14:49 PST 2010
|
|
+ added support for combining --auth with --tls using a subclass of Net::SMTP::TLS submitted by Brad Guillory; please note that to use the "PLAIN" authentication type you need to patch your Net::SMTP:TLS because it has a bug in sub auth_PLAIN (sprintf %S instead of %s)
|
|
+ version 0.5.2
|
|
|
|
Mon Jan 3 10:39:42 PST 2011
|
|
+ added default Date and Message-ID headers; Date header uses POSIX strftime and Message-ID header uses hostname command to get localhost name
|
|
+ version 0.7.0
|
|
|
|
Fri May 6 08:35:09 AST 2011
|
|
+ added --hires option to enable use of Time::Hires if available
|
|
+ version 0.7.1
|
|
|
|
Wed Jul 6 19:18:26 AST 2011
|
|
+ the --hostname is now optional; if not provided the plugin will lookup the MX record for the --mailto address (requires Net::DNS)
|
|
+ version 0.7.2
|
|
|
|
Tue Dec 13 09:24:04 PST 2011
|
|
+ separated authentication errors from connection errors
|
|
+ version 0.7.3
|
|
|
|
=head1 AUTHOR
|
|
|
|
Jonathan Buhacoff <jonathan@buhacoff.net>
|
|
|
|
=head1 COPYRIGHT AND LICENSE
|
|
|
|
Copyright (C) 2005-2011 Jonathan Buhacoff
|
|
|
|
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 3 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, see <http://www.gnu.org/licenses/>.
|
|
|
|
http://www.gnu.org/licenses/gpl.txt
|
|
|
|
=cut
|
|
|