back 2017-01-18 DockerLinuxServer
  1. Mail-Server with Cow Power
    1. Mailcow
      1. SOGo Groupware
      2. docker-compose.yml adjustments
      3. Rainloop Webmail
      4. Send mails from the docker host system
      5. DNS, DKIM, SPF

Mail-Server with Cow Power

My mail server have seen better days and it’s time to think about a new stack.
A modern mail server should cover:

  • Anti-Spam tools with auto-learning
  • SSL Encryption
  • DKIM mail signing
  • Sender policy framework (SPF)
  • Webmail UI
  • Filter-rules for ie vacation auto-reply
  • Docker containers

The most difficult part is the anti-spam implementation. Its a narrow burr between spam and ham. A good spam filter should block most real spam but has to be permissive enough to accept your friends mails.

I’ve used Postfix as SMTP and Dovecot for IMAP along with SpamAssassin and Postgrey for anti-spam and greylisting. I achieved good results using this stack.

Greylisting is a technique to block mails from unknown servers in a way that the sending SMTP thinks the target is not reachable. Ordinary mail servers would retry the delivery for some time but spammers (mostly) give up on the first fail. The drawback is a delay of about 15 minutes for mails from unknown servers and this can be really annoying.

Some researches brought me to rspamd. This nice anti-spam tool scans the incoming mails and uses greylisting only if the spam rating exceeds a given threshold. It looks like a better replacement for SpamAssassin and Postgrey.

Mailcow

A friend who has written some german posts about his mail setup recommended mailcow. I took a deeper look at the dockerized version of mailcow which differs from the standard setup but includes all the things from my must-have feature list and has a nice WebUI.

So I tried mailcow. The setup was pretty easy, a little bash script generates a config for you and docker-compose up does the rest. Mailserver up and running in one minute. Nice!

SOGo Groupware

Mailcow bundles the SOGo Groupware solution but it’s nothing I need. To get rid of it remove the sogo-mailcow definition from the docker-compose.yml file. But from now, dovecot won’t start anymore. The entrypoint script needs the sogo volume mounts. A look at the docker-entrypoint.sh shows that it populates only some sieve credentials to one file. I opened a pull request to make this optional and rebuilt the image myself.

docker-compose.yml adjustments

Mailcow’s compose file looks pretty good but it uses volume containers what I dislike. I prefer volume mounts to specify the path on the host system. Because I’ve an global reverse proxy I also kicked the nginx container. The last adjustment affects the service names. I.e. the mailcow-postfix service obtain mailcow_mailcow-postfix as container name because docker-compose adds the project name prefix.

Rainloop Webmail

I choose Rainloop as webmail client cause it looks simple and integrates a sive filter management. The setup is pretty straight forward but some points must be considered:

  • Every Domain must be set up in the admin tool
  • Use SSL for IMAP and SMTP
  • Use STARTTLS for Sieve

Send mails from the docker host system

Usually the host-system has its own postfix installation configured as mail relay but the port 25 is occupied by mailcow. Just comment the line starting with smtp inet ... in /etc/postfix/master.conf. After an restart postfix does not bind the port anymore but sendmail can still deliver mails.

DNS, DKIM, SPF

A proper DKIM and SPF setup needs correct DNS records.
Mailcow lets you generate DKIM Keys and uses dkim als selector.
The DNS records could look like:

@               IN TXT "v=spf1 a mx -all"
_dmarc          IN TXT "v=DMARC1; p=reject; rua=mailto:you@example.com"
dkim._domainkey IN TXT "v=DKIM1;k=rsa;t=s;s=email;p=MIGfMA0...DAQAB"

This defines that the SPF validation should accept if the sender IP matches the A or MX record and reject all others.

There are some tools you can use to check your setup like MX Toolbox

That’s it basically, if you didn’t it already, checkout Mailcow


Interesting posts

Nginx reverse proxy setup to host multiple applications using Docker
Installation and configuration of PsiTransfer
Freifunk Uplink VM mit Auftrennung der Netze über VLANs