Configure a Mailserver for your Tech Startup

So you just bought a domain name and now you need to setup email accounts for everyone in your Startup. Well, I guess you could go out and find email hosting. But who wants to spend about $2-$3 / month / mailbox? After all, this is Lean Startup right? Screw that! You call yourself a tech guy right? You are 1337! So setup your own email server!

This guide will walk though the steps to configuring a Mailserver hosted on Amazon EC2 using Ubutnu 12.04. By the end you will have working:

  • Unlimited email accounts with unlimited storage (depending on your VPS disk space of course)
  • Ability to setup as many alias/forward addresses (think support@, noreply@, etc)
  • IMAP and POP3 (but IMAP is way better, don’t use POP3)

To accomplish this we will use Postfix and Dovecot installed on Ubuntu 12.04 server on Amazon EC2.

Setup your Mailserver

The server instance should allow tcp traffic from the internet in. Email commonly runs on these ports, so open then up on your firewall:
SMTP – 25
SMTP (submission) – 587
IMAP – 143
IMAPS – 993
POP3 – 110
POP3S – 995

If you are running your mail server on EC2, you should know that Amazon puts limitations on sending emails from your server. You should fill out this form to request Amazon allow email to be sent from your instance.

Setup DNS

Set your domain’s MX record to point to your email server. You probability only have one email server at this point, so set the MX’s priority to 0.

Also, setup a SPF DNS Record. Setting this up is import to ensure that email sent from your server is less likely to be marked as SPAM. Read more about Sender Policy Framework here.

Install Postfix and Dovecot

sudo apt-get install postfix dovecot-core dovecot-sqlite

The config wizard will run, choose ‘Internet Site’, and then enter your domain, like ‘example.com’. You now how Postfix installed and listening for SMTP traffic on port 25. By default, Postfix comes configured to accept incoming emails for system user accounts and deliver them to /var/mail/account_name. See, back in the day, when email was first invented, it was invented by a bunch of computer nerds, for computer nerds (BNFN). The only people sending and receiving emails where these huge dorks sitting in front of a computer terminal, running their science computer programs on prehistoric mainframe computers. When an email came in, it was delivered to a special text file on the computer (/var/mail/account_name) and was read but printing out the contents of the text file to the screen. Super primitive stuff. But now, its 2013 and the entire world’s business runs on email. Even your mom has an email account. So email technology has evolved and now we have email clients that make it a lot more user friendly to send and receive emails for humans (not just nerds). We now have to do some extra configuration work to get our email server into the modern day.

Virtual mailboxes allow you to add email address to your server without creating a new unix account for each new address. But before we configure the virtual mailboxes, we gotta create a new system user and location on the filesystem to store the virtual mailboxes. Also we will be using a different mailbox format called Maildir to store the email on disk.

Configure Maildir

First lets start by creating a vmail user and group then we will configure postfix to save incoming email to /var/vmail/domain/user.

Create a vmail System user

sudo useradd -r -g mail -d /var/vmail -s /bin/false -c "Virtual maildir handler" vmail  
sudo mkdir /var/vmail  
sudo chmod 770 /var/vmail  
sudo chown vmail:mail /var/vmail  

Create sqlite virtual mailbox database

Now let’s create a sqlite database to hold our virtual mailbox address. There is a little bit of custom code I wrote that I will reference in the following steps. You can see my code in this gist. The first bit of code I reference is the sqlite db schema file: maildb.sql

cat maildb.sql | sudo sqlite3 /etc/mailbox.sqlite

Configure postfix to use sqlite

Edit /etc/postfix/main.cf

  • remove the ‘mydestination’ entry
  • add:
virtual_mailbox_domains = vym.me  
virtual_mailbox_base = /var/vmail  
virtual_mailbox_maps = sqlite:/etc/postfix/vmailbox_sqlite.cf  
virtual_minimum_uid = 100  
virtual_uid_maps = static:999  
virtual_gid_maps = static:8  

Note: the virtual_uid_maps and virtual_gid_maps are the unix user/group ids of the vmail user we just created. Lookup your values in /etc/passwd

Create a new mailbox account

Generate a new password for a user:

doveadm pw  
Enter new password:  
Retype new password:  
{CRAM-MD5}ab89326afeb60fc2b1566a543e3d28adbf222afdef39ff989596a51bbf89f88d

Now you can start adding new virtual mailboxes for your domain:

echo "INSERT INTO mailbox ('username', 'domain', 'password') VALUES ('paul', 'example.com', '{CRAM-MD5}ab89326afeb60fc2b1566a543e3d28adbf222afdef39ff989596a51bbf89f88d');" | sudo sqlite3 /etc/mailbox.sqlite  

Configure SMTP submission port (TCP 587)

A lot of times ISP will block access to TCP 25 because its common use of sending out SPAM. So it is a good idea to also use port 587.

uncomment the lines in /etc/postfix/master.cf to look like:

submission inet n       -       -       -       -       smtpd  
-o syslog_name=postfix/submission
-o smtpd_tls_security_level=encrypt
-o smtpd_sasl_auth_enable=yes
-o smtpd_client_restrictions=permit_sasl_authenticated,reject

Configure Dovecot

/etc/dovecot/dovecot.conf

mail_location = maildir:/var/vmail/%d/%n  
mail_uid = vmail  
mail_gid = mail  
ssl = yes  
ssl_cert = </etc/ssl/certs/ssl-cert-snakeoil.pem  
ssl_key = </etc/ssl/private/ssl-cert-snakeoil.key  
protocols = imap

service imap-login {  
  inet_listener imap { port = 143 } inet_listener imaps { port = 993 } }
protocol imap { }  
auth_mechanisms = plain login  
userdb {  
  driver = sql
  args = /etc/dovecot/dovecot_sqlite.conf
} 
passdb {  
  driver = sql
  args = /etc/dovecot/dovecot_sqlite.conf
} 
service auth {  
  unix_listener /var/spool/postfix/private/auth { 
    mode = 0660
    user = postfix
    group = postfix 
  }
}

test user login:

sudo doveadm auth *paul@vym.me*

You can also tail the /var/log/mail.log file when testing to make sure that everything is going well

tail -f /var/log/mail.log

Some great sources:
http://www.uponmyshoulder.com/blog/2010/set-up-a-mail-server-on-amazon-ec2/
http://technology.mattrude.com/2009/09/installing-postfix-with-sqlite-support/

Paul Soucy

Read more posts by this author.