Integrating email in PHP applications on Ubuntu server with Amazon SES

Most of the things on the internet got easier over the years. One aspect that became more difficult is integrating sending email from Linux servers or PHP hosting applications. In the past you could easily fill out the SMTP credentials from an email provider but due to 2 tier authentication and other layers of security it becomes more difficult to integrate your Gmail, Yahoo or any other email providers account. Also the internet service providers are blocking ports and become more strict in the usage of sending emails due to spam control. Another reason for using SES is that there is no need to fill out SMTP credentials in web applications, also if something goes wrong your SES account will be blocked but you still maintain access to your email account.

http://arrioch.deviantart.com/art/Senary-157281730
http://arrioch.deviantart.com/art/Senary-157281730

This tutorial describes a way how to set up a perfect mail relay system for an Ubuntu server. Let’s list the ingredients first:

When you feel familiar with the topics above than this setup will be a breeze if not do some further investigation to the links above.

Amazon AWS

In 2006, Amazon Web Services (AWS) began offering IT infrastructure services to businesses in the form of web services — now commonly known as cloud computing. With the Cloud, you can instantly spin up hundreds or thousands of servers in minutes and deliver results faster.

Today, Amazon Web Services provides a highly reliable, scale-able, low-cost infrastructure platform in the cloud that powers hundreds of thousands of businesses in 190 countries around the world. With data center locations in the U.S., Europe, Brazil, Singapore, Japan, and Australia.

Ubuntu Server

The leading platform for scale-out computing, Ubuntu Server helps you make the most of your infrastructure. Whether you want to deploy an OpenStack cloud, a Hadoop cluster or a 50,000-node render farm, Ubuntu Server delivers the best value scale-out performance available.

Amazon AWS SES

Amazon SES stands for Simple Email Service. Amazon SES is an outbound-only email-sending service that provides an easy, cost-effective way for you to send email. You can use Amazon SES to send marketing emails such as special offers, transactional emails from PHP applications such as order confirmations, and other types of correspondence such as newsletters or get emails from a Linux server about the status. As always with Amazon you only pay for what you use. The pricing in October 2014 is 10 cents per 1000 emails. In addition you pay data out transfer which is probably around 1 cent per GB.

Other companies that deliver similar email relay services are, Luxsci Smarthost, SMTP email delivered, AuthSMTP.

PHP websites

A lot of websites in the world are built on PHP to name a few popular ones: Facebook, Yahoo, Wikipedia and WordPress and when you are running your own website like this WordPress website you probably want some email interaction with your website.

Webmin

When running your own Linux server for example Ubuntu LTS 14 or 12 you like to get some feedback from it to know if everything is running smooth. You can do this via the command line but when you don’t use the command line everyday a browser based system such as Webmin is more convenient. Webmin is a web-based interface for system administration for Unix. Using the popular browsers Chrome or Firefox, you can set up user accounts, Apache, DNS, file sharing and so on your Linux box.

Sendmail

Sendmail is the software that makes it possible to sent an email in a Linux environment. Sendmail is a general purpose internet work email routing facility that supports many kinds of mail-transfer and delivery methods, including the Simple Mail Transfer Protocol (SMTP) used for email transport over the Internet. Two other good open source choices are Postfix and Exim.

Setup SES in Amazon AWS

So far the introduction of the ingredients, from now I assume you have your Amazon AWS account setup, you have an Ubuntu server running as EC2 instance, Virtual Machine or an old computer with Ubuntu in your home. I further assume you have access the domain name records at your domain name registration provider since we have to add a few. If you have your website running at a hosting provider like Hostgator, Bluehost, Godaddy, iPage, JustHost or Hub webhosting club you can use this tutorial for some inspiration. Before we start with the configuration of the server and the server software we first setup Amazon SES. It’s pretty easy just a few screenshots to guide you.

First thing you want to do, is apply for production access, otherwise you can only play around in the sandbox

AWS SES 1

2. Create your SMTP credentials

AWS SES 2

3. Verify a new domain, this is the domain you want to use for sending email, this can be different from you internet domain name.

AWS SES 3

4. After verifying you will get TXT record and CNAME records which you need to copy into DNS records at you hosting company your domain name registrar or use a service provider like CloudFlare.AWS SES 6

You will receive some emails from Amazon when the setup is completed.

Software installation and configuration

Start up shell access to your server and install Sendmail:

sudo apt-get install sendmail

The next step you only have to do when you don’t use a fully qualified domain name (FQDN) such as www.maripositas.org. In this example I use the hostname maripositas

The next step take some extra care make a mistake and you lose connection to your sever. Edit your host file:

sudo nano /etc/hosts

add the following bold line to the configuration which probably looks something like this

127.0.0.1    localhost

127.0.1.1    maripositas.localhost maripositas

# The following lines are desirable for IPv6 capable hosts

::1     ip6-localhost ip6-loopback

fe00::0 ip6-localnet

ff00::0 ip6-mcastprefix

ff02::1 ip6-allnodes

ff02::2 ip6-allrouters

if you have a fully qualified domain name then it probably looks like this:

127.0.0.1 localhost blog.maripositas.org

# The following lines are desirable for IPv6 capable hosts

::1 ip6-localhost ip6-loopback

fe00::0 ip6-localnet

ff00::0 ip6-mcastprefix

ff02::1 ip6-allnodes

ff02::2 ip6-allrouters

ff02::3 ip6-allhosts

Note for a system with a permanent IP address the 127.0.1.1 could also be replaced with the permanent IP address for more reading check out source 1 and source 2. (source 1 and source 2).

Restart the network so the new host configuration will be loaded:

sudo /etc/init.d/networking restart

Now we are going to configure Sendmail to send email through the Amazon SES endpoint you have three options here:

  1. email-smtp.eu-west-1.amazonaws.com (Ireland)
  2. email-smtp.us-west-2.amazonaws.com (Oregon)
  3. email-smtp.us-east-1.amazonaws.com (Virginia)
sudo nano /etc/mail/authinfo

add the following text to the file:

AuthInfo:email-smtp.us-east-1.amazonaws.com "U:root" "I:USERNAME" "P:PASSWORD" "M:PLAIN"

Change USERNAME to the Amazon credentials you go from the Amazon AWS website when you created the SMTP credentials. Change PASSWORD to the Amazon credentials as well.

The LOGIN i have set to PLAIN, if you like you can use the more secure DIGEST-MD5 but than you have to convert the password.

Save the authinfo file

Type the following command to generate /etc/mail/authinfo.db:

sudo makemap hash /etc/mail/authinfo.db < /etc/mail/authinfo

Open the /etc/mail/access file and include support for relaying to the Amazon SES SMTP endpoint by adding the following line.

sudo nano /etc/mail/access

Move to line 69 were you find

# Client Connection rate (and #) control

Connect:localhost        RELAY

Connect:email-smtp.eu-west-1.amazonaws.com RELAY

and add the bold line check you use the correct region which you earlier setup.

Type the following command to regenerate /etc/mail/access.db:

sudo makemap hash /etc/mail/access.db < /etc/mail/access

If you like back-up copy of /etc/mail/sendmail.mc and /etc/mail/sendmail.cf.

Add the following group of lines to the /etc/mail/sendmail.mc file before any MAILER() definitions. If you add a FEATURE() line after a MAILER() definition, when you run m4 in a later step, you will get the following error: "ERROR: FEATURE() should be before MAILER().":

Important be sure to use the ` character and the apostrophe exactly as shown.

define(`SMART_HOST', `email-smtp.us-east-1.amazonaws.com')dnl
define(`RELAY_MAILER_ARGS', `TCP $h 25')dnl
define(`confAUTH_MECHANISMS', `LOGIN PLAIN')dnl
FEATURE(`authinfo', `hash -o /etc/mail/authinfo.db')dnl
MASQUERADE_AS(`maripositas.org')dnl
FEATURE(masquerade_envelope)dnl
FEATURE(masquerade_entire_domain)dnl

Change Smart_Host to the correct region settings region

Masquerade_as should be the domain name were you want to sent the emails through, By adding this masquerade, you are making email from this host appear to be sent from your domain. Otherwise, the email will appear as if the email is being sent from the host name of the mail server, and you may get an “Email address not verified” error when you try to send an email.

Run the following commands:

sudo chmod 666 /etc/mail/sendmail.cf
sudo m4 /etc/mail/sendmail.mc > /etc/mail/sendmail.cf
sudo chmod 644 /etc/mail/sendmail.cf
sudo /etc/init.d/sendmail restart

Send a test email by doing the following, you can only do this test if you have done the complete registration procedure at Amazon SES.

sudo /usr/sbin/sendmail -f [email protected] [email protected]

Press enter

hello world

Press ctrl+D

You should now be able to receive emails to the account you have sent the message to if any problems check the log file: /var/log/mail.log

Sendmail must now be fully functional we have to configure the php.ini files to let Apache know how it can sent email:

Edit (uncomment) the php.ini files in Ubuntu so they match the files below:

 sudo nano /etc/php5/apache2/php.ini
; For Unix only.  You may supply arguments as well (default: "sendmail -t -i").
; http://php.net/sendmail-path
sendmail_path = "/usr/sbin/sendmail -t -f [email protected] -i"
sudo nano /etc/php5/cli/php.ini
; For Unix only.  You may supply arguments as well (default: "sendmail -t -i").
; http://php.net/sendmail-path
sendmail_path = "/usr/sbin/sendmail -t -f [email protected] -i"

Further more you can do a quick test in your Webmin environment:

Go to Webmin menu, Webmin configuration files, on the next page click sending email:

webmin send email

I hope this helps in setting up a good and stable email relay system for your Linux server. When you find any mistakes drop a comment.

IPV6 ready

Today about 1% of Internet surfers can’t get to my site. These surfers are on an IPv6-only network and their entire Internet universe consists of only about 6,000 websites. To put that in perspective, that’s like the Internet circa 1996. The other 99% of Internet surfers use the IPv4 network and can get to your site no problem since it running on IPv4 infrastructure. But the number of IPv4 addresses is running out, and the 1% of visitors on IPv6 will soon be 2% and eventually most new web surfers will only have IPv6. That means before long, if something doesn’t change, most surfers on the web won’t be able to see my site.

That seemed like a really gloomy outcome so i spend a little time to setup my IPV6 records in my dns records of Cloudflare.


ipv6 ready

Featured image thanks to Samskart