File: //usr/local/bin/emailnotify
#!/bin/bash
export PATH="/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin:/root/bin"
######################################################
# tools/emailnotify.sh
# https://community.centminmod.com/threads/18184/
# utilise tools/email.sh setup primary & secondary
# email addresses populated by user at initial install
# time to send centminmod related email notifications
# https://community.centminmod.com/threads/6117/
######################################################
# variables
#############
DT=$(date +"%d%m%y-%H%M%S")
CENTMINLOGDIR='/root/centminlogs'
SCRIPT_DIR=$(readlink -f $(dirname ${BASH_SOURCE[0]}))
# Amazon SES smtp based email sending settings
# add these variables to persistent config file
# /etc/centminmod/custom_config.inc
# for them to persistent. Using below variables will
# be overridden on centminmod updates so persistent
# config file method is highly recommended
# Amazon SES emails are sent via native openssl s_client
# https://www.openssl.org/docs/man1.1.1/man1/s_client.html
EMAILNOTIFY_SES='n'
EMAILNOTIFY_SES_FROM_EMAIL='your_ses_verified_from_email_address'
EMAILNOTIFY_SES_TO_EMAIL='your_desired_email_to_receive_server_emails'
# CC and BCC options are optional. If not need, set and leave
# empty without a value
EMAILNOTIFY_SES_CC_EMAIL='your_desired_cc_email_to_receive_server_emails'
EMAILNOTIFY_SES_BCC_EMAIL='your_desired_bcc_email_to_receive_server_emails'
EMAILNOTIFY_SES_SMTP_USERNAME='your_ses_smtp_username'
EMAILNOTIFY_SES_SMTP_PASSWORD='your_ses_smtp_password'
EMAILNOTIFY_SES_SMTP_SERVER='your_ses_smtp_server'
EMAILNOTIFY_SES_SMTP_PORT='587'
# IPv4/IPv6
FORCE_IPVFOUR='y'
CURL_TIMEOUTS=' --max-time 5 --connect-timeout 5'
#####################################################
# local geoip server version used
VPS_GEOIPCHECK_V3='n'
VPS_GEOIPCHECK_V4='y'
######################################################
# Setup Colours
black='\E[30;40m'
red='\E[31;40m'
green='\E[32;40m'
yellow='\E[33;40m'
blue='\E[34;40m'
magenta='\E[35;40m'
cyan='\E[36;40m'
white='\E[37;40m'
boldblack='\E[1;30;40m'
boldred='\E[1;31;40m'
boldgreen='\E[1;32;40m'
boldyellow='\E[1;33;40m'
boldblue='\E[1;34;40m'
boldmagenta='\E[1;35;40m'
boldcyan='\E[1;36;40m'
boldwhite='\E[1;37;40m'
Reset="tput sgr0" # Reset text attributes to normal
#+ without clearing screen.
cecho () # Coloured-echo.
# Argument $1 = message
# Argument $2 = color
{
message=$1
color=$2
echo -e "$color$message" ; $Reset
return
}
######################################################
# functions
#############
# set locale temporarily to english
# due to some non-english locale issues
export LC_ALL=en_US.UTF-8
export LANG=en_US.UTF-8
export LANGUAGE=en_US.UTF-8
export LC_CTYPE=en_US.UTF-8
# disable systemd pager so it doesn't pipe systemctl output to less
export SYSTEMD_PAGER=''
ARCH_CHECK="$(uname -m)"
shopt -s expand_aliases
for g in "" e f; do
alias ${g}grep="LC_ALL=C ${g}grep" # speed-up grep, egrep, fgrep
done
if [ -f "/etc/centminmod/custom_config.inc" ]; then
# default is at /etc/centminmod/custom_config.inc
dos2unix -q "/etc/centminmod/custom_config.inc"
. "/etc/centminmod/custom_config.inc"
fi
symlink_setup_emailnotify() {
if [[ -f "${SCRIPT_DIR}/emailnotify.sh" && ! -h /usr/local/bin/emailnotify ]]; then
ln -s "${SCRIPT_DIR}/emailnotify.sh" /usr/local/bin/emailnotify >/dev/null 2>&1
fi
}
send_ses_credential_encode() {
SES_SMTP_USER=$(echo -n "$EMAILNOTIFY_SES_SMTP_USERNAME" | openssl enc -base64)
SES_SMTP_PASS=$(echo -n "$EMAILNOTIFY_SES_SMTP_PASSWORD" | openssl enc -base64)
}
send_ses_mail() {
# send email using native openssl client
bodyget=$1
subject=$2
toemail=$3
send_ses_credential_encode
if [ "$toemail" ]; then
EMAILNOTIFY_SES_TO_EMAIL="$toemail"
else
EMAILNOTIFY_SES_TO_EMAIL="$EMAILNOTIFY_SES_TO_EMAIL"
fi
if [ -f "$bodyget" ]; then
body=$(cat "$bodyget")
else
body="$bodyget"
fi
email_date=$(date)
SES_FROM_DOMAIN=$(echo "$EMAILNOTIFY_SES_FROM_EMAIL" | awk -F '@' '{print $2}')
if [ "$EMAILNOTIFY_SES_CC_EMAIL" ]; then
ses_cc="\nCc: $EMAILNOTIFY_SES_CC_EMAIL"
else
ses_cc=
fi
if [ "$EMAILNOTIFY_SES_BCC_EMAIL" ]; then
ses_bcc="\nBcc: $EMAILNOTIFY_SES_BCC_EMAIL"
else
ses_bcc=
fi
cat > /tmp/email_body_template.txt <<EOF
EHLO $SES_FROM_DOMAIN
AUTH LOGIN
$SES_SMTP_USER
$SES_SMTP_PASS
MAIL FROM: ${EMAILNOTIFY_SES_FROM_EMAIL}
RCPT TO: ${EMAILNOTIFY_SES_TO_EMAIL}
DATA
From: $EMAILNOTIFY_SES_FROM_EMAIL <${EMAILNOTIFY_SES_FROM_EMAIL}>
To: ${EMAILNOTIFY_SES_TO_EMAIL}${ses_cc}${ses_bcc}
Subject: $subject $(hostname) $email_date
$body
.
QUIT
EOF
if [ -f /usr/bin/systemctl ]; then
# centos 7 and higher openssl supported option
brief_opt=' -brief'
else
brief_opt=
fi
if [[ "$EMAILNOTIFY_SES_SMTP_PORT" = '587' ]]; then
echo "----------------------------------------------------"
echo "Send email via SES using openssl client"
echo "Success email send will end with line:"
echo "451 4.4.2 Timeout waiting for data from client"
echo "and return to command prompt after 10 seconds"
echo "----------------------------------------------------"
echo
openssl s_client -crlf -quiet${brief_opt} -starttls smtp -connect ${EMAILNOTIFY_SES_SMTP_SERVER}:${EMAILNOTIFY_SES_SMTP_PORT} < /tmp/email_body_template.txt
# rm -f /tmp/email_body_template.txt
elif [[ "$EMAILNOTIFY_SES_SMTP_PORT" = '465' ]]; then
echo "----------------------------------------------------"
echo "Send email via SES using openssl client"
echo "Success email send will end with line:"
echo "451 4.4.2 Timeout waiting for data from client"
echo "and return to command prompt after 10 seconds"
echo "----------------------------------------------------"
echo
openssl s_client -crlf -quiet${brief_opt} -connect ${EMAILNOTIFY_SES_SMTP_SERVER}:${EMAILNOTIFY_SES_SMTP_PORT} < /tmp/email_body_template.txt
# rm -f /tmp/email_body_template.txt
fi
}
postfix_update() {
if [[ "$FORCE_IPVFOUR" = [yY] && -f /usr/sbin/postconf && "$(postconf -n inet_protocols | awk -F ' = ' '{print $2}')" != 'ipv4' ]]; then
# force postfix to use IPv4 address
echo "updating postfix inet_protocols = ipv4"
postconf -e 'inet_protocols = ipv4'
if [[ "$(ps -ef | grep postfix | grep -v grep)" ]]; then
# only restart postfix is detected that it's currently running
service postfix restart >/dev/null 2>&1
fi
elif [[ "$FORCE_IPVFOUR" = [nN] ]]; then
echo "updating postfix inet_protocols = all"
postconf -e 'inet_protocols = all'
if [[ "$(ps -ef | grep postfix | grep -v grep)" ]]; then
# only restart postfix is detected that it's currently running
service postfix restart >/dev/null 2>&1
fi
fi
}
cloudflare_note() {
if [[ "$(curl -s4Ik $serverhostname | awk '/Server:/ {print $2}')" = 'cloudflare' ]]; then
echo "
Cloudflare users should DISABLE 'orange cloud' Proxy on
server's main $serverhostname DNS record as enabling
Cloudflare on main $serverhostname DNS record will negatively
impact proper email delivery from your server as destination
mail servers can not do a proper reverse DNS PTR lookup to
verify and match your main hostname $serverhostname and it's
resolving server IP address which currently points to:
$pointed_hostname_ip
"
fi
}
check_fail_msg() {
echo "
server ${text_label} IP: $pointed_ip
$serverhostname checked DNS ${text_label} record: $pointed_hostname_ip
-----------------------------------------------------------------------------
fail: PTR ${text_label} DNS record setup
-----------------------------------------------------------------------------
Centmin Mod main hostname $serverhostname reverse PTR
DNS ${text_label} record not detected
$serverhostname requires a working PTR DNS record to ensure
server outbound sent emails are properly delivered to your
previously setup server notification email addresses otherwise
server sent emails end up in destination receipient's spam/junk
mail box. Full instructions to remedy this can be read at
https://community.centminmod.com/threads/6999/
$cloudflare_note
-----------------------------------------------------------------------------
" | tee /tmp/check_fail_msg.log
}
check_pass_msg() {
echo "-----------------------------------------------------------------------------"
echo -e "pass: ok\n$serverhostname reverse PTR lookup ${text_label} address = $pointed_hostname_ip"
}
checks() {
if [[ "$VPS_GEOIPCHECK_V3" = [yY] ]]; then
serverip_ipv4=$(curl -${ipv_forceopt}s${CURL_TIMEOUTS} https://geoip.centminmod.com/v3 | jq -r '.ip')
serverip_ipv6=$(curl -6s${CURL_TIMEOUTS} https://geoip.centminmod.com/v3 | jq -r '.ip')
elif [[ "$VPS_GEOIPCHECK_V4" = [yY] ]]; then
serverip_ipv4=$(curl -${ipv_forceopt}s${CURL_TIMEOUTS} https://geoip.centminmod.com/v4 | jq -r '.ip')
serverip_ipv6=$(curl -6s${CURL_TIMEOUTS} https://geoip.centminmod.com/v4 | jq -r '.ip')
fi
serverhostname=$(hostname)
serverhostname_ipv4=$(dig +short A $serverhostname)
serverhostname_ipv6=$(dig +short AAAA $serverhostname)
relaycheck=$(postconf -n relayhost | egrep -o 'amazonaws|sendgrid|mailgun')
if [[ "$relaycheck" = 'amazonaws' ]]; then
ses_detected='y'
relayhost_detected='y'
elif [[ "$relaycheck" = 'sendgrid' ]]; then
sendgrid_detected='y'
relayhost_detected='y'
elif [[ "$relaycheck" = 'mailgun' ]]; then
mailgun_detected='y'
relayhost_detected='y'
elif [[ "$relaycheck" ]]; then
relayhost_detected='y'
else
ses_detected='n'
sendgrid_detected='n'
mailgun_detected='n'
relayhost_detected='n'
if [[ "$(echo "$serverhostname_ipv4"|wc -l)" -gt '1' || "$(echo "$serverhostname_ipv6"|wc -l)" -gt '1' ]]; then
# check for cdn or anycase/cloudflare proxies
multiip='y'
else
multiip='n'
if [[ "$serverhostname_ipv4" = "$serverip_ipv4" ]]; then
checkptr_ipv4=y
text_label='IPv4'
pointed_hostname_ip=$serverhostname_ipv4
check_pass_msg
else
text_label='IPv4'
pointed_ip=$serverip_ipv4
pointed_hostname_ip=$serverhostname_ipv4
check_fail_msg
failipv4=y
fi
if [[ "$serverip_ipv6" ]] && [[ "$serverhostname_ipv6" = "$serverip_ipv6" ]]; then
checkptr_ipv6=y
text_label='IPv6'
pointed_hostname_ip=$serverhostname_ipv6
check_pass_msg
elif [[ "$serverip_ipv6" ]] && [[ "$serverhostname_ipv6" != "$serverip_ipv6" ]]; then
text_label='IPv6'
pointed_ip=$serverip_ipv6
pointed_hostname_ip=$serverhostname_ipv6
check_fail_msg
failipv6=y
fi
fi
fi
}
check_sent() {
senderr=$?
if [[ "$senderr" -eq '0' ]]; then
echo "email sent at $email_date"
else
echo "error detected sending email"
fi
if [ -f /tmp/check_fail_msg.log ]; then
rm -f /tmp/check_fail_msg.log
fi
}
get_mailid() {
echo "saving postfix maillog entry $CENTMINLOGDIR/emailnotify-maillog-${DT}.log.gz"
echo
echo "to read use zcat:"
echo
echo "zcat $CENTMINLOGDIR/emailnotify-maillog-${DT}.log.gz"
sleep 3.5
mailid=$(tail -20 /var/log/maillog | grep "$primary_email" | tail -1 | awk '{print $6}')
sleep 0.5
grep "$mailid" /var/log/maillog > "$CENTMINLOGDIR/emailnotify-maillog-${DT}.log"
gzip -1 "$CENTMINLOGDIR/emailnotify-maillog-${DT}.log"
}
send_mail() {
if [ -f /etc/centminmod/email-primary.ini ]; then
postfix_update
if [[ "$EMAILNOTIFY_SES" != [yY] ]]; then
symlink_setup_emailnotify
checks
fi
email_date=$(date)
primary_email=$(head -n1 /etc/centminmod/email-primary.ini)
secondary_email=$(head -n1 /etc/centminmod/email-secondary.ini)
body=$1
subject=$2
toemail=$3
if [ "$toemail" ]; then
to_email="$toemail"
else
to_email=$primary_email
fi
if [ -f "$body" ]; then
if [[ "$failipv4" = [yY] && -f /tmp/check_fail_msg.log ]]; then
# append check_fail_msg to body of email so user is aware of issue
#body=$(cat "$body" /tmp/check_fail_msg.log)
bodyecho="$body"
check_fail_msg_note="Message to $serverhostname system administrator regarding mail deliverability improvements: "
body=$(echo -e "$(cat "$body")\n\n${check_fail_msg_note}\n$(cat /tmp/check_fail_msg.log)")
bodyfile=/tmp/emailnotify_temp.log
echo "$body" > "$bodyfile"
if [ -f /usr/sbin/sendmail ]; then
(cat - $bodyfile)<<END | sendmail -t $to_email
From: $primary_email
To: $to_email
Subject: ${subject} - $(hostname) ${email_date}
END
rm -f "$bodyfile"
else
echo "echo \"$bodyecho\" | mail -s \" ${subject} - $(hostname) ${email_date}\" $to_email"
echo "$body" | mail -s " ${subject} - $(hostname) ${email_date}" $to_email
fi
else
bodyfile=/tmp/emailnotify_temp.log
cat "$body" > "$bodyfile"
if [ -f /usr/sbin/sendmail ]; then
(cat - $bodyfile)<<END | sendmail -t $to_email
From: $primary_email
To: $to_email
Subject: ${subject} - $(hostname) ${email_date}
END
rm -f "$bodyfile"
else
echo "cat \"$body\" | mail -s \" ${subject} - $(hostname) ${email_date}\" $to_email"
cat "$body" | mail -s " ${subject} - $(hostname) ${email_date}" $to_email
fi
fi
get_mailid
check_sent
else
if [[ "$failipv4" = [yY] && -f /tmp/check_fail_msg.log ]]; then
# append check_fail_msg to body of email so user is aware of issue
bodyecho="$body"
check_fail_msg_note="Message to $serverhostname system administrator regarding mail deliverability improvements: "
body=$(echo -e "$body\n\n${check_fail_msg_note}\n$(cat /tmp/check_fail_msg.log)")
bodyfile=/tmp/emailnotify_temp.log
echo "$body" > "$bodyfile"
if [ -f /usr/sbin/sendmail ]; then
(cat - $bodyfile)<<END | sendmail -t $to_email
From: $primary_email
To: $to_email
Subject: ${subject} - $(hostname) ${email_date}
END
rm -f "$bodyfile"
else
echo "echo \"$bodyecho\" | mail -s \" ${subject} - $(hostname) ${email_date}\" $to_email"
echo "$body" | mail -s " ${subject} - $(hostname) ${email_date}" $to_email
fi
else
bodyfile=/tmp/emailnotify_temp.log
echo "$body" > "$bodyfile"
if [ -f /usr/sbin/sendmail ]; then
(cat - $bodyfile)<<END | sendmail -t $to_email
From: $primary_email
To: $to_email
Subject: ${subject} - $(hostname) ${email_date}
END
rm -f "$bodyfile"
else
echo "echo \"$body\" | mail -s \" ${subject} - $(hostname) ${email_date}\" $to_email"
echo "$body" | mail -s " ${subject} - $(hostname) ${email_date}" $to_email
fi
fi
get_mailid
check_sent
fi
else
echo
echo "error: /etc/centminmod/email-primary.ini missing"
echo
"${SCRIPT_DIR}/email.sh"
fi
}
usage() {
echo "Usage:"
echo
echo "$0 send emailbody emailsubject"
echo "$0 send emailbody emailsubject toemail-address"
echo
}
######################################################
case "$1" in
send )
if [[ -z "$2" || -z "$3" ]]; then
echo "error: incorrect paramters"
usage
else
if [[ "$EMAILNOTIFY_SES" = [yY] ]]; then
send_ses_mail "${2}" "${3}" "${4}"
else
send_mail "${2}" "${3}" "${4}"
fi
fi
;;
* )
usage
;;
esac