myscripts/check-postfix.sh

135 lines
5.4 KiB
Bash
Executable File

#!/usr/bin/bash
#############################################################################################################
# check-postfix.sh #
#############################################################################################################
# #
# This script is just something I cooked up for work. I setup a server with posftix configured as an` #
# email/smtp relay so that some of our old equipment can still function without having to try and #
# configure our commercial Email Server to accept unauthed requests to send email. #
# #
# This requres a few packages to be installed: #
# - postfix (of course) #
# - telnet #
# - sendmail #
# #
# The issue is if the postfix service dies and fails to come back up after a restart via this script, #
# you will be unable to send any emails via a smtp client (as they will try to contact the service #
# on the server itself). So the only workaround I was able to find is to manually send the email via #
# telnet using a coproc. You could use a smtp library with python or perl, but I like to keep these #
# scripts using a single language wherever possible. #
# #
# Since telnet is just a basic tcp client we are able to interact with the smpt port on a mailserver #
# (port 25). So setting it up as coproc allows us to run a concurrent process and pipe commands into #
# the file-descriptor to send the commands to the mailserver. Which allows us to manually send an email #
# to an authoritative email server (provided they don't have your IP blocklisted or are filtering #
# traffic on port 25). #
# #
#############################################################################################################
# BEGIN: Variables
## Duration to wait to see if service has come back up
DURATION=10
## Wait duration to send next part of message
WAIT=1
## Test flag
TEST=0
## Email addresses
NOTIFY_EMAIL=recipient@domain.com
MAIL_FROM=username@domain.net
FROM_DOMAIN=` echo $FROM_EMAIL | cut -d @ -f 2 `
DAMAIN=` echo $NOTIFY_EMAIL | cut -d @ -f 2 `
# END: Variables
# BEGIN: Helper Functions
send_email () {
local MESSAGE="${1:?"send_email: No message was passed through"}"
sendmail $NOTIFY_EMAIL <<< "$MESSAGE"
}
: "
The only option is to manually telnet to the smtp port on the authoritative mailserver for the target domain. As otherwise unless a mail-host is configured as an email relay, you will be unable to send an email to a user outside of the mailservers domain (without authentication).
"
do_emergency_email () {
local MESSAGE="${1:-"The Postfix service has failed to come up on `hostname` (`hostname -i`) after a service restart. Please ssh into server to troubleshoot the issues."}"
## Getting a mailserver IP for manual message
MAILSERVER=`dig $DOMAIN mx | grep -Eo '[0-9]+\.[0-9]+\.[0-9]+\.[0-9]+' | head -n 1`
## Setting up coprocess to send commands to telnet session coproc TELNET { telnet $MAILSERVER 25; }
coproc TELNET { telnet $MAILSERVER 25; }
## Commands to send email manually
local -a commands=(
"ehlo $FROM_DOMAIN\n"
"mail from: <$MAIL_FROM>\n"
"rcpt to: <$NOTIFY_EMAIL>\n"
"data\n"
"Subject: Postfix Service Failure\nFrom: $MAIL_FROM\nTo: $NOTIFY_EMAIL\n"
"$MESSAGE\n\n.\n"
"quit\n"
)
## Iterate through commands and send them to coprocesses
### We need to wait before each command as the remote mailserver will not catch everything otherwise.
for i in ${!commands[@]}; do
COMMAND="${commands[$i]}"
echo -e "$COMMAND" >&${TELNET[1]}
sleep $WAIT
done
}
# END: Helper Functions
# BEGIN: Test Check
if [[ $TEST -eq 1 ]]; then
MESSAGE_1="
This is a test message to verify that postfix can send an email
"
send_email "$MESSAGE_1"
MESSAGE_2="This is a test email to make sure the postfix crash workaround email works"
do_emergency_email "$MESSAGE_2"
exit
fi
# END: Test Check
# BEGIN: Work
if [[ `systemctl is-active postfix` != 'active' ]]; then
systemctl restart postfix
sleep $DURATION
SERVICE_STATUS=` systemctl is-active postfix `
if [[ "$SERVICE_STATUS" == 'active' ]]; then
MESSAGE="
SUBJECT: Postfix Service Failure
FROM: root
TO: $NOTIFY_EMAIL
The postfix service on `hostname` (`hostname -i`) was found to be not running.
The service has been restarted, and after waiting $DURATION seconds it was found to be $SERVICE_STATUS.
"
send_email "$MESSAGE"
else
do_emergency_email
fi
fi
# END: Work