Zabbix SMTP server availability monitoring
Check
on some mail servers (Exim) returns "554 SMTP synchronization error"
The reason is that Exim does not accept input sent before it is ready, i.e. at a moment when it should not have been sent. Therefore, checking the SMTP server via NETCAT does not work.
Zabbix Template: zabbix_template_smtp_servers.xml.7z
Comment: 2016-06-03 - the nodata() function in the trigger is completely useless, because its value for a network data item in "Not supported" status = UNKNOWN, and the trigger does not fire.
Zabbix agent configuration:
Script 1 (deprecated): /etc/zabbix/zabbix-check-smtp.sh
#!/bin/sh
# default - check error
result=0
if [ $# -lt 1 ]
then {}
else {
# Extract server name from email address
domain=$1
# Determine MX domain
mxserver=$( dig $domain MX |\
egrep 'MX[[:space:]]+[0-9]+[[:space:]]+[^[:space:]]+\.' |\
sort -n -k5,5 |\
head -1 | awk '{print $6}' | sed 's/\.$//' )
#
# echo 'mxserver='$mxserver
# MX found
if [ "$mxserver" != "" ]
then {
# Attempt SMTP dialogue
smtpconnect=`/usr/bin/php -f /etc/zabbix/check-smtp-server.php $mxserver 25`
# form result
if [ $smtpconnect = "1" ]
then
{
result=1
}
fi
}
fi # MX server for domain found
}
fi # number of parameters
echo $result
Script 2 : /etc/zabbix/zabbix-check-smtp.sh Advantages: checks all existing MX records, saves available MX record to /var/cache/zabbix Don't forget to create and set permissions on /var/cache/zabbix!
#!/bin/sh
#
CACHE=/var/cache/zabbix
checksmtp()
{
echo `/usr/bin/php -f /etc/zabbix/check-smtp-server.php $1 25`
}
# Domain name set
domain=$1
ismx=$CACHE/ismx-$domain.list
goodmx=$CACHE/goodmx-$domain
# if there is NO file with good MX name list
if [ ! -f $goodmx ]
then
# Get all mx-record from DNS server to file
dig $domain MX |\
egrep 'MX[[:space:]]+[0-9]+[[:space:]]+[^[:space:]]+\.' |\
sort -n -k5,5 | awk '{print $6}' | sed 's/\.$//' > $ismx
# check all MX one by one
index=0
while read line; do
mxserver=$line
smtpconnect=$(checksmtp $mxserver)
if [ $smtpconnect = "1" ]
then
rm $ismx
echo $mxserver >> $goodmx
# EXIT
echo 1
exit
fi
done < $ismx
# If we are here that means THERE ARE NO answer from ALL MX-records
rm $ismx
echo 0
exit
# WE HAVE STORED FILE WITH GOOD MX RECORD
#-----------------------------------------
else
mxserver=$(head -1 $goodmx)
if [ "$mxserver" != "" ]
then
smtpconnect=$(checksmtp $mxserver)
if [ $smtpconnect = "1" ]
then
echo 1
exit
else
rm $goodmx
echo 0
exit
fi
fi
fi
PHP script /etc/zabbix/check-smtp-server.php:
Important: The timeout parameter in fsocketopen and stream_set_timeout functions must correlate with the TimeOut parameter value in the zabbix-agent configuration.
<?php
error_reporting(0);
function server_parse($socket, $response, $line = __LINE__) {
$server_response ='';
while (substr($server_response, 3, 1) != ' ') {
//
// TimeOut !!!
stream_set_timeout($socket, 20);
if (!($server_response = fgets($socket, 256))) {
return false;
}
}
if (!(substr($server_response, 0, 3) == $response)) {
return false;
}
return true;
}
//
// TimeOut = 3 seconds
// Otherwise we get a long wait, and the data item does not receive values by timeout.
function checkSMTPServer( $smtp_host, $smtp_port ) {
if ( !$socket = fsockopen( $smtp_host, $smtp_port, $errno, $errstr, 3) ) {
return 0;
}
if (!server_parse($socket, "220", __LINE__)) {
return 0;
}
fputs($socket, "QUIT\r\n");
fclose($socket);
return 1;
}
if ($argc != 3) {
echo 'Command line: /usr/bin/php check-smtp-server.php mx.mydomain.com 25'."\n";
}
else {
echo checkSMTPServer( $argv[1], $argv[2])."\n";
}