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
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.