≡ Menu

Using Procmail with Plesk

For many years now, I’ve been maintaining a separate mail server, web server, and shell server. I’m getting busy these days, and just don’t have the time to dedicate to this maintenance. About a year and a half ago, I purchased a 30-domain Plesk license, which I am using for all the sites I host for friends and family, but I haven’t cut my own sites over to it yet. I’m finally getting to the point where I want to stop having to worry about all the VM’s, and thinking about moving my sites and e-mail over to Plesk. The one big downside for me is that Plesk, by default, does not support server-side mail sorting or filtering. I am on about 50 different mailing lists, etc, and really don’t want to have to deal with sorting out that e-mail by hand. So, I did a bit of searching, and found that there are ways of getting Plesk to use Procmail – here are a few blog posts that discuss the subject:

http://www.russwittmann.com/2007/07/14/server-side-mail-filtering-using-qmailprocmail-under-plesk/
http://rackerhacker.com/2007/11/27/sort-e-mail-in-plesk-with-procmail/

In my case, I am not using Plesk’s built-in spam filtering (instead, I’m fronting it with Maia Mailguard – if you are curious on how to get that working, comment, and I’ll write a post on it someday), so the spam part of this really doesn’t apply for me.. but the posts do describe how to get procmail working. The one big downside is that it isn’t done automatically — any time the account is updated via Plesk, the .qmail file will be overwritten, and you will need to edit it by hand to get things working again. One of the posts suggests making it immutable, but, well, that’s a pain in the rear too. ;)

I wrote a quick script that will run through this setup for you, and then set up Plesk’s event handlers to call this script after an account is created or updated. My system is Plesk 9.0.0 on Debian 64-bit, using Postfix as the MTA — even though it’s Postfix, Plesk calls a virtual mail delivery agent that still uses the .qmail files. If you are interested in how this works, read more!

Without further ado, here is the script that I am using to auto-update the .qmail and .procmailrc files. Save this as /usr/local/sbin/add-procmail-rules.pl, and then read through the comments and make any updates that are needed.

### — start of add-procmail-rules.pl ###
#!/usr/bin/perl -w
#
# Plesk event handler script to use procmail for mail delivery instead of
# Plesk’s default mail handler.
#
# By Nate Carlson
# http://www.natecarlson.com
use strict;
#
# Basic configuration, in case Parallels changes where Plesk stores stuff.
my($topdir) = “/var/qmail/mailnames”;
my($qmailcfg) = “.qmail”;
my($procmailcfg) = “.procmailrc”;
my($maildir) = “Maildir”;
#
# First, sleep for 5 seconds to make sure that Plesk has finished writing
# out it’s configuration to the .qmail file
sleep(5);
#
# Grab the e-mail address from Plesk’s NEW_MAILNAME variable, and split
# it into user/domain parts.
my($emailaddress) = $ENV{‘NEW_MAILNAME’};
my($user,$domain) = split(/\@/, $emailaddress, 2);
#
# Verify that we were able to split NEW_MAILNAME into user/domain parts;
# die if not.
if(!$user || !$domain) {
print “NEW_MAILNAME was not valid!\n”;
exit 1;
}
#
# Set the user directory; die if it does not exist.
my($userdir) = “$topdir/$domain/$user”;
if ( ! -d “$userdir”) {
print “User directory $userdir does not exist.”;
exit 1;
}
#
# Make sure the qmail cfg file exists
if (! -f “$userdir/$qmailcfg”) {
print “User does not have a dot-qmail file; exiting.”;
exit 1;
}
#
# Read in old qmail cfg file
open(OLDQMAILCFG, “<$userdir/$qmailcfg"); my(@oldqmailcfg) = ;
close(OLDQMAILCFG);
#
# Rename the old file for a backup copy
rename “$userdir/$qmailcfg”, “$userdir/$qmailcfg.old”;
#
# Write out our custom .qmail file, only changing the deliverquota line
# to procmail.
open(QMAILCFG, “>$userdir/$qmailcfg”);
#
my($oldline);
foreach $oldline (@oldqmailcfg) {
chomp($oldline);
if ($oldline =~ /deliverquota/) {
print QMAILCFG “| /usr/bin/procmail -m -o .procmailrc\n”;
} else {
print QMAILCFG “$oldline\n”;
}
}
close(QMAILCFG);
#
# If the procmail file does not already exist, write out a totally base
# config file. If you want to move tagged spam to a different folder,
# you will need to update this. If it already exists, leave it alone.
if (! -f “$userdir/$procmailcfg”) {
open(PROCMAILCFG, “>$userdir/$procmailcfg”);
print PROCMAILCFG “MAILDIR=$userdir/$maildir\n”;
print PROCMAILCFG ‘DEFAULT=${MAILDIR}/’ . “\n”;
close(PROCMAILCFG);
}
#
# Get the right ownership of these files
system(“chown popuser:popuser $userdir/$qmailcfg $userdir/$qmailcfg.old $userdir/$procmailcfg”);

2009/01/08 Update: The previous version of this script blew away whatever was in the file, which broke Plesk’s spam filtering and mail redirection features. I’ve changed the script above to a new version which directly replaces the local delivery agent with procmail, but leaves the rest of the .qmail file alone. This should be better.

So basically drop that script on your filesystem somewhere (I use /usr/local/sbin/add-procmail-rules.pl), make it executable, then register the event with Plesk – to do that..

  1. Log into Plesk as admin, go to Main->Logs & Statistics->Event Manager
  2. Click ‘Add New Event Handler’; you will need to create an event with an event type of ‘Mail account created’, priority set as desired, ‘User’ is root (or another user with proper perms), and ‘Command’ is the script that you created above – in my case, /usr/local/sbin/add-procmail-rules.pl.
  3. Repeat the step above, but substitute ‘Mail account created’ with ‘Mail account updated’.

You will need to force an update of any mail accounts whenever Plesk is upgraded – I do this manually right now, but it’d be really helpful to figure out a way to automate it. ;)

Note that I am not accounting for people who want their end users to be able to update their .procmailrc files — this article assumes that the root user will be the one making updates. In my case, this works fine; however, at some point, I will probably investigate setting up Plesk’s hacked-up version of Ingo to update the .procmailrc files for individual users. That way, users could define filters via IMP Webmail, and have them automatically applied on the server side.

Update: I figured out how to make this work with Ingo. Check out my next post here.

If you have any questions or comments, or find this useful, please leave me a comment below!

{ 10 comments… add one }
  • Jens Jacobsen April 13, 2009, 2:16 pm

    So I am curious about your Maia Mailguard setup in front of your plesk system. I’m using Plesk 9 on Ubuntu 8.04 LTS.

  • Jens Jacobsen April 13, 2009, 5:21 pm

    I just tried to get the automatic .procmailrc creation up and running. I added the Evenhandlers for E-Mail account creation and update but it seems I can’t get it to work. If I run the perl script directly from the commandline I get the following error:

    syntax error at /usr/local/sbin/add-procmail-rules.pl line 56, near “= ;”
    Execution of /usr/local/sbin/add-procmail-rules.pl aborted due to compilation errors.

    I’ve already fixed several bugs with the “, ”, ‘ and ’ signs which actually should be ” and ‘, but I can’t get the perl file to just run. Is there a way to find out wether plesk is running the handlers by adding a log entry to /var/log/messages?

    I’m hoping for some help, as I’m not familiar with perl :)

  • Jens Jacobsen April 14, 2009, 1:43 pm

    Nevermind, found the missing <OLDQMAILCFG> in the html code :)

  • nc April 14, 2009, 9:48 pm

    Glad to hear you got it working! ;)

    I will add a note to self to post the code as actual downloadable files versus cut/paste in Wordpress, which should resolve this issue – I always forget how badly Wordpress munges up code. ;(

  • lukas June 19, 2009, 6:33 am

    That’s a great script, thanks!

    What it’s missing is the removal of the procmail line in .qmail if the Mailbox gets disabled (forward only).

    I changed the appropriate part of the script to the following:

    […]
    my($oldline);
    foreach $oldline (@oldqmailcfg) {
    chomp($oldline);
    if ($oldline =~ /procmail/) {
    # Do nothing
    } elsif ($oldline =~ /deliverquota/) {
    print QMAILCFG “| /usr/bin/procmail -m -o .procmailrc\n”;
    } else {
    print QMAILCFG “$oldline\n”;
    }
    }
    […]

  • lukas June 19, 2009, 7:41 am

    hmm…
    the above script is not better. it deletes the procmail entry of .qmail when changing aliases. sorry.

  • lukas June 19, 2009, 8:50 am

    Now it works as it should. It additionally checks if the Mailbox got disabled. And I replaced the default .procmailrc entry with one that reflects the quota system:


    [...]
    # Write out our custom .qmail file, only changing the deliverquota line
    # to procmail.
    open(QMAILCFG, ">$userdir/$qmailcfg");
    my($newmailbox) = $ENV{'NEW_MAILBOX'};
    my($oldline);
    foreach $oldline (@oldqmailcfg) {
    chomp($oldline);
    if (($oldline =~ /procmail/) && ($newmailbox eq "false")) {
    ### purge this line
    } elsif ($oldline =~ /deliverquota/) {
    print QMAILCFG "| /usr/bin/procmail -m -o .procmailrc\n";
    } else {
    print QMAILCFG "$oldline\n";
    }
    }
    close(QMAILCFG);

    # If the procmail file does not already exist, write out a totally base
    # config file. If you want to move tagged spam to a different folder,
    # you will need to update this. If it already exists, leave it alone.
    if (! -f "$userdir/$procmailcfg") {
    open(PROCMAILCFG, ">$userdir/$procmailcfg");
    print PROCMAILCFG "MAILDIR=$userdir/$maildir\n";
    print PROCMAILCFG "\n";
    print PROCMAILCFG ':0 E' . "\n";
    print PROCMAILCFG '| /usr/bin/deliverquota $MAILDIR' . "\n";
    close(PROCMAILCFG);
    }

    [...]

    regards
    Lukas.

  • Joerg April 5, 2010, 12:58 pm

    Hi,
    currently setting up my new PLESK server (upgrading from v8) and found this very nice script! I´m not familar to Plesk’s eventhandler so it would be perfect if someone could tell me how to register this script with plesk?

    Thanks in advance!

    Regards,

    Joerg

Leave a Comment