From 2f9f6b10020615846e76c16272abbdcc2452623b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andr=C3=A9=20Stein?= Date: Thu, 28 Apr 2016 08:57:50 +0200 Subject: [PATCH] Implement basic sieve support using Dovecot. The dovecot-sieve plugin is installed and configured to apply sieve as soon as a .dovecot.sieve file is encountered in the virtual user's home directory (that is /var/mail/${domain}/${username}/.dovecot.sieve). Transport has been changed in the postfix configuration to use Dovecot LDA (see http://wiki.dovecot.org/LDA/Postfix) to actually enable sieve filtering. Tests have been added. --- Dockerfile | 3 ++- Makefile | 5 +++++ README.md | 1 + target/postfix/main.cf | 2 ++ target/postfix/master.cf | 8 +++++++- test/config/sieve/dovecot.sieve | 8 ++++++++ test/email-templates/sieve-spam-folder.txt | 12 ++++++++++++ test/tests.bats | 14 ++++++++++++-- 8 files changed, 49 insertions(+), 4 deletions(-) create mode 100644 test/config/sieve/dovecot.sieve create mode 100644 test/email-templates/sieve-spam-folder.txt diff --git a/Dockerfile b/Dockerfile index c8181fdb..74a9fdf0 100644 --- a/Dockerfile +++ b/Dockerfile @@ -5,7 +5,7 @@ MAINTAINER Thomas VIAL RUN DEBIAN_FRONTEND=noninteractive apt-get update -q --fix-missing && \ apt-get -y upgrade && \ apt-get -y install --no-install-recommends \ - postfix dovecot-core dovecot-imapd dovecot-pop3d gamin amavisd-new spamassassin razor pyzor \ + postfix dovecot-core dovecot-imapd dovecot-pop3d dovecot-sieve gamin amavisd-new spamassassin razor pyzor \ clamav clamav-daemon libnet-dns-perl libmail-spf-perl bzip2 file gzip p7zip unzip arj rsyslog \ opendkim opendkim-tools opendmarc curl fail2ban ed iptables && \ curl -sk http://neuro.debian.net/lists/trusty.de-m.libre > /etc/apt/sources.list.d/neurodebian.sources.list && \ @@ -16,6 +16,7 @@ RUN DEBIAN_FRONTEND=noninteractive apt-get update -q --fix-missing && \ # Configures Dovecot RUN sed -i -e 's/include_try \/usr\/share\/dovecot\/protocols\.d/include_try \/etc\/dovecot\/protocols\.d/g' /etc/dovecot/dovecot.conf +RUN sed -i -e 's/#mail_plugins = \$mail_plugins/mail_plugins = \$mail_plugins sieve/g' /etc/dovecot/conf.d/15-lda.conf ADD target/dovecot/auth-passwdfile.inc /etc/dovecot/conf.d/ ADD target/dovecot/10-*.conf /etc/dovecot/conf.d/ diff --git a/Makefile b/Makefile index a9bdd4cf..f0b50cd5 100644 --- a/Makefile +++ b/Makefile @@ -49,12 +49,17 @@ run: sleep 20 fixtures: + # Setup sieve & create filtering folder (INBOX/spam) + docker cp "`pwd`/test/config/sieve/dovecot.sieve" mail:/var/mail/localhost.localdomain/user1/.dovecot.sieve + docker exec mail /bin/sh -c "maildirmake.dovecot /var/mail/localhost.localdomain/user1/.INBOX.spam" + docker exec mail /bin/sh -c "chown 5000:5000 -R /var/mail/localhost.localdomain/user1/.INBOX.spam" # Sending test mails docker exec mail /bin/sh -c "nc 0.0.0.0 25 < /tmp/docker-mailserver-test/email-templates/amavis-spam.txt" docker exec mail /bin/sh -c "nc 0.0.0.0 25 < /tmp/docker-mailserver-test/email-templates/amavis-virus.txt" docker exec mail /bin/sh -c "nc 0.0.0.0 25 < /tmp/docker-mailserver-test/email-templates/existing-alias-external.txt" docker exec mail /bin/sh -c "nc 0.0.0.0 25 < /tmp/docker-mailserver-test/email-templates/existing-alias-local.txt" docker exec mail /bin/sh -c "nc 0.0.0.0 25 < /tmp/docker-mailserver-test/email-templates/existing-user.txt" + docker exec mail /bin/sh -c "nc 0.0.0.0 25 < /tmp/docker-mailserver-test/email-templates/sieve-spam-folder.txt" docker exec mail /bin/sh -c "nc 0.0.0.0 25 < /tmp/docker-mailserver-test/email-templates/non-existing-user.txt" # Wait for mails to be analyzed sleep 10 diff --git a/README.md b/README.md index 96e8aab9..da361009 100644 --- a/README.md +++ b/README.md @@ -22,6 +22,7 @@ Includes: - opendkim - opendmarc - fail2ban +- basic sieve support using dovecot - [LetsEncrypt](https://letsencrypt.org/) and self-signed certificates - [integration tests](https://travis-ci.org/tomav/docker-mailserver) - [automated builds on docker hub](https://hub.docker.com/r/tvial/docker-mailserver/) diff --git a/target/postfix/main.cf b/target/postfix/main.cf index b1b65acf..630fea79 100644 --- a/target/postfix/main.cf +++ b/target/postfix/main.cf @@ -61,6 +61,8 @@ virtual_mailbox_maps = hash:/etc/postfix/vmailbox virtual_alias_maps = hash:/etc/postfix/virtual virtual_uid_maps = static:5000 virtual_gid_maps = static:5000 +# Enable Dovecot Sieve +virtual_transport = dovecot # Additional option for filtering content_filter = smtp-amavis:[127.0.0.1]:10024 diff --git a/target/postfix/master.cf b/target/postfix/master.cf index a8078d5b..659a5237 100644 --- a/target/postfix/master.cf +++ b/target/postfix/master.cf @@ -63,9 +63,15 @@ mailman unix - n n - - pipe flags=FR user=list argv=/usr/lib/mailman/bin/postfix-to-mailman.py ${nexthop} ${user} +# +# Dovecot LDA configuration +# + +dovecot unix - n n - - pipe + flags=DRhu user=docker argv=/usr/lib/dovecot/deliver -f ${sender} -d ${user}@${nexthop} -m ${extension} # -# Amavis configuraiton +# Amavis configuration # smtp-amavis unix - - - - 2 smtp diff --git a/test/config/sieve/dovecot.sieve b/test/config/sieve/dovecot.sieve new file mode 100644 index 00000000..cce44e99 --- /dev/null +++ b/test/config/sieve/dovecot.sieve @@ -0,0 +1,8 @@ +require ["fileinto", "reject"]; + +if address :contains ["From"] "spam@spam.com" { + fileinto "INBOX.spam"; +} else { + keep; +} + diff --git a/test/email-templates/sieve-spam-folder.txt b/test/email-templates/sieve-spam-folder.txt new file mode 100644 index 00000000..4f904fdd --- /dev/null +++ b/test/email-templates/sieve-spam-folder.txt @@ -0,0 +1,12 @@ +HELO mail.external.tld +MAIL FROM: user@external.tld +RCPT TO: user1@localhost.localdomain +DATA +From: Spambot +To: Existing Local User +Date: Sat, 22 May 2010 07:43:25 -0400 +Subject: Test Message +This is a test mail. + +. +QUIT diff --git a/test/tests.bats b/test/tests.bats index 86e78aa2..58ea96ac 100644 --- a/test/tests.bats +++ b/test/tests.bats @@ -129,9 +129,9 @@ } @test "checking smtp: delivers mail to existing account" { - run docker exec mail /bin/sh -c "grep 'status=sent (delivered to maildir)' /var/log/mail/mail.log | wc -l" + run docker exec mail /bin/sh -c "grep 'status=sent (delivered via dovecot service)' /var/log/mail/mail.log | wc -l" [ "$status" -eq 0 ] - [ "$output" -eq 2 ] + [ "$output" -eq 3 ] } @test "checking smtp: delivers mail to existing alias" { @@ -409,3 +409,13 @@ [ "$status" -eq 0 ] [ "$output" = "my-domain.com" ] } + +# +# sieve +# + +@test "checking sieve: user1 should have received 1 in folder INBOX.spam" { + run docker exec mail /bin/sh -c "ls -A /var/mail/localhost.localdomain/user1/.INBOX.spam/new | wc -l" + [ "$status" -eq 0 ] + [ "$output" = 1 ] +}