2023-11-17 19:37:45 +00:00
#!/usr/bin/bash
2023-11-19 01:13:31 +00:00
#############################################################################################################
# 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). #
# #
#############################################################################################################
2023-11-17 19:37:45 +00:00
# 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
2023-11-19 01:01:45 +00:00
FROM_DOMAIN = ` echo $FROM_EMAIL | cut -d @ -f 2 `
2023-11-17 19:37:45 +00:00
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 "
}
: "
2023-11-19 00:57:25 +00:00
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) .
2023-11-17 19:37:45 +00:00
"
do_emergency_email ( ) {
2023-11-19 00:59:58 +00:00
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." } "
2023-11-17 19:37:45 +00:00
## Getting a mailserver IP for manual message
MAILSERVER = ` dig $DOMAIN mx | grep -Eo '[0-9]+\.[0-9]+\.[0-9]+\.[0-9]+' | head -n 1`
2023-11-19 00:59:58 +00:00
## Setting up coprocess to send commands to telnet session coproc TELNET { telnet $MAILSERVER 25; }
2023-12-06 17:06:51 +00:00
coproc TELNET { telnet $MAILSERVER 25; }
2023-11-17 19:37:45 +00:00
## Commands to send email manually
local -a commands = (
2023-11-19 01:01:45 +00:00
" ehlo $FROM_DOMAIN \n "
2023-11-17 19:37:45 +00:00
" 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