Postfix relaying Amazon SES in a Beanstalk PHP application


I’ve been working alot with a customers setup with originally a local sendmail server on Amazon Linux server. This turned out to not work as intended. I have setup a Ubuntu machine with Exim4 relaying Amazon SES for another customer, but unfortunately Amazon Linux doesn’t provide any packages for Exim4, so I had to go with Postfix instead.

The installation was pretty straightforward and the initial setup just includes the smtp settings Amazon provide in their documentation.

relayhost = email-smtp.eu-west-1.amazonaws.com:25
smtp_sasl_auth_enable = yes
smtp_sasl_security_options = noanonymous
smtp_sasl_password_maps = hash:/etc/postfix/sasl_passwd
smtp_use_tls = yes
smtp_tls_security_level = encrypt
smtp_tls_note_starttls_offer = yes

Just change the relayhost to whatever Amazon SMTP server you have production access too.

Then the password file has to be created. Because I want to reuse the same Amazon AMI to more than one customer, I can’t make the password file onto the image, and it has to be inserted individually on each Beanstalk application deploy.
I created a small bash script to make that possible. Include that script into the .ebextension directory of the application zip.
Here’s the simple bash script.

files:
  "/opt/aws/postfix-ses.sh" :
    content: |
        #!/bin/bash
        #
        # Configure postfix to relay Amazon SES SMTP servers in EU
        PHPINI="/etc/php.d/environment.ini"
        PASSWDFILE="/etc/postfix/sasl_passwd"
        if [[ -a ${PHPINI} ]]; then
          SES_USERNAME=`grep 'SES_USERNAME' /etc/php.d/environment.ini | cut -d "=" -f2 | sed -e 's/^"//'  -e 's/"$//'`
          SES_PASSWORD=`grep 'SES_PASSWORD' /etc/php.d/environment.ini | cut -d "=" -f2 | sed -e 's/^"//'  -e 's/"$//'`
          echo "email-smtp.eu-west-1.amazonaws.com:25 ${SES_USERNAME}:${SES_PASSWORD}" > ${PASSWDFILE}
          if [[ -a ${PASSWDFILE} ]]; then
            postmap hash:${PASSWDFILE}
            rm -f ${PASSWDFILE}
            if [[ -a "${PASSWDFILE}.db" ]]; then
              chown root:root "${PASSWDFILE}.db"
              chmod 0600 "${PASSWDFILE}.db"
              postconf -e 'smtp_tls_CAfile = /etc/ssl/certs/ca-bundle.crt'
            else
              logger "Could NOT find ${PASSWDFILE}.db, postfix configuration failed."
              exit 1
            fi
          else
            logger "Could NOT find ${PASSWDFILE}, postfix configuration failed."
            exit 1
          fi
        else
          logger "Could NOT find ${PHPINI}, postfix configuration failed."
          exit 1
        fi
    mode: "000755"
    owner: root
    group: root

What is needed for this to work out as intended then?
First of all, this is a PHP application, so I’m not sure how this would be possible to transfer into a Java application.
As you can see in the script above, I grep for environment variables that is set in Beanstalk software configuration. You can use whatever variable name you want but change the grep lines accordingly. So, the variables are of course the username and password you were given when you signed up for Amazon SES production access. It’s not your normal IAM credentials. Other than that, you’re ready to go.

Comments

comments