Navigation:

Search



Our Friends

Articles Using Procmail
 

Using Procmail

How to use the Procmail mail delivery agent to filter your incoming mail intelligently.

This was written by Moshe Jacobson and given on Sat Dec 01 2001.

Table of Contents


1. Concepts
1.1. What is Procmail?

Procmail is a utility that allows you to filter your incoming mail according to pretty much any parameters you choose. In its most simple usage, it filters based on pattern matching. A procmail "recipe" is basically a set of regular expressions that should or should not be matched in an incoming email, along with a folder to place the email into if it is matched.

Some people (like me) have multiple email addresses that are all handled by the same server, and they want to keep the emails separate from each other for one reason or another. Procmail will allow you to filter into different inboxes based on which address an email was sent to.

1.2. What are Procmail's capabilities?

Procmail can filter mail using several methods:

  • Pattern matching against a fixed regular expression
  • Negating a pattern match
  • Piping the email to a command and taking its exit status
    (If the command exits with a failure exit code, the recipe conditions are not satisfied)
  • Checking the length of the email

Procmail can take one of three actions with the text of an email once it has determined the email to match the recipe specification:

  • Append the text to a file
  • Feed the text to the standard input of another program
  • Forward the email to another address
  • Process the text of the email using an external program
    The modified text will now be considered as if it were the original email, and Procmail will continue to test this text against the rest of the recipies.

The first three rules are delivering recipies , whereas the latter is a non-delivering recipe . Non-delivering recipies are useful for modifying the content of an incoming email before it's delivered.

2. Basic Configuration
2.1. Setting up your .procmailrc

The file that will contain all your procmail recipes is ~/.procmailrc . Most systems are already configured with sendmail or another MTA that is procmail-aware, but just to make sure your mail actually gets filtered through procmail rather than directly delivered, you must place the following line in your ~/.forward file:

|/usr/bin/procmail

That should be all you have in the file. Any special forwarding you want to do can be done from within the procmailrc file. Of course, if procmail doesn't live in /usr/bin on your system, correct the path appropriately.

2.2. Global procmailrc settings

There are some variables that can be set from within the .procmailrc, whose values determine specific behavior of procmail while delivering your mail. Here is a list of the more commonly used ones. Don't get overwhelmed. Most of these have reasonable default values:

MAILDIR
Current directory while procmail is executing (that means that all paths are relative to $MAILDIR).
DEFAULT
Default mailbox file (if not told otherwise, procmail will dump mail in this mailbox). Procmail will automatically use $DEFAULT$LOCKEXT as lockfile prior to writing to this mailbox. You do not need to set this variable, since it already points to the standard system mailbox.
LOG
Anything assigned to this variable will be appended to $LOGFILE. Useful for debugging purposes.
ORGMAIL
Usually the system mailbox (ORiGinal MAILbox). If, for some obscure reason (like `filesystem full') the mail could not be delivered, then this mailbox will be the last resort. If procmail fails to save the mail in here (deep, deep trouble :-), then the mail will bounce back to the sender.
TRAP
When procmail terminates it will execute the contents of this variable. A copy of the mail can be read from stdin. Any output produced by this command will be appended to $LOGFILE. Possible uses for TRAP are: removal of temporary files, logging customised abstracts, etc.
INCLUDERC
Names an rcfile (relative to the current directory) which will be included here as if it were part of the current rcfile. Nesting is permitted and only limited by systems resources (memory and file descriptors). As no checking is done on the permissions or ownership of the rcfile, users of INCLUDERC should make sure that only trusted users have write access to the included rcfile or the directory it is in.
DROPPRIVS
If set to `yes' procmail will drop all privileges it might have had (suid or sgid). This is only useful if you want to guarantee that the bottom half of the /etc/procmailrc file is executed on behalf of the recipient.

See the procmailrc manpage for the default values assigned to these variables.

2.3. The format of a procmail recipe

A procmail recipe takes the following format:

:0 [flags] [ : [locallockfile] ]
* condition-regex1
* condition-regex2
> exactly one action line <

There can be 0 or more condition regexes, each preceeded by a * . The conditions are ANDed, so if a message does not match them all, it will not match the recipe.

By the way, the 0 following the : that marks the start of a new rule has no significance. In older versions of procmail, the digit was used, but due to changes in the functionality of procmail, it has become obsolete. Therefore, we always use 0.

The condition REs can be preceeded by a ! (negate the RE), ? (Use the exit code of the specified program), > , or > (Ensure that the message size is less than or greater than the number of bytes specified as the expression).

2.4. Recipe flags

There are several flags that can be placed after the :0 that affect the behavior of the recipe. When no flags are specified, a default flag set of "Hhb" is assumed. Any combination of the following flags can be specified, and the new flag set will override the default flag set. Here is a list of commonly used flags:

H
Egrep the header against the specified REs (default)
B
Egrep the body against the specified REs
D
Be case sensitive (default is case insensitive)
h
Feed the mail header to the action (default)
b
Feed the mail body to the action (default)
f
Filter program will modify the mail's text
c
Send mail to this rule, but continue through procmailrc

The last option, c, is used on rules that do things such as send a response to the email, or send a carbon copy of the email to another address, for example.

2.5. Types of patterns to look for

To filter a message by sender, use a rule such as:

* ^From .*sender@somedomain

Note that there are t wo From fields in a typical email header. The one with no colon following it is where the mail r eally came from, wheras the one with the colon after it is the address that the sender claims to be sending from.

To filter a message by recipient, use a rule such as:

* ^To: .*your@address

Subjects also have some good information you may want to use to filter. See my example procmailrc file for different ways I egrep the Subject.

3. More advanced recipe tricks
3.1. Multi-tiered recipies

If you have one recipe that is a base requirement for many other recipes, you can nest them. Say you have two email addresses and you want to filter differently for each:

:0
* To:.*joe.blow@somecompany.com
{
    :0
    * From:.*boss@somecompany.com
    urgent-mail

    :0
    INBOX
}

:0
* To:.*jblow@home.com
{
    :0
    * From:.*boss@somecompany.com
    /dev/null

    :0
    INBOX
}

3.2. Formail

formail is a program that takes mail headers on standard input and modifies them in some way and prints them back onto standard output. This is useful for auto responders that respond using the same subject as the email you were initially sent. See my procmailrc below for an example.

4. Some Examples
4.1. Generic Examples

The best place to look for examples is the procmailex(1) manpage. It has a much more complete set of examples than I can put in this document.

4.2. My procmailrc

Here is my procmailrc. Mail to my runslinux.net address comes into the same box as my jehsom.com address, and I'd like to treat them differently. Sorry the comments are sparse and the file isn't cleaned up as much as I would have liked, but I'm short on time, so it's all I can do:

Download the sample procmailrc (Text format, 2.9 KB).

# Moshe's procmailrc
# This procmailrc processes email coming in on several email addresses. Mail
# for jehsom@jehsom.com should be filed separately from all other mail.

MAILDIR=$HOME/var/mail
LOGFILE=$HOME/.procmail.log
VERBOSE=on

# trash advertisements
:0
* ^Subject: \[?ADV?[] ]?:?\b
/dev/null

# Killfile billie pendleton parker
:0
* ^From: .*(billiee.*pendleton.*parker)
* ^To: .*(apo|bp4@prism.gatech.edu)
/dev/null

# Killfile ruffside
:0
* ^From:.*ruffside
/dev/null

# Trash lugatgt listproc stupidness
:0 HB
* signoff lugatgt-list
/dev/null

# Remove any duplicate emails (mailing list Cc:'s and stuff)
:0 Wh : $MAILDIR/.idcache.lock
| formail -D 1000 $MAILDIR/.idcache

# Tack on a header to togetherweb mail
:0 hbf
* ^(To|Cc): .*@[^ ]*togetherweb.com <
| $HOME/bin/addtotop " *** NOTICE: This mail was sent to togetherweb.com ***\n"

# Remove yahoo advertisements
:0 hbf
* ^From:.*yahoo
| sed '/^_\{50\}$/,$ d'

# Fix incorrect sigdashes
:0 Bfwhb
* ^--$
| sed 's/^--$/-- /'

# Remove cyberbuzz ad
:0 hbf
* ^Message-ID:.*cyberbuzz
| sed '/^-\{49\}$/,$ d'

# Send autoresponse to @togetherweb mail, saying I've changed my address.
:0 chw
* !^FROM_DAEMON
* !^X-Loop: .*moshe@runslinux\.net
* ^(To|Cc): .*(moshe|jehsom)@togetherweb\.com
* !^From: .*(moshe|jehsom|togetherweb\.com)
| { formail -r -I "From: Moshe Jacobson> moshe@runslinux.net <" \
             -a "Date: `date -R`" \
             -A "X-Loop: moshe@runslinux.net"; \
    cat $HOME/.autoreply.togetherweb; \
 cat $HOME/.sig.moshe; \
  } | sendmail -oi -t


:0
* ^(To|Cc): .*jehsom
{
    :0 BH
    * !^FROM_DAEMON
    * !^X-Loop: .*jehsom@jehsom.com
    * zipscript|debug( mode|ging)|glftpd|\b0day\b|file_id.diz|\brels\b|racers
    {
        :0 c
        * !^From: .*maestro
        ! maestro@dv8.org

        :0 :   
        jehsom/INBOX-zipscript
    }

    :0 BH
    * !^FROM_DAEMON
    * !^X-Loop: jehsom@jehsom\.com
    * \b(ftp.(account|server)|serial|vcd|iso|bin.*cue|irc|key|cd[123])\b
    jehsom/INBOX-scene

    :0 :
    jehsom/INBOX
}

# Vacation Autoresponder for moshe@*
#:0 chw
#* ^(To|Cc):.*moshe
#* !^X-Loop: moshe@runslinux\.net
#| { formail -r -I "From: Moshe Jacobson> moshe@runslinux.net <" \
#               -A "X-Loop: moshe@runslinux.net" \
#               -a "Date: `date -R`"; \
#    cat $HOME/.autoreply.vacation
#  cat $HOME/.sig.moshe
#  } | sendmail -oi -t

# Mail from my website
:0 hb :
* ^X-Mail-Gateway:.*Doug
moshe/INBOX-web

# Put list mailings in a separate folder
:0 hb :
* ^Subject: (Re: )?\[[^]]*\] .*
* !^(To|Cc): .*(jehsom|moshe)
moshe/INBOX-lists

# Catch mail from root/daemons and put it in a separate folder
:0 hb :
* ^From:.*\> (MAILER-DAEMON|root|bugzilla-daemon)@
moshe/INBOX-daemons

# Mail from alert scripts
:0 :
* ^To:.* alert@togetherweb.com
moshe/INBOX-daemons

# Orchstra and list/chat lists
:0 hb :
* ^(To|Cc): .*(orchestra|-(list|chat))@
moshe/INBOX-lists

:0 :
moshe/INBOX

5. Resources
  • man pages: procmail(1), procmailrc(5), procmailex(5), procmailsc(5)
    The man pages for (respectively) procmail itself, the procmailrc file and its format, a lot of good examples of procmail recipies, and procmail scoring. procmailrc(5) and procmailex(5) should provide pretty much all the information you'll need on how to use procmail. For some really advanced scary stuff on mail scoring using procmail (not covered in this document), see procmailsc(5).
  • http://www.procmail.org/
    This is the official Procmail website.
  • http://www.iki.fi/era/procmail
    This is a very well-written FAQ on Procmail. It should answer the most common questions concerning problems you may run into while using Procmail.
  • http://www.spambouncer.org/
    The SpamBouncer is a set of procmail instructions that search the headers and text of your incoming email to see if it meets one or more of a list of conditions for probable spam. It will then either tag the suspected spam and return it to your main incoming mailbox, tag the suspected spam, delete spam from known spam sources, and file suspected spam in a separate folder, send a simulated MAILER-DAEMON daemon "bounce", complain to the "upstream providers" of known spammers or spam sites/domains, etc.
  • http://junkfilter.zer0.org/
    junkfilter is a procmail -based filter system for electronic mail. It filters sex spam, MLM schemes, and all other types of unsolicited commercial e-mail (UCE).
  • http://ceti.pl/~kravietz/spamr
    Spamrc is a set of Procmail scoring rules that try to eliminate spam from your incoming email based on scoring. Spamrc checks a number of commong spam signatures, giving the email some points for each matching rule. The points are added and the result is used to decide the probability that the message is spam. The scheme works quite well, though it has some false positives and misses.

This article has external documents! Click here.