A Quick, Practical Procmail Guide

Lloyd B. Eldred,

Procmail is a Unix utility to process and filter email. It can be a little confusing at first, but once running it can make your life a lot easier. I use procmail to sort my various mailing lists into folders and to detect and delete most spam.

This page is intended to give you a quick and dirty explanation and the tools you need to get things set up. It is not anywhere near a complete set of procmail documentation. See the section on other links for that.


What you need

To use procmail you need to receive your mail via a Unix shell account. And the procmail program needs to be on the system, which is almost always the case.

To check if procmail is on your system type which procmail. The system will reply with the location of the program (usually "/usr/bin/procmail" or "/usr/local/bin/procmail"). Remember where it is. You'll need that info for the next step.


Geting Started

There are two basic steps to starting to use procmail: the .forward and the .procmailrc files.

The .forward file (note the period as the first character of the filename. It's important!) simply causes your inbound mail to be looked at by the procmail program before being put in your inbox. Create it in your root directory and type in some version of the following line, including the quotation marks:

"|IFS=' '&&exec /usr/local/bin/procmail -f-||exit 75 #user"

You should change the middle part of this line to the actual location of the procmail program on your system and change the last word "user" to your username.

Note: on some systems (such as my Linux machine at home) procmail is the default local mail agent. In such cases the .forward file is not required (although it doesn't really hurt anything). I don't know of an easy way for users to determine their local configuration. Try sending test mail to yourself with and without the forwarding is my best suggestion.

The .procmailrc (again note leading period) file contains your instructions to the filtering program. It also goes in your root directory. You should start your file with something like the following:

# .procmailrc
# routes incoming mail to appropriate mailboxes
PATH=/usr/bin:/usr/local/bin
MAILDIR=$HOME/Mail
PMDIR=$MAILDIR
LOGFILE=$PMDIR/procmail.log
LOGABSTRACT=no
SHELL=/bin/sh

Remember that the dot as the first character in the Unix filename makes the file hidden. It won't appear in a normal directory listing. Use 'ls -a' to verify that your new files are where they should be.


Basic Filtering

Ok, now procmail is up and running. But, it's not actually doing anything other than putting your mail in your inbox. Next you'd like to set up some filters.

Each filter is specified by a "recipe". You can have as many recipies in your .procmailrc file as you wish. Procmail will test each mail message against each recipe in order. If it finds one that matches it follows your instructions. If not, it puts the mail in your normal inbox. Here's an example recipe:

# fencing mailing list
:0:
* ^(From|Cc|To).*(sca-rapier)
Fence

That may be a little confusing at first, but it's not really that bad. Any line starting with a # is a comment. The third line is the test. It looks for the text "sca-rapier" in the From, CC, and To fields of the mail. If it's found, the mail is put in the "Fence" folder. By the way, you can use the special "TO" command to mean "(From|Cc|To)". Thus, the test line could have been written as:

* ^TOsca-rapier*

Multiple tests can be specified sequentially. The following recipe sends messages about "Espers" from the rapier list to /dev/null (the Unix trashbin).

# Junk some boring stuff
:0:
* ^TOsca-rapier*
* ^(Subject).*(Espers)
/dev/null

With these tools you should be able to do a good job of sorting your mail into a useful order. Both pine and elm are mail readers that support multiple folders. I'm partial to pine myself.


Advanced spam defenses

Ok, it's time to do battle against the scum who want to take over your mailbox. With a little work you can lock-out 95% of the low-lifes. There are a number of simple strategies that will accomplish this.

Safety tip: It may take some experimentation to get things to work correctly. To help detect problems turn logging from off to on (in the .procmailrc header) and rather than deleting unwanted mail send it to a junk folder that you check once in a while. Once you're sure things are working correctly, then you can "/dev/null" to your heart's content.

"To" filtering

Very little junk email is actually addessed to the receiver (your name is in the BCC, or blind carbon copy field instead). Note that this is also typically the case for legitimate mailing lists, so you should carefully filter the mail you wish to keep out first. Then, add a recipe that checks for your email address in the header like this:

:0:
* !^(From|Sender|to|Cc):.*(galtham)
spam-bin

The "!" in front means "not". So, if my user name is not in one of the four fields listed, the mail gets put into my storage folder.

"From" filtering

Most junk email comes from a small number of companies and addresses. By checking who a message is from, a lot of such mail can be detected and dealt with. For a while, I had a long list of recipes dealing with each spam site. Recently, I've replaced those pages of recipes with the following single recipe:

# grep based spam detector
# Exitcode: 67=no such user
#           77=permission denied
:1
? fgrep -i -f $PMDIR/sites
{
 EXITCODE = 77
 :0
 /dev/null
}

This is a little more complicated. Basically, I have a file in my Mail directory called "sites". This contains a list of those internet sites that I've decided I don't wish to receive mail from. Recently, the file grew so large that I broke it into two parts. My current files can be viewed here and here. The Unix "fgrep" utility searches the inbound mail for any of the sites listed in the file. Should they be found, then two things happen. First, the sender gets a "permission denied" error, then the mail gets deleted (or put in a folder if desired).

This approach is very powerful and effective.

Other approaches

There are any number of other tactics that can be used to detect spam. One group of spammers likes to always have their mail to "friend@public.com". Others like to use the string "XXX" in their adult web site advertisements. Anything that you can pick up as a pattern can be used to defeat these guys. Here are a couple of other useful recipes.

To test for an invalid IP address:

* ^Received.*\[[0-9\.]*([03-9][0-9][0-9]|2[6-9][0-9]|25[6-9])

To test for an advertisement header:

* ^X-Advertisement

Good luck and good hunting.


Short sample .procmailrc file

# .procmailrc
# routes incoming mail to appropriate mailboxes
PATH=/usr/bin:/usr/local/bin
MAILDIR=$HOME/Mail
#DEFAULT=$HOME/.mailspool/ian
PMDIR=$MAILDIR
LOGFILE=$PMDIR/procmail.log
LOGABSTRACT=no
SHELL=/bin/sh

# ------------------- Sorting Mailing Lists ---------------------
# Various fencing mailing lists
:0:
* ^(From|Cc|To).*(sca-rapier|sca-fence|fencers)
Fence

# Linux stuff mailing lists
:0:
* ^(From|Cc|To).*(trn-|linux-security)
linux

#------------------------- Trash detection ------------------

# New grep based spam detector
# Exitcode: 67=no such user
#           77=permission denied
:1
? fgrep -i -f $PMDIR/.spamsites
{
 EXITCODE = 77
 :0
 spam-bin
}

# Stealth Mailer bogus timestamp
:0
* ^Received:.*-0[67]00 \(E[SD]T\)
{
 EXITCODE = 77
 :0
 spam-bin
}

#---------- Be suspicious with stuff that's not TO me -
:0:
* !^(From|Sender|to|Cc).*(galtham)
spam-bin

#---------- End of .procmailrc

Other Procmail related resources

Procmail How-To Page Very good!

Procmail Mini-FAQ Good page with a HUGE list of links.

Junkfilter Another guy's procmail filters.

The Procmail filters kit Another set.

Filtering Mail FAQ

Pine FAQ

Stop Junk Email A bunch of news and links on spam and the fight against it.

CAUCE A group lobbying Congress to outlaw spam.


[Index] [Whoman] [Space Rogues] [Ordering]

Copyright (c) 1997-2003 Lloyd B. Eldred , all rights reserved.