Red Hat Linux includes two primary MDAs, Procmail and
mail. Both of the applications are considered Local
Delivery Agents and both move email from the MTA's spool file into the
user's mailbox. However, Procmail provides a robust filtering system.
This section details only Procmail. For information on the
mail command, consult its man page.
Procmail delivers and filters email as it is placed in the mail spool
file of the localhost. It is powerful, gentle on system resources, and
widely used. Procmail can play a critical role in delivering email to be
read by email client applications.
Procmail can be invoked in several different ways. Whenever an MTA
places an email into the mail spool file, Procmail is launched. Procmail
then filters and files the email so the MUA can find it, and
quits. Alternatively, the MUA can be configured to execute Procmail any
time a message is received so that messages are moved into their correct
mailboxes. By default, the presence of a
.procmailrc file in the user's home directory will
invoke Procmail whenever an MTA receives a new message.
The actions Procmail takes with an email are dependent upon instructions
from particular recipes, or rules, that messages
are matched against by the program. If a message matches the recipe,
then the email will be placed in a certain file, deleted, or otherwise
processed.
When Procmail starts, it reads the email message and separates the body
from the header information. Next, Procmail looks for
/etc/procmailrc and rc files
in the /etc/procmailrcs directory for default,
system-wide, Procmail environmental variables and recipes. Then,
Procmail looks for a .procmailrc file in the user's
home directory to find rules specific to that user. Many users also
create additional rc files of their own for
Procmail that are referred to by their .procmailrc
file, but may be turned on or off quickly if a mail filtering problem
develops.
By default, no system-wide rc files exist in the
/etc directory, and no user
.procmailrc files exist. To begin using Procmail,
construct a .procmailrc file with particular
environment variables and rules for certain types of messages.
In most configurations, the decision as to whether Procmail starts and
attempts to filter the email is based on the existence of a user's
.procmailrc file. To disable Procmail, but save the
work on the .procmailrc file, move it to a similar
file's name using the mv ~/.procmailrc
~/.procmailrcSAVE command. When ready to test Procmail again,
change the name of the file back to
.procmailrc. Procmail will begin working again
immediately.
11.4.1. Procmail Configuration
Procmail configuration files, most notably the user's
.procmailrc, contain important environmental
variables. These variables tell Procmail which messages to sort, what
to do with the messages that do not match any recipes, and so on.
These environmental variables usually appear at the beginning of
.procmailrc in the following format:
<env-variable>="<value>"
In this example,
<env-variable> is
the name of the variable and
<value> defines the
variable.
Many environment variables are not used by most Procmail users, and
many of the more important environment variables are already defined
by a default value. Most of the time, the following variables will be
used:
DEFAULT — Sets the default mailbox where
messages that do not match any recipes will be placed.
The default DEFAULT value is the same as
$ORGMAIL.
INCLUDERC — Specifies additional
rc files containing more recipes for messages
to be checked against. This breaks up the Procmail
recipe lists into individual files that fulfill different roles,
such as blocking spam and managing email lists, that can then be
turned off or on by using comment characters in the user's
.procmailrc file.
For example, lines in a user's
.procmailrc file may look like this:
If the user would like to turn off Procmail filtering of their
email lists but leave spam control in place, they could comment
out the first INCLUDERC line with a
hash mark character [#].
LOCKSLEEP — Sets the amount of time, in
seconds, between attempts by Procmail to use a particular
lockfile. The default is eight seconds.
LOCKTIMEOUT — Sets the amount of time,
in seconds, that must pass after a lockfile was last modified
before Procmail assumes that the lockfile is old and can be
deleted. The default is 1024 seconds.
LOGFILE — The location and file to contain
any Procmail information or error messages.
MAILDIR — Sets the current working
directory for Procmail. If set, all other Procmail paths are
relative to this directory.
ORGMAIL — Specifies the original mailbox,
or another place to put the messages if they cannot be
placed in the default or recipe-required location.
By default, a value of /var/spool/mail/$LOGNAME
is used.
SUSPEND — Sets the amount of time, in
seconds, that Procmail will pause if a necessary resource, such as
swap space, is not available.
SWITCHRC — Allows a user to specify an
external file containing additional Procmail recipes, much like
the INCLUDERC option, except that recipe checking
is actually stopped on the referring configuration file and only
the recipes on the SWITCHRC-specified file are
used.
VERBOSE — Causes Procmail to log more
information. This option is useful for debugging.
Other important environmental variables are pulled from the shell,
such as LOGNAME, which is the login name;
HOME, which is the location of the home directory;
and SHELL, which is the default shell.
A comprehensive explanation of all environments variables, as well as
their default values, is available in the procmailrc
man page.
11.4.2. Procmail Recipes
New users often find the construction of recipes the most difficult
part of learning to use Procmail. To some extent, this is
understandable, as recipes do their message matching using
regular expressions, which is a particular
format used to specify qualifications for a matching string. However,
regular expressions are not very difficult to construct and even less
difficult to understand when read. Additionally, the consistency of
the way Procmail recipes are written, regardless of regular
expressions, makes it easy to figure out what is happening.
A thorough explanation of regular expressions is beyond the scope of
this section. The structure of Procmail recipes is more important and
useful sample Procmail recipes can be found at various places on the
Internet (including http://www.iki.fi/era/procmail/links.html).
The proper use and adaptation of the regular expressions found in
these recipe examples depend upon an understanding of Procmail recipe
structure. Introductory information specific to basic regular
expression rules can be found in the grep man
page.
The first two characters in a Procmail recipe are a colon and a
zero. Various flags can optionally be placed after the zero to control
what Procmail does when processing this recipe. A colon after the
<flags> section
specifies that a lockfile is created for this message. If a lockfile
is to be created, specify its name in the
<lockfile-name>
space.
A recipe can contain several conditions to match against the message.
If it has no conditions, every message matches the
recipe. Regular expressions are placed in some conditions in order to
facilitate a match with a message. If multiple conditions are used,
they must all match in order for an action to be performed. Conditions
are checked based on the flags set in the recipe's first
line. Optional special characters placed after the
* character can further control the
condition.
The
<action-to-perform>
specifies what is to happen to a message if it matches one of the
conditions. There can only be one action per recipe. In many cases,
the name of a mailbox is used here to direct matching messages into
that file, effectively sorting the email. Special action characters
may also be used before the action is specified.
11.4.2.1. Delivering vs. Non-Delivering Recipes
The action used if the recipe matches a particular message
determines whether the recipe is considered delivering or
non-delivering. A delivering recipe contains
an action that writes the message to a file, sends the message to
another program, or forwards the message to another email address. A
non-delivering recipe covers any other
actions, such as when a nesting block is used. A nesting
block is an action contained in braces {
} that designates additional actions to perform on messages
that match the recipe's conditions. Nesting blocks can be nested,
providing greater control for identifying and performing actions on
messages.
Delivering recipes that match messages causes Procmail to perform
the action specified and stop comparing the message against any
other recipes. Messages that match conditions in non-delivering
recipes continue to be compared against other recipes in the
current and following rc files. In other words,
non-delivering recipes cause the message to continue through the
recipes after the specified action is taken on it.
11.4.2.2. Flags
Flags are very important in determining how or if a recipe's
conditions are compared to a message. The following flags are
commonly used:
A — Specifies that this recipe is
only used if the previous recipe without an A
or a flag also matched this message.
To ensure that the action on this last previous matching recipe
was successfully completed before allowing a match on the
current recipe, use the a flag instead.
B — Parses the body of the message
and looks for matching conditions.
b — Uses the body in any resulting action,
such as writing the message to a file or forwarding it. This is
the default behavior.
c — Generates a carbon copy of the
email. This is useful with delivering recipes, since the
required action can be performed on the message and a copy of
the message can continue being processed in the
rc files.
D — Makes the egrep
comparison case-sensitive. By default, the comparison process is
not case-sensitive.
E — While similar to the
A flag, the conditions in this recipe are only
compared to the message if the immediately preceding recipe
without an E flag did not match. This is
comparable to an else action.
Use the e flag if this recipe is checked
only when the preceding recipe matched but the action failed.
f — Uses the pipe as a filter.
H — Parses the header of the message and
looks for matching conditions. This occurs by default.
h — Uses the header in a resulting
action. This is the default behavior.
w — Tells Procmail to wait for the
specified filter or program to finish, and reports whether or not
it was successful before considering the message filtered.
To ignore "Program failure" messages when deciding whether a
filter or action succeeded, use the W option
instead.
Additional flags can be found in the procmailrc
man page.
11.4.2.3. Specifying a Local Lockfile
Lockfiles are very useful with Procmail to ensure that more than one
process does not try to alter a certain message at the same
time. Specify a local lockfile by placing a colon
(:) after any flags on a recipe's first
line. This creates a local lockfile based on the destination
file name plus whatever has been set in the LOCKEXT
global environment variable.
Alternatively, specify the name of the local lockfile to be used
with this recipe after the colon.
11.4.2.4. Special Conditions and Actions
Particular characters used before Procmail recipe conditions and
actions change the way they are interpreted.
The following characters may be used after the *
character at the beginning of a recipe's condition line:
! — In the condition line, this
character inverts the condition, causing a match to occur only
if the condition does not match the message.
< — Checks to see if the message is
under the specified number of bytes.
> — Checks to see if the message
is over a specified number of bytes.
The following characters are used to perform special actions:
! — In the action line, this
character tells Procmail to forward the message
to the specified email addresses
$ — Refers to a variable set earlier
in the rc file. This is often used to set a
common mailbox that is referred to by various recipes.
| — The pipe character tells Procmail to
start a specific program to deal with this message.
{ and } — Constructs a
nesting block, used to contain additional recipes to apply to
matching messages.
If no special character is used at the beginning of the action line,
Procmail assumes that the action line is specifying a mailbox where
the message should be written.
11.4.2.5. Recipe Examples
Procmail is an extremely flexible program, which matches messages
with very specific conditions and then perform detailed actions on
them. As a result of this flexibility, however, composing a Procmail
recipe from scratch to achieve a certain goal can be difficult for
new users.
The best way to develop the skills to build Procmail recipe
conditions stems from a strong understanding of regular expressions
combined with looking at many examples built by others. The
following very basic examples exist to serve as a demonstration of
the structure of Procmail recipes and can provide the foundation for
more intricate constructions.
A basic recipe may not even contain conditions, as is illustrated in
the following example:
:0:
new-mail.spool
The first line starts the recipe by specifying that a local lockfile
is to be created but does not specify a name, leaving Procmail to
use the destination file name and the LOCKEXT to
name it. No condition is specified, so every message matches this
recipe and, therefore, is placed in the single spool file called
new-mail.spool, located within the directory
specified by the MAILDIR environment variable. An
MUA can then view messages in this file.
This basic recipe could be placed at the end of all
rc files to direct messages to a default
location. A more complicated example might grab messages from a
particular email address and throw them away, as can be seen in this
example.
:0
* ^From: spammer@domain.com
/dev/null
With this example, any messages sent by
spammer@domain.com are immediately
moved to /dev/null, deleting them.
Caution
Be very careful that a rule is working
correctly before moving messages that are matched to
/dev/null, are permanently deleted. If the
recipe conditions inadvertently catch unintended messages, they
disappear without a trace, making it hard to troubleshoot the
rule.
A better solution is to point the recipe's action to a special
mailbox, which can be checked from time to time in order to look
for false positives, or messages that
inadvertently matched the conditions. Once satisfied that no
messages are accidentally being matched, delete the mailbox and
direct the action to send the messages to
/dev/null.
Procmail is primarily used as a filter for email, automatically
placing it in the right place to prevent manual sorting. The
following recipe grabs email sent from a particular mailing list and
puts it in the correct folder.
:0:
* ^(From|CC|To).*tux-lug
tuxlug
Any messages sent from the
tux-lug@domain.com mailing list
will be placed in the tuxlug mailbox
automatically for the MUA. Note that the condition in this example
will match the message if it has the mailing list's email address on
the From,
CC, or
To lines.
Consult the many Procmail online resources available from
Section 11.6 Additional Resources to see more detailed
and powerful recipes.
11.4.2.6. Spam Filters
Because it is called by Sendmail, Postfix, and Fetchmail upon
receiving new emails, Procmail can be used as a powerful tool for
combating spam.
This is particularly true when Procmail is used in conjunction with
SpamAssassin. When used together, these two applications can quickly
identify spam emails, and sort or destroy them.
SpamAssassin uses header analysis, text analysis, blacklists, and a
spam-tracking database to quickly and accurately identify and tag
spam.
The easiest way for a local user to use SpamAssassin is to place the
following line near the top of the
~/.procmailrc file:
The
/etc/mail/spamassassin/spamassassin-default.rc
contains a simple Procmail rule that activates SpamAssassin for all
incoming email. If an email is determined to be spam, it is tagged
in the header as such and the title is prepended with the following
pattern:
*****SPAM*****
The message body of the email is also prepended with a running tally
of what elements caused it to be diagnosed as spam.
To file email tagged as spam, a rule similar to the following can be
used:
:0 Hw
* ^X-Spam-Status: Yes
spam
This rule files all email tagged in the header as spam into a mailbox
called spam.
Since SpamAssassin is a Perl script, it may be necessary on busy
servers to use the binary SpamAssassin daemon
(spamd) and client application
(spamc). Configuring SpamAssassin this way,
however, requires root access to the host.
To start the spamd daemon, type the following
command as root:
/sbin/service spamassassin start
In order for the SpamAssassin daemon to start when the system is
booted, use an initscript utility, such as the
Services Configuration Tool
(redhat-config-services), to turn on the
spamassassin service. Refer to
Section 1.4.2 Runlevel Utilities for more
information about initscript utilities.
To configure Procmail to use the SpamAssassin client application
instead of the Perl script, place the following line near the top of
the ~/.procmailrc file or for a system-wide
configuration, place it in /etc/procmailrc: