Hacking together procmail mail filtering on a shared host

The first thing we did was establish what access we did have, in this case a shell on the machine (jailshell), physical access to the Maildir, and access to a batch job scheduler (cron). This is enough to hack together a rudimentary mail filtering system, albeit with a few drawbacks.

The first thing I did was create a temporary mailstore. There is no reason why this actually needs to reside in the Maildir tree, but I like to be sure that should anything go pearshaped I will still be able to read incoming mail.

maildirmake mail/psych0tik.net/richo/.xxToProcess

And subscribed myself to it (this will make clients who login to my IMAP store pull down this folder automatically)

echo xxToProcess >> mail/psych0tik.net/richo/subcriptions

With this in place, I could now begin writing the actual filtering scripts. The first is the simplest, it simply looks through my inbox for any mail it hasn’t already seen, and moves it to the holding pen (xxTmp)

#!/bin/sh

MAILDIR=~/mail/psych0tik.net/richo
TOPROCESS=~/mail/psych0tik.net/richo/.xxToProcess/cur

for i in `find ${MAILDIR}/cur -type f`; do
        if grep "X-Richo-Procmail: Yes" $i > /dev/null; then
                # We've seen this mail, do nothing
                echo -n ''
        else
                # New mail- move to the queue for procmail handling
                mv $i $TOPROCESS
        fi
done

I set this script to run once per minute as it’s quite cheap, and it will annoy me to have a lot of mail floating about (as a load test I subscribed to a few high traffic lists, the performance is quite good).

The second script runs less often (every 10 mins in this case) and goes through the holding pen, passing each message through procmail like in a conventional setup where you can alter the MTA config, and directs mail appropriately, with the extra caveat that it adds a header to each message, so that the initial script won’t look at it again.

#!/bin/sh

MAILDIR=~/mail/psych0tik.net/richo
TOPROCESS=~/mail/psych0tik.net/richo/.xxToProcess

for i in `find ${TOPROCESS}/cur -type f`; do
        procmail -m ~/.procmailrc.richo < $i && rm $i

done

Bear in mind that this means all mail will spend at most 60 seconds in your inbox, but if you have new mail notifications and active list subscriptions, your computer will probably go a bit mental. Also, keeping your inbox pruned is advisable to reduce the load on the first script to avoid upsetting your hosting provider. These scripts can be very easily ported to be more parameterised so that they can be shared by multiple users on the server, however in this case I assumed that the other users may want to tweak a few things, and so splitting them out was a better solution.

Questions comments hit me up below and I’ll do my best to follow up

~richo

About richo

I enjoy exploring interesting concepts in weird languages. I also like hacking on all of the things.
This entry was posted in Guides and tagged , , , , , . Bookmark the permalink.

Leave a Reply

Your email address will not be published. Required fields are marked *

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>