Skip to main content

Automated linux shell script to setup Postfix on RHEL7 with Gmail



In my previous article on "How to setup unauthenticated mail server configuration using mail forwarding with authentication", I've tried to collate all the steps required to setup Postfix server on RHEL7. Here, I simply automate it.
Why do it manually, when you could do the same with automation for next 5 years.
-- Random Thoughts

#!/bin/sh

######################################################
# This script will enable the linux postfix setup.
# Ensure that mail, postfix and openssl are installed.
# @author cubicrace.com
######################################################

SMTP_HOST=$1
SMTP_PORT=$2

SMTP_USERNAME=$3
SMTP_PASSWORD=$4
POSTFIX_DIR=/etc/postfix
MAIN_CF=${POSTFIX_DIR}/main.cf
HOSTNAME=`hostname`

ERROR(){
  local line=$3
  [ ! -z $3 ] && line=`expr $line - 1` || line=""
  echo "$1, RC=$2, ERROR on line: $line"
  exit $2
}

INFO(){
  echo "$1"
}

addProperty(){
  echo "${1} = ${2}" >> ${3}
  if [ $? -eq 0 ]
  then 
    INFO "Property \"$1\" configured with value \"$2\""
  else
    ERROR "Failed to add property \"$1\"" 2 ${LINENO}
  fi
}

updateProperty(){
  sed -i "s|^$1[[:space:]]*=.*|$1 = $2|g" ${3}
  if [ $? -eq 0 ]
  then
    INFO "Property \"$1\" configured with value \"$2\"" 
  else 
    ERROR "Failed to update property \"$1\"" 2 ${LINENO}
  fi
}

configure(){
  KEY="$1"
  VALUE="$2"
  FILE="$3"
  [ -z ${KEY} ] && ERROR "Invalid or empty property name \"${KEY}\"." 1 ${LINENO}
  [ -z ${FILE} -o ! -f $FILE ] && ERROR "No such file, $FILE" 1 
  grep -q "^[[:space:]]*${KEY}[[:space:]]*=" ${FILE} >/dev/null 2>&1
  rc=$?
  if [ $rc -eq 0 ]
  then
    updateProperty "${KEY}" "${VALUE}" "${FILE}" 
  else 
    addProperty "${KEY}" "${VALUE}" "${FILE}"
  fi
}

encryptAndStoreSMTPCredentials(){
   echo "${1}:${2}    ${3}:${4}" > ${5}
   postmap ${5}
   chown root:root "${5}" "${5}.db"
   chmod 0600 "${5}" "${5}.db"
}

setupTLSPolicy(){
  echo "$1:$2 encrypt" > ${3}
  postmap ${3}
}

getSignerCert(){
  local domain=`echo "$1" | awk -F'.' '{print $(NF-1)"." $NF}'`
  echo -n | openssl s_client -connect $domain:443 | \
  sed -ne '/-BEGIN CERTIFICATE-/,/-END CERTIFICATE-/p' >/tmp/cacertbundle.pem

  if [ $? -eq 0 ]
  then
    cp /tmp/cacertbundle.pem ${POSTFIX_DIR} 
  else 
    INFO "WARNING: Failed to retrieve certificate from host $domain:443"
  fi
}

sendTestMail(){
  TEST_MAILID="$1"
  TEST_MAILSUB="$2"
  TEST_MAILBODY="$3"
  echo "${TEST_MAILBODY}" | mail -s "$TEST_MAILSUB" "$TEST_MAILID"
  echo ""
  echo "Test email has been sent to $TEST_MAILID with subject, \"$TEST_MAILSUB\""
}

USAGE(){
  SCRIPTNAME=`basename $0`
  echo ""
  echo "Usage:"
  echo "$SCRIPTNAME    "
  echo ""
  echo "For example: $SCRIPTNAME 'smtp.gmail.com' '587' 'sysadmin@gmail.com' 'passpass'"
  echo ""
  exit 1
}

[ $# -lt 4 ] && USAGE

encryptAndStoreSMTPCredentials "${SMTP_HOST}" "${SMTP_PORT}" \
"${SMTP_USERNAME}" "${SMTP_PASSWORD}" "${POSTFIX_DIR}/sasl_password"

setupTLSPolicy "${SMTP_HOST}" "${SMTP_PORT}" "${POSTFIX_DIR}/tls_policy"

configure "myhostname" "$HOSTNAME" "${MAIN_CF}"
configure "relayhost" "${SMTP_HOST}:${SMTP_PORT}" "${MAIN_CF}"
echo "/^From:.*/ REPLACE From:$SMTP_USERNAME" > ${POSTFIX_DIR}/smtp_header_checks
configure "smtp_header_checks" "pcre:${POSTFIX_DIR}/smtp_header_checks" "${MAIN_CF}"
configure "smtp_sasl_auth_enable" "yes" "${MAIN_CF}"
configure "smtp_sasl_security_options" "noanonymous" "${MAIN_CF}"
configure "smtp_sasl_tls_security_options" "noanonymous" "${MAIN_CF}"
configure "smtp_sasl_password_maps" "hash:${POSTFIX_DIR}/sasl_password" "${MAIN_CF}"
configure "smtp_tls_policy_maps" "hash:${POSTFIX_DIR}/tls_policy" "${MAIN_CF}"
configure "smtpd_use_tls" "yes" "${MAIN_CF}"
getSignerCert "${SMTP_HOST}"
configure "smtp_tls_CAfile" "${POSTFIX_DIR}/cacertbundle.pem" "${MAIN_CF}"
service postfix restart
sleep 2
sendTestMail "${SMTP_USERNAME}" \
"Test email: Postfix configuration for $HOSTNAME on `date`" \
"This is a test mail generated by the configuration script from 'http://www.cubicrace.com'"


Usage:
./setup_postfix_relay.sh "smtp.gmail.com" "587" "someadmin@gmail.com" "gmail_password_of_someadmin"