Add Mailfiltering to the Falko howto Postfix Guide

Want to support HowtoForge? Become a subscriber!
 

Add Mailfiltering to the Falko howto Postfix Guide 

In this guide, you will learn how to get around some of the security policies that Postfix affords in favour of quickness and speed.

The Falko guide shows us how to get Virtual users working with Postfix/ Courier IMAP however it would be nice to offer per user mail filtering on email marked as spam by Spam Assasin for example to go into a SPAM folder for example.

This is no easy task like say using the local delivery agent in Postfix where you can make use of .forward files and .procmailrc/.mailfilter files dependant on your mailbox_command. The Falko guide uses the VDA (Virtual Delivery Agent), it gives security and speed but removes the expansion of the .forward files and doesn't use the mailbox_command. One method around this is to replace the Virtual_transport configuration option on Postfix with Maildrop however on any large scale system you might experience slowdown, the VDA is super super fast so lets leave it be and concentrate mail filtering on a per domain / per user basis instead using Maildrop

Firstly we need to recompile Maildrop to include virtual user support from MySQL databases (on a note nearly every other Linux distro apart Debian a MySQL version of Maildrop already exists):

# cd /usr/local/src
# apt-get src maildrop

# tar zxvf <tarballname>

# cd <dir>

# ./configure --enable-maildirquota --prefix=/usr/local/maildrop --enable-maildropmysql --with-mysqlconfig=/etc/maildropmysql.conf --enable-maildrop-uid=5000 --enable-maildrop-gid=5000 --enable-trusted-users="root postfix vmail" --enable-syslog=1
# make
# make install

Points to note 5000 UID/GID refers to the Falko guide, syslogging is essential as Maildrop is troublesome to get going. I am using a prefer of /usr/local/maildrop because I don't want this mucking around with my default Debian, it can be easily removed by a simply rm -rf command at any stage. Maildirquota needs to be enabled because the VDA will no longer be used for this domain, so Maildrop needs to be used to enforce the quota instead of the patched Postfix.

Next we need to change the Maildrop entry in /etc/postfix/master.cf

It would appear the Debian documentation is crap on Maildrop (anyone trying to do a Horde install will back me up on this one, some things are just not documented clearly) the Maildrop lines needs changes to read:

maildrop unix - n n - - pipe
flags=DRhu user=vmail argv=/usr/local/maildrop/bin/maildrop -d ${user}@${nexthop} ${extension} ${recipient} ${user} ${nexthop} ${sender}

Next we add the following into the /etc/postfix/main.cf file:

maildrop_destination_recipient_limit=1


At this point we need to restart postfix / reload postfix


# /etc/init.d/postfix reload

# /etc/init.d/postfix restart


Now time to configure Maildrop.


Create a file called /etc/maildroprc

#

LOGNAME=tolower("$LOGNAME")
EXTENSION="$1"
RECIPIENT=tolower("$2")
USER="$3"
HOST="$4"
SENDER="$5"
DEFAULT="/u0/vmail/$HOST/$USER/."

if ( "$EXTENSION" ne "" )
{
DELIMITER="+"
}

if (!$SENDER)
{
SENDER = ""
}

#
# Autocreate maildir, if not existant
#

`test -e /u0/vmail/$HOST`
if ( $RETURNCODE != 0 )
{
`mkdir /u0/vmail/$HOST`
}

`test -e /u0/vmail/$HOST/$USER`
if ( $RETURNCODE != 0 )
{
`/usr/local/maildrop/bin/maildirmake /u0/vmail/$HOST/$USER`
`chmod -R 0700 /u0/vmail/$HOST`
}

#
# Check that user has his own maildrop include,
# if not available, check if $DEFAULT is set
# (newer maildrop get's that from the DB and updates
# it) and deliver or fail temporarily if not available
#

`test -f /u0/vmail/.mailfilters/$LOGNAME`
if ( $RETURNCODE == 0 )
{
include "/u0/vmail/.mailfilters/$LOGNAME"
}
else
{
if ( "$DEFAULT" ne "" )
{
to "$DEFAULT"
}
else
{
EXITCODE=75
exit
}
}

Points to note your vmail directory will be different so you need to change this script and secondly this script makes the directories if they don't already exist. Unlike the VDA, Maildrop cannot make it's own directories without a little help!!

Configure Maildrop to get the Directory storage through MySQL:

Edit the following file /etc/maildropmysql.conf

hostname 127.0.0.1
port 3306
database mail
dbuser mail_admin
dbpw <password>
dbtable users

default_uidnumber 5000
default_gidnumber 5000

uid_field email
uidnumber_field uid
gidnumber_field gid
maildir_field maildir
homedirectory_field maildir
quota_field quota

mailstatus_field active

where_clause "where active = 'yes'"

Points to note: the active field and the "clause" can also be added to courier authlib stuff to allow you to still receive email for a user but not allow them to login. This is brilliant if a custom hasn't paid a bill and you simply want them to be turned off for a few hours whilst they sweat and go pay their bill, otherwise you have to delete the user from the virtual users mailbox and begin boucing mail which isn't the most elegant of solutions.

Next we need a slight modification to the original users table provided my the Falko guide:

CREATE TABLE users (
active enum('yes','no') NOT NULL default 'yes',
email varchar(80) NOT NULL default '',
`password` varchar(20) NOT NULL default '',
quota int(10) default '10485760',
maildir varchar(128) NOT NULL default '',
uid int(11) NOT NULL default '5000',
gid int(11) NOT NULL default '5000',
PRIMARY KEY (email)
) ENGINE=MyISAM DEFAULT;

added fields "active, uid, gid, maildir'.

UID/ GID can be left alone and take a default value of 5000/5000 when adding new users as does the active field. The only field that must be keyed in is the maildir field. Previously the Falko guide does a string concatonation to make up the maildir directory from email address, but Maildrop is so clever so we must specify. Once again none of this is neccessary for domains that will still continue to use the VDA instead of Maildrop.


Final we need to added a transport to force the mail away from the VDA to Maildrop (important to note you can do this on a purely per email basis ie, all emails but users@example.com go to the normal virtual transport and by adding in the email address and a maildrop transport it will be the only one that gets process in this manner:

INSERT INTO `transport` ( `domain` , `transport` )
VALUES (
'example.com', 'maildrop' );

Next we need a basic Mailfilter to test:

In my example mailfilters will be stored in the following location:

/u0/vmail/.mailfilter/user@domain.com


Below we have a very basic filter:

logfile "/u0/vmail/.mailfilters/mailfilter-log.txt"

if ( /^Subject: SPAM/)
{
log "------------------------------------------------------------- Spam general. "
to "/u0/vmail/example.com/user/.spam" # Make this "cc" for copy or "to" to not send it to Inbox.
}
else
{
to "/u0/vmail/example.com/user/."
}

This filter sends emails with the word spam to a folder called spam in the users inbox or else all the other mail goes unfiltered and arrives as normal in the main part of the users inbox. If all goes wrong look at the syslog (hence the reason for compiling in support for it as it will help to some degree in make head or tails of whats happening)

More to come...how to do maildrop quota as we have just lost the abilty for Postfix to manage it by using this fitler


Please do not use the comment function to ask for help! If you need help, please use our forum.
Comments will be published after administrator approval.
Submitted by khairilthegreat (registered user) on Sat, 2007-08-11 10:23.

Recently I jump to this tutorial and it works great, except it had some typo:

/u0/vmail/.mailfilter/user@domain.com

It should be

/u0/vmail/.mailfilters/user@domain.com

Submitted by rockwilda (registered user) on Fri, 2006-10-13 06:52.

Hello!

This is a verny nice howto, I've got the ability to filter my mails, but I need quota ...

"More to come...how to do maildrop quota as we have just lost the abilty for Postfix to manage it by using this fitler "

When is the howto planed?

 greetz, Nico

Submitted by herbie (registered user) on Fri, 2006-12-22 20:54.

    Dec 22 11:30:47 picard postfix/pipe[24543]: 41239BF40EE: to=<axle@****.com>, relay=maildrop, delay=0, status=bounced (permission denied. Command output: maildrop: maildir over quota. )

Quota messages still being sent to users & admin as well after I installed this. I also found the following mod of the user@domain.com filter to be a big hit:

logfile "/home/vmail/.mailfilters/mailfilter-log.txt"
                                                                                                                   
if ( /^Subject: ***SPAM/)
{
log "--junk for USERNAME to /dev/null----------------------------- Spam TOSSED. "
to "/dev/null" # Make this "cc" for copy or "to" to not send it to Inbox.
}
else
{
to "/home/vmail/qlynx.com/user/."
}

Throws mail marked as spam away. For testing the caps are handy, I'd: grep -c USERNAME mailfilter-log.txt and find it tossing 1,000s of spams a week for some users.
 

Submitted by todgerme (registered user) on Mon, 2006-12-25 13:58.

I think, they want the quota limits and custom quota messages stuff that maildrop can do via the master.cf in Postfix.  So little time to do this stuff!! 

Is it wise to throw away SPAM instead of moving it into a directory?  Surely you'd want to use sa-learn on it and mark the ocassional message as ham?

Submitted by todgerme (registered user) on Sun, 2006-12-10 13:24.
Let me see if Santa can't do something before christmas!  No promises though!!!
Submitted by rockwilda (registered user) on Wed, 2006-10-11 18:48.