configuring a fake mail server for testing

When building systems that send out e-mails to the customers one has to find a way to test what the output looks like without actually sending the mail to the client.

This article describes how to set up such a fake mail server that can be used in the test environment as a drop in replacement for you actual mail gateway.
Incoming e-mails will be stored on the local inboxes based on the FROM address (the TO address is ignored).
This allows you to test multiple applications against the same test mail server assuming that the applications use different FROM address.

I will also show how to configure IMAP access to these test mailboxes.
This guide has been tested on Debian 7.

Postfix

We will use Postfix as our SMTP server and Dovecot for the IMAP support.

apt-get install postfix dovecot-imapd

In the file /etc/postfix/master.cf find a line that looks like this:

smtp      unix  -       -       -       -       -       smtp

and replace it with:

smtp      unix  -       -       -       -       -       discard

This tells Postfix to send all outgoing mail to discard instead of smtp.
discard will just happily accept whatever is sent to it and will always report successful delivery.

In order to keep a local copy of the the discarded mail for testing add the following line to the file /etc/postfix/main.cf:

sender_bcc_maps = hash:/etc/postfix/sender_bcc

This parameter tells where BCC copies of the mails should be sent based on the FROM address.

Create the /etc/postfix/sender_bcc with contents like this:

user@example.com test1@fake
@example.com fallthrough@fake

and run the command:

postmap /etc/postfix/sender_bcc

At this point the very basic setup is in place and if you restarted the postfix all the relayed e-mails would be dropped and local copies would be stored in mailboxes under /var/mail

To make testing a bit more convenient we will set up virtual mailboxes that will be stored under /var/vmail and can be accessed over IMAP using non-system accounts.

Add the following to the file /etc/postfix/main.cf:

virtual_mailbox_domains = fake
virtual_mailbox_base = /var/vmail
virtual_mailbox_maps = hash:/etc/postfix/virtual_mailbox
virtual_minimum_uid = 100
virtual_uid_maps = static:65534
virtual_gid_maps = static:8

Create the file /etc/postfix/virtual_mailbox

test1@fake test1/
fallthrough@fake test2/

Run postmap on it:

postmap /etc/postfix/virtual_mailbox

Create the mail directory:

mkdir /var/vmail
chown nobody:mail /var/vmail

Now restart Postfix.

postfix reload

At this point mail should be correctly be delivered to Maildir formated directories under /var/vmail for addresses that match entries in /etc/postfix/sender_bcc.

IMAP

Now we will configure access to these local mailboxes over IMAP using Dovecot.
We will use file based auth to keep things as simple as possible.

Create the file /etc/dovecot/conf.d/auth-plain.conf.ext with the following contents:

passdb {
  driver = passwd-file
  args = username_format=%u /etc/dovecot/passwd
}

userdb {
  driver = passwd-file
  args = username_format=%u /etc/dovecot/passwd
}

Now open /etc/dovecot/conf.d/10-auth.conf and add the following line at the end of it:

!include auth-plain.conf.ext

Create the file /etc/dovecot/passwd with contents similar to this:

test1@fake:{SSHA}ghZpew7L4psekJyC0MUoVA3Usg0SxAjm:65534:8::/var/vmail/test1::
test2@fake:{SSHA}c9yb4ibK+rpoMBR+OnoMBrNgyjD8KraL:65534:8::/var/vmail/test2::

Password hashes can be created with doveadm like this:

doveadm pw -s SSHA -p yourPassword

Edit the file /etc/dovecot/conf.d/10-mail.conf by replacing

mail_location = mbox:~/mail:INBOX=/var/mail/%u

with

mail_location = maildir:/var/vmail/%n

Finally restart Dovecot with:

/etc/init.d/dovecot restart

Safeguard

To make double sure that no test e-mails will leave this system we will also firewall outgoing SMTP and only allow connections over localhost:

iptables -A OUTPUT -p tcp -d 127.0.0.1 --dport 25 -j ACCEPT
iptables -A OUTPUT -p tcp --dport 25 -j DROP

And to make this change permanent add it into the file /etc/network/interfaces so that it would be read in every time the interface comes up. Mine looks like this:

iface eth0 inet dhcp
        up /sbin/iptables -A OUTPUT -p tcp -d 127.0.0.1 --dport 25 -j ACCEPT
        up /sbin/iptables -A OUTPUT -p tcp --dport 25 -j DROP

One thought on “configuring a fake mail server for testing

  1. Andrew

    Sven,

    This looks good, but still tooooo complicated for me.

    I am not getting half of it.

    The “names” of the local e-mail stuff is not well explained for me to understand.
    The “format” (do I need a .org at the end of my e-mail address?) and stuff like that.

    Also in your walk through, you restart the server/program. It tells me SUPERUSER needs to do that.
    So SOME of the commands need SUDO in front of them.
    I was doing that mostly anyway, I think, and the one time I didn’t it said I needed to.

    I am only wanting to set up a local e-mail thing as some of my devices have the ability to send e-mails of logs/reports/etc to an e-mail address.
    I don’t want to complicate this and have that going outside, so your idea seems good, but to actually get it working – well that is still to be done.

    Could you please help me?
    I’m going to need a lot of help on this.
    postfix didn’t set up correctly to start with, so there are monsters waiting there to be looked at.

Leave a Reply

Your email address will not be published.


*