Tutorial: Email server for a small company – including IMAP for mobiles, SPF and DKIM

email_iconA few months back my wife started a small business. Of course I was the one to build the “IT stuff” here that included a website, some reservation system on it for customers (php programming here), local network in the office and customer area and other things. Most of that was all pretty common tasks for me with the exception of one, building an email system for a company emails. So I built it and since it was new and interesting experience for me, I will share here a quick tutorial (or better call this a cookbook?) to replicate the very minimum system.

Now also let me state here that I really missed somehow in my life running a real email system so far. And it was a little challenge to setup it properly for the first time. I always thought in the past that installing SMTP daemon in linux and activating it for all local users was all that I will ever need (because up to this point my needs were only to receive monitoring and alarm emails to my gmail, nothing else). Now that my needs has moved to a much more “representative” role the approach had to be changed a lot.


1) A Linux server, preferably debian to follow this tutorial step by step, on other distributions the software packages and file paths can be different

2) Public IP address preferably directly on the server (+ if you are not directly owning the IP in RIPE database, the provider of this IP address to you should be able and willing to set reverse DNS entry on this IP address later in this tutorial, so if you are just looking for provider check this with him before ordering a service from him).

3) A publicly registered domain name either with some DNS hosting company (like I used here for convenience) or you can do yourself a small DNS server (but this is outside of this tutorial). If you will have a DNS provider, just make sure he allows you to enter TXT records for your domain record.

My example users and domain used in this tutorial

In this tutorial, I will be using one of my public domains “pingonyou.com” that I am personally owning, but which I am not really using at this moment for anything usefull. Please change all pingonyou.com text in this tutorial to your own domain when following this tutorial. At the point of writing this tutorial this pingonyou.com was pointing to public IP of, which is one small VM server I was renting at the time, this is also no longer in my possession. 

Also the demouser account I will be using is a fake, so do not bother sending email to demouser@pingonyou.com.

The target what we will have at the end of this tutorial

  • We would like to have an email system with email in the form of @pingonyou.com
  • We would like to have IMAP secured with SSL for access to your emails (test is to access emails from your smartphone)
  • We would like all standard protection mechanisms on our emails so that other email systems do not classify our emails as SPAM, this includes SPF, DKIM, rDNS and SpamAssassin header.

The implementation Step-by-Step

Step 1: Configure local hostname and domain on linux server

In this step, we have to first realize how we will call our systems. As I mentioned earlier, I will use “pingonyou.com” as example of domain and our server you are free to designate as you wish with a hostname, as example here I will use “pingonyouserver“. The last point is that if I will need to use a public IP address for your mail server or DNS, I will use example (this is a gmail DNS system FYI).

Verification is easy, just use these commands and you should get the answers visible.

Step 2: Install email system exim4 and supporting packages

To get all the software in debian for our little tutorial, we need three main pieces of software:

  1. Exim4 – the SMTP daemon
  2. Courier – communication extension for Exim4 to have IMAP and POP access to emails
  3. Swaks – Swiss army knife for SMTP troubleshooting
  4. SSL-cert packages – for easy work with generating certificates in later parts of the tutorial

If you are using debian like I am, then you can simply follow these commands :

The courier will by default use a self-signed certificates, these are OK if you are going to be the only user of the mail system, but if you plan to invite many people like for a public system (and you do not plan to distribute your own certification authority to them), then you need a signed-certificate. But for our use-case we will not go into replacing these for our small IMAP usage which is OK for a small company, but definitely not OK for a public or larger one! This is also the warning installation will give you about this fact:
courier warning===============================================

Verification of the installation can be afterwards done by checking the running ports with a netstat command if all the pop3, imap, smtp, pop3s and imaps ports are present like visible like in the example below:

Step 3: Preparing local users for mail system (Maildir)

In this example, I will prefer each user having his email inside his home directory under ~/Maildir. For the new users, add this directory to the skeleton so that it is automatically created for new users like this:

For existing users, you have to do this manually (or do a script for this). For example for my test user “testuser” like this:

Step 4: Create new user to test the mail system

Give this user a password when prompted. Always choose a good password here because this UNIX passwords will also be user by the IMAP/POP3 access to your emails!

Step 5: Configure exim4

Now, first step here is to use the debian built-in configuration package to configure the “main” exim4 points with:

It will give you several options in a wizard, this is how I configured my answers for a small and independent server:

  • General type of mail configuration: internet site; mail is sent and received directly using SMTP
  • System mail name: pingonyou.com
  • IP-addresses to listen on for incoming SMTP connections: leave this field empty!!!
  • Other destinations for which mail is accepted: leave this field empty!!!
  • Domains to relay mail for: leave this field empty!!!
  • Machines to relay mail for: leave this field empty!!!
  • Keep number of DNS-queries minimal (Dial-on-Demand)?:NO
  • Delivery method for local mail: Maildir format in home directory
  • Split configuration into small files?: NO
  • Root and postmaster mail recipient: demouser (or your real administrator name, but non-root account)

 Step 6: X.509 certificate for exim4 TLS support

First run this small command to generate a certificate based on example from exim.

Next, based on the documentation you find in /usr/share/doc/exim4-base/ , you should create a file /etc/exim4/exim4.conf.localmacros to and insert these lines to enable TLS support on port 465.

Inside /etc/default/exim4 change this line:

To this:

Ok, now restart exim4 again with the service command

And check if the exim4 is listening on port 465:

 Step 7: Verification of emails delivery

Ok, so the basic email system should now be running, lets test it with the most basic test and that is sending an email locally (either between two users of the local system or to yourself).

For my test, I will send email to testuser from testuser.

You can either check the inbox of demouser, or more simply check logs inside /var/log/exim4/mainlog

Ok, all looks good, now lets try sending to external source like gmail (replace the xxxx with your real email).

Now the good and the bad part, the email arrived, but it ended most probably in spam folder because technically this is a “rogue” system with unknown domain and no basic signatures in the email headers.

Step 8-9: First problem with PAM not enabled in courier

As immediate step after my emails got working was that Thunderbird was unable to connect to the courier with IMAPS (with TLS enabled) despite the basic certificates existed from the installation (during apt-get install a default set was generated).

To verify what is going one, this is the best test to see the problem, we will use SWAKS to troubleshoot like this:

As you noticed, the TLS layer is there successfully, the problem is more with the authentication not working.

  1. Add these lines to /etc/exim4/exim4.conf.template
  2. Install SASLAUTH daemon that will do the authentication for us against local unix usernames.
    NOTE: If you want some other method of authentication, check the exim4 wiki.
  3. Edit /etc/default/saslauthd to enable saslauth with this line change:
  4. Restart the SASLAUTH daemon:
  5. Add exim to sasl group
  6.  Inside /etc/exim4/exim4.conf.template uncomment these lines to enable PAM authentication (in the below all lines below and including the “plain_saslauthd_server”):
  7.  Do a restart of both exim4 and saslauth

VERIFICATION is again with swaks the same command, but now you should get this (note “235 Authentication succeeded” below):

 Step 10: Configure courier for IMAP

You want this because it is most useful for your smartphone access that is definitely supporting mainly IMAP. Just follow these basic commands:

Step 11: Test access with email client (e.g. Thunderbird)

I am personally using Thunderbird for a long time now, but if you have a different preferred client, please feel free to try using it (including smartphone mail clients that support IMAP protocol). These are my Thunderbird settings that worked for this example configuration.

Thunderbird wizard adding new email account and manually configured IMAP and SMTP parameters

Thunderbird wizard adding new email account and manually configured IMAP and SMTP parameters

NOTE: Since we are using self-signed certificates here, you are definitely going to get warnings from Thunderbird (or other clients) that the certificates are not officially trusted. If you are doing this for a real company, please go and purchase a real certificates from certification authorities (e.g. verisign…)

Thunderbird self-signed certificate warning

Thunderbird self-signed certificate warning

If your connection with any client was successful, please try writing a quick email to yourself, for example this is how it looked in my system in Thunderbird.

Thunderbird email loop test

Thunderbird email loop test

Or here is the raw message code:

 Step 12: Testing towards gmail or other external system

Now simply use Thunderbird, or other client and send an email to external systems, but the point he is that there is a random chance (for example I expect ~50% chance with gmail) that your email will end in spam folder on the destination.

HINT: To check if your email left your system, check all the mail logs in the /var/log/mail*

Step 13: Making the email system appear as a valid domain owner for passing spam filters

There are three basic things every email system should do to get anti-spam protection permitting emails received from your new systems to remote systems inboxes without ending in spam folders.

  1. rDNS (or reverse DNS)  to have reverse DNS lookup on the public IP pointing back to your domain.
  2. SPF (Sender Policy Framework) that let’s the receiving system know which systems are allowed to send emails for your domain.
  3. DKIM (DocumentKeys Identified Mails) a public/private key pair that is used for signing emails by the domain owner to avoid spammers being able to send emails “as if” coming from your domain.

Step 13A: Reverse DNS entry

Now, this part is between you and your provider, but you must ask the owner of the public IP you are using to create a reverse DNS entry for you.

Most providers of servers (ramnode, nfoserver, etc… ) have this option as part of their control panel so the work is a few clicks, but it is imperative to do.

DISCLAIMER: I am going to use in the following example the public IP of which I was on temporary measure using in one rented virtual server from undisclosed provider. I do not own this IP, please consider this IP only as random public IP without any technical meaning and replace in this step with your own public IP used.

A quick view on one such system:

eDNS setting example with my server provider GUI

eDNS setting example with my server provider GUI

To verify, either use “nslookup -r” command to your own domain, or web tool such as this one http://mxtoolbox.com/SuperTool.aspx

Step 13B: SPF

In summary to what we will be doing here for SPF is basically again that you need to interact either with your own DNS system, or contact your DNS hosting company (or do this via their control panel if they have this) and ask them to enter some special TXT records to your domain. Here are example steps to follow:

  1. First I absolutely stress that you read this page to understand SFP to avoid generating something incorrectly and hurting you email system from the very beginning!
  2. For my example, I simply want to allow my main server “yourmailserver” from my “yourcompany.com” domain to send emails. So the records for my are like this for SPF1 and SPF2 records:

    Quick legend:

    1. the “a” allows any of the DNS A records to authorize domains (like basic pingonyou.com) to send emails.
    2. the “include” allows other domains like the server FQDN to send the email (MAKE SURE YOU ALSO HAVE A DNS A RECORD FOR YOUR SERVER FQDN!)
    3. “-all” removes all other IPs/Domains from the ability of sending emails.EXAMPLE: My provider (websupport.sk) has a nice GUI to edit these TXT records for my domains, please adjust this step according to your way of DNS providing, I am 99% sure your DNS provider will support this, or if you are self-DNS hosting, adding this to your database shouldn’t be a problem for you. Please note that “yourcompany.com” is a fake, so I will show here as example a picture how I have setup one of my domains pingonyou.com, which is currently not really hosting anything useful.

      TXT record editing example in web gui of my provider (websupport.sk) for my inactive pingonyou.com domain

      TXT record editing example in web gui of my provider (websupport.sk) for my pingonyou.com domain

  3. You can then apply them to the DNS record and test it with an online tool like this:
    http://tools.bevhost.com/spf/HINT: At the very end of this guide, we will be sending a test email to a testing service that will verify SPF and other useful things for us, so if you have trouble with this tool, wait with testing for that.

UPDATE 2018: Since moving to new server that includes also IPv6, here is how a SPF records should look like if you are in dual IP4 and IPv6 situation like I am:

 Step 13c: DKIM public keypair to sign emails leaving your system

Now this one is a little more tricky as we are again going to play with certificates, but also with exim4 routing of emails. So let’s take it slowly:

  1. Generate an RSA public and private keys with openssl
  2. Read your new public key
  3. Construct a DNS TXT record with the public key following this formula :
    Domain name: key1._domainkey.<your domain name>
    TXT record: v=DKIM1; k=rsa; p=<your public key string>For my domain example pingonyou.com , this is the TXT record I asked my DNS provider to enter into the DNS system.Domain name:

    TXT record itself:

    Here is how it looked in my DNS provider system:

    DNS TXT record with DKIM key in my example DNS provider (websupport.sk)

    DNS TXT record with DKIM key in my example DNS provider (websupport.sk)

  4. Create a file dkim_senders to tell exim what source domains the DKIM should be used for:
  5. Edit /etc/exim4.conf.template and in section “router/200_exim4-config_primaryjust beforednslookup_relay_to_domains:” add these new lines:
  6. Again inside the /etc/exim4/exim4.conf.template inside section “transport/30_exim4-config_remote_smt” just before “remote_smtp:” add these new lines:
  7. Restart exim
  8. Now you should have everything very nicely prepared, to get a report about how successfully you were, send a test email here (any content) :
    You will get back an email with a very nice and complete summary of the SPF/DKIM and some other checks, here is my example with details how the system from this tutorial passed SFP and DKIM test. I think this is a very nice result so far 🙂

Step 14: SpamAssassin header attachment

One thing that was missing in the previous step last test was the SpamAssassin check. SpamAssassin is mainly used for incomming emails, but I am leaving that for some follow-up tutorial. Right now we are going to use SpamAssassin to add its header to all emails that our system sends to try to declare we are not spam.

So this is a super quick how-to to enable very basic spam-assassin checks on your emails.

DISCLAIMER: Taken mostly from debian exim documentation: https://wiki.debian.org/Exim, not much credit for me here :apt-get install spamassassin

  1. Set “ENABLED=1” inside /etc/default/spamassassin
  2. Start the spamassassin daemon:
  3. Uncomment this line in /etc/exim4/exim4.conf.template
  4. Edit /etc/exim4/exim4.conf.template and inside section “40_exim4-config_check_data change” edit the content inside  “acl_check_data:” function
  5. Rebuild exim config and restart exim
  6. Test by either sending again to check-auth@verifier.port25.com  or catch the outcomming emails from your system and it should have this header inside:


In summary, this is how my very first email system started running (only that the used example pingonyou.com is not the real company email, but my test domain that no longer servers emails, so do not bother sending something to it). And yes, the next step to do after the other systems (like gmail) stopped considering us a spam with SPF/DKIM and other functions satisfied is to filter out all the incomming spam! (oh boy how much we started getting it after 6 months …  but solving that is for the next tutorial to come.

I hope you enjoyed this tutorial and it helped you a little. It is not as cool as the cloud/SDN/network topics, but hopefully some basic and practical one is also helpful.

Peter Havrila

About Peter Havrila

Peter's Profile Page