Using Procmail to filter mail with Cyrus and Postfix
13 November 2003
With Mac OS X Server 10.3, Apple finally jettisoned its limited “Apple Mail Service” and adopted two excellent Open Source alternatives: Postfix for the mail transport, and Cyrus IMAP for the mail storage/database. In this article, I will show how you can migrate your old Procmail recipes from when you used UW IMAP and use them with the new mail system in Mac OS X Server 10.3.
CAVEAT: As with any mission-critical operation, you should backup your mail prior to following the steps in this article. We explicitly disclaim any responsibility for the loss of e-mail—the steps outlined in this article have only been tested on our existing test and production servers, and your setup may be wildly different.
What is Procmail?
VIrtually all modern e-mail programs include some function to let you sort your e-mail, usually based on simple string matches. Procmail is a mail processing system that takes the simplistic functions present in e-mail programs and turns them into a powerful, flexible e-mail processing language. Procmail can quickly and efficiently sort e-mail into folders; but it can also automatically forward mail; save messages to files; process commands embedded in messages; and perform sophisticated anti-spam filtering. An excellent example of the last function is the SpamBouncer, which is quite possibly the most complex procmail setup I have ever seen.
Procmail is organized around “recipes;” each recipe handles the destination of a message. At its simplest, a recipe checks to see if some criteria are met, and then takes action. For example, the following recipe will file all messages addressed to “feedback@afp548.com” in the folder “feedback":
:0: * ^TO.*feedback@afp548.com feedback
Procmail works natively with UNIX 'mbox' style mailboxes, and works extremely well with Postfix in conjunction with the UW IMAP server. As Apple have brought Postfix and the Cyrus IMAP server into the mix in Mac OS X Server 10.3, we will have to do some work to make Procmail work. Luckily, the amount of work involved isn’t unbearable.
An unfortunate note
The bad news here is that Apple ships Mac OS X Server 10.3’s Server Admin application with the assumption that users will never attempt to enhance or expand the default mail setup. If you make any changes in the Mail module’s settings and click Save, Apple will overwrite critical portions of the Postfix configuration file and you will lose your access to Procmail. While we hope that Apple will eventually switch from this practice, until then you will need to configure Mail using command line tools. Check out our other articles on Postfix for more tips and tricks; look for other articles on Postfix, Cyrus and e-mail under Mac OS X Server 10.3 in future.
Configuring Postfix
Once you’ve set up the basic mail environment using Server Admin, log in to the Server via the command line and assume super-user permissions. Change to the /etc directory and add the following line to imapd.conf:
reject8bit: no
Although this step is not strictly necessary, it will help make handling mail encoded beyond simple ASCII easier. Next, change to the /etc/postfix directory. This is where Postfix' control files are located. We will need to edit both main.cf, the master configuration file, and master.cf, the transports configuration file.
First, we’re going to add a new transport description to master.cf. Add the following two lines to the end of the file; note that the second line is inset a couple of spaces, and while it wraps in the browser, it should not wrap in the file:
procmail unix - n n - - pipe
flags=R user=cyrus argv=/usr/bin/procmail -t -m USER=${user} EXTENSION=${extension} /etc/procmailrc
In essence, this line sets up a new transport for Postfix to use to deliver mail. It invokes the Procmail binary, passing on the e-mail user ID and e-mail address extension to Procmail for handling by the recipies. Procmail is told to use a master configuration file that will live at /etc/procmailrc.
Next, we’ll add two lines to the end of main.cf:
mailbox_command = /usr/bin/procmail -t -a “$EXTENSION" mailbox_transport = procmail
The main.cf file itself has descriptions of what both commands do; in short, you’re telling Postfix to use Procmail as the local message delivery system. Be sure to comment out Apple’s mailbox_transport=cyrus line.
Configuring Procmail
At this point, Postfix is ready to start handing off every incoming message to Procmail for processing (the messages will have passed any anti-spam and valid user tests already set up in Postfix). Now we need to setup Procmail to interact with Cyrus IMAP. To do this, we’ll set up a master Procmail recipe file, at /etc/procmailrc:
### # # Master Procmail Recipe for Postfix > Procmail > Cyrus # ### DELIVERTO="/usr/bin/cyrus/bin/deliver" USERINBOX="$DELIVERTO -e -a $USER -m user/$USER" # # OPTIONAL: Include users' own .procmail recipe files # INCLUDERC=/Users/$USER/.procmailrc #
# Last but not least, deliver mail that falls through to the user’s INBOX # :0 w | $USERINBOX
We set two variables in this file. The first, DELIVERTO, is just a convenience and is a pointer to the Cyrus deliver program. That program handles the process of adding a mail message to the appropriate mailbox. The second variable, USERINBOX, will deliver a message handed to it to the user’s INBOX. Cyrus mailboxes are normally expressed as “user.username.mailboxname” but Apple has turned the UNIX-style delimiter on so we have to use slashes. Cyrus treats the mailbox “user/username” as the user’s INBOX, rather than the UW IMAP way of storing the INBOX in /var/mail/username.
If you have power-users on your system, chances are they will appreciate the chance to use Procmail to filter their e-mail. The INCLUDERC line generalizes the user’s Procmail recipe file to one called “.procmailrc” (the leading period is significant) that is stored in the directory /Users/username on the root drive. In one sense, this breaks the “black-box” nature of Cyrus—which is designed to handle e-mail for users who do not necessarily have a local home folder—but your users will appreciate the deep power of Procmail. Obviously, if your users are scattered around your system, you will need to make the INCLUDERC line more complex; refer to Procmail’s manpage for more information (man procmail, man procmailrc, man procmailex are your friends).
Last but not least, we have a fallback recipe that will deliver any mail that didn’t get otherwise filtered to the user’s INBOX.
All set to go
At this point, we’re all set to go. All you need to do is restart Postfix with the “postfix reload” command (run as root, in /etc/postfix) and mail will be processed by Postfix > Procmail > Cyrus!
A word of caution—Procmail cannot create new mailboxes within Cyrus, so be sure to create any mailboxes you want Procmail to use as a destination before enabling recipes to deliver there. Your e-mail application should be able to handle that for you.