Chapter 7. Utilities

Table of Contents

7.1. Maildrop
7.1.1. Per user filtering
7.2. Vacation
7.3. Webmail

7.1. Maildrop

Postfix has a built in local delivery agent, but to provide quota support and moving messages marked as spam into separate folders we are going to replace it with Maildrop.

To install maildrop, run

apt-get install maildrop

Maildrop config file is located at /etc/maildroprc, open it and replace the content with this:

# Global maildrop filter file (used on Debian)
# For use with Postfix/Courier IMAP/Amavisd-new virtual mailbox domains.
#
# This maildroprc automagically creates a Spam folder for the recipient
# and places spam there. It also subscibes the recipient to the folder.
#
# Example maildir: /home/vmail/example.com/user/
#
# Also in main.cf:
# virtual_transport = maildrop
# maildrop_destination_concurrency_limit = 2
# maildrop_destination_recipient_limit = 1
#
# and in master.cf:
#
# maildrop  unix  -       n       n       -       -       pipe
#  flags=DRhu user=vmail:vmail argv=/usr/bin/maildrop -w 90 -d ${user}@${nexthop}
#  ${extension} ${recipient} ${user} ${nexthop}
#
# /var/log/maildroprc.log needs to exist and owned by vmail:vmail and
# a logrotate script needs to be created.
#
HOME_DIR="/home/vmail"
logfile "/var/log/maildroprc.log"
EXTENSION="$1"
RECIPIENT=tolower("$2")
USER="$3"
HOST="$4"
SENDER="$5"
DEFAULT="$HOME_DIR/$HOST/$USER"
 
# Check if host and user directory exist
 
`test -e $HOME_DIR/$HOST/$USER`
#log "Testing for $HOME_DIR/$HOST subdirectory: result=$RETURNCODE"
# Only continue if directory does NOT exist
if ($RETURNCODE != 0)
{
        log "MailDir $HOME_DIR/$HOST/$USER does NOT exist"
        `test -e $HOME_DIR/$HOST`
        if ( $RETURNCODE != 0 )
        {
                log "Creating $HOME_DIR/$HOST"
                `mkdir $HOME_DIR/$HOST`
                `chmod -R 0700 $HOME_DIR/$HOST`
        }
 
        # Create users MailDir
        `maildirmake $HOME_DIR/$HOST/$USER`
}
 
if (/^X-Spam-Flag: YES/)
{
        EXTENSION = "Junk"
 
        # See if the spam directory already exists
        `test -e $HOME_DIR/$HOST/$USER/.$EXTENSION`
        #log "Testing for $EXTENSION subdirectory: result=$RETURNCODE"
        if ( $RETURNCODE != 0 ) # spam directory does not exist - so we create it
        {
                # Create the subdirectory
                `maildirmake -f $EXTENSION $HOME_DIR/$HOST/$USER`
                log "Ran \"maildirmake -f $EXTENSION $HOME_DIR/$HOST/$USER\""
 
                # Auto-subscribe the subdirectory
                `if ! grep -q INBOX.$EXTENSION $HOME_DIR/$HOST/$USER/courierimapsubscribed; then echo INBOX.$EXTENSION >> $HOME_DIR/$HOST/$USER/courierimapsubscribed; fi`
        }
 
        # Deliver the message to the mailbox
        exception {
                # for those who unsubscribed themselves - subscribe them
                `if ! grep -q INBOX.$EXTENSION $HOME_DIR/$HOST/$USER/courierimapsubscribed; then echo INBOX.$EXTENSION >> $HOME_DIR/$HOST/$USER/courierimapsubscribed; fi`
                to "$HOME_DIR/$HOST/$USER/.$EXTENSION"
        }
}

This script does two things:

  • Creates the folders for the users mail on the server if they do not exist (this is the part that Postfix virtual delivery agent does automatically).

  • Checks if the messages has the X-Spam-Flag: YES header and delivers the message to the Junk folder (it creates one if it doesn't exist).

We also need to create a log file and change its permission.

touch /var/log/maildroprc.log
chown vmail:vmail /var/log/maildroprc.log

To automatically rotate logs for the maildroprc.log file create /etc/logrotate.d/maildroprc with the following content:

/var/log/maildroprc.log {
    rotate 7
    daily
    compress
    delaycompress
    copytruncate
    notifempty
}

To tell Postfix to use Maildrop as a local delivery agent edit /etc/postfix/main.cf and add

virtual_transport = maildrop
maildrop_destination_concurrency_limit = 2
maildrop_destination_recipient_limit = 1
[Important]Important

You already have virtual_transport = virtual, you have to replace this line and change virtual to maildrop.

Edit /etc/postfix/master.cf and replace

maildrop  unix  -       n       n       -       -       pipe
  flags=DRhu user=vmail argv=/usr/bin/maildrop -d ${recipient}

with

maildrop  unix  -       n       n       -       -       pipe
  flags=ODRhu user=vmail:vmail argv=/usr/bin/maildrop -w 90 -d ${user}@${nexthop}
  ${extension} ${recipient} ${user} ${nexthop}

As you can see we are invoking maildrop as user:group “vmail:vmail”. Maildrop on Debian is compiled against the courier-authlib library which need access to the /var/run/courier/authdaemon folder. Debian package sets user/group permission to daemon:daemon on this folder. To force maildrop to work when invoked as vmail:vmail we need to change the group ownership of this folder to vmail.

chgrp vmail /var/run/courier/authdaemon

As you can see we are invoking maildrop with two parameters. -w 90 tells maildrop to copy the quota warning message if the user is over 90% of his mailbox quota.

The quota warning message must be located in /etc/quotawarnmsg and it should look something like this:

X-Comment: Rename/Copy this file to quotawarnmsg, and make appropriate changes
X-Comment: See deliverquota man page for more information
From: Mail Delivery System <postmaster@example.com>
Reply-To: postmaster@example.com
To: Valued Customer:;
Subject: Mail quota warning
Mime-Version: 1.0
Content-Type: text/plain; charset=iso-8859-1
Content-Transfer-Encoding: 7bit

Your mailbox on the server is now more than 90% full. So that you can continue to receive mail you need to remove some messages from your mailbox

Unfortunately Postfix Admin does not allow entering quota values, but id does create the needed columns in the database table mbox. To enter quota values log into mysql and add the quota value for the mailbox you wish to have quota applied. Your mailbox should have something like this:

mysql> select * from mailbox;
+-----------------+----------+-------------+--------------------+-----------+------------+--------------+---------------------+---------------------+--------+
| username        | password | name        | maildir            | quota     | local_part | domain       | created             | modified            | active |
+-----------------+----------+-------------+--------------------+-----------+------------+--------------+---------------------+---------------------+--------+
| gog@example.com | ommited  | Goran Juric | example.com/gog    | 100000000 | gog        | example.com  | 2009-04-14 00:53:38 | 2009-04-14 00:53:38 |      1 |

Maildrop will get quota information using Couriers /etc/courier/authmysqlrc settings we set earlier. That is the reason why we have added MYSQL_QUOTA_FIELD concat(quota,'S') in authmysqlrc.

Change the permissions on /var/lib/amavis/tmp

chmod -R 775 /var/lib/amavis/tmp

We also need to restart Amavisd-new and Postfix.

/etc/init.d/amavis restart
/etc/init.d/postfix restart

Send a test email to check that everything is working and commit your changes with etckeeper.

[Tip]Tip

Examine /var/log/maildroprc.log and /var/log/mail.info if you are expiriencing problems.

7.1.1. Per user filtering

If you would like to have the ability to provide per user filtering you will have to modify /etc/maildroprc to check if there is a “mailfilter” file in the users directory and if it's found that it gets included.

You can change it like this

[....]
        # Create users MailDir
        `maildirmake $HOME_DIR/$HOST/$USER`
}
 
`test -e $DEFAULT/mailfilter`
if ( $RETURNCODE == 0 )
{
     exception {
         log "Including $HOME_DIR/$HOST/$USER/mailfilter..."
         include "$HOME_DIR/$HOST/$USER/mailfilter"
     }
}
 
if (/^X-Spam-Flag: YES/)
[...]

All you have to do now is to put your rules in the mailfilter file.