Chapter 1 - Forwarding and filtering in Exim
This document describes the user interfaces to Exim’s in-built mail filtering facilities, and is copyright © University of Cambridge 2007. It corresponds to Exim version 4.77.
Most Unix mail transfer agents (programs that deliver mail) permit individual users to specify automatic forwarding of their mail, usually by placing a list of forwarding addresses in a file called .forward in their home directories. Exim extends this facility by allowing the forwarding instructions to be a set of rules rather than just a list of addresses, in effect providing “.forward with conditions”. Operating the set of rules is called filtering, and the file that contains them is called a filter file.
Exim supports two different kinds of filter file. An Exim filter contains instructions in a format that is unique to Exim. A Sieve filter contains instructions in the Sieve format that is defined by RFC 3028. As this is a standard format, Sieve filter files may already be familiar to some users. Sieve files should also be portable between different environments. However, the Exim filtering facility contains more features (such as variable expansion), and better integration with the host environment (such as the use of external processes and pipes).
The choice of which kind of filter to use can be left to the end-user, provided that the system administrator has configured Exim appropriately for both kinds of filter. However, if interoperability is important, Sieve is the only choice.
The ability to use filtering or traditional forwarding has to be enabled by the system administrator, and some of the individual facilities can be separately enabled or disabled. A local document should be provided to describe exactly what has been enabled. In the absence of this, consult your system administrator.
This document describes how to use a filter file and the format of its contents. It is intended for use by end-users. Both Sieve filters and Exim filters are covered. However, for Sieve filters, only issues that relate to the Exim implementation are discussed, since Sieve itself is described elsewhere.
The contents of traditional .forward files are not described here. They normally contain just a list of addresses, file names, or pipe commands, separated by commas or newlines, but other types of item are also available. The full details can be found in the chapter on the redirect router in the Exim specification, which also describes how the system administrator can set up and control the use of filtering.
2. Filter operation
It is important to realize that, in Exim, no deliveries are actually made while a filter or traditional .forward file is being processed. Running a filter or processing a traditional .forward file sets up future delivery operations, but does not carry them out.
The result of filter or .forward file processing is a list of destinations to which a message should be delivered. The deliveries themselves take place later, along with all other deliveries for the message. This means that it is not possible to test for successful deliveries while filtering. It also means that any duplicate addresses that are generated are dropped, because Exim never delivers the same message to the same address more than once.
3. Testing a new filter file
Filter files, especially the more complicated ones, should always be tested, as it is easy to make mistakes. Exim provides a facility for preliminary testing of a filter file before installing it. This tests the syntax of the file and its basic operation, and can also be used with traditional .forward files.
Because a filter can do tests on the content of messages, a test message is required. Suppose you have a new filter file called myfilter and a test message in a file called test-message. Assuming that Exim is installed with the conventional path name /usr/sbin/sendmail (some operating systems use /usr/lib/sendmail), the following command can be used:
/usr/sbin/sendmail -bf myfilter <test-message
The -bf option tells Exim that the following item on the command line is the name of a filter file that is to be tested. There is also a -bF option, which is similar, but which is used for testing system filter files, as opposed to user filter files, and which is therefore of use only to the system administrator.
The test message is supplied on the standard input. If there are no message-dependent tests in the filter, an empty file (/dev/null) can be used. A supplied message must start with header lines or the “From ” message separator line that is found in many multi-message folder files. Note that blank lines at the start terminate the header lines. A warning is given if no header lines are read.
The result of running this command, provided no errors are detected in the filter file, is a list of the actions that Exim would try to take if presented with the message for real. For example, for an Exim filter, the output
Deliver message to: firstname.lastname@example.org Save message to: /home/lemuel/mail/archive
means that one copy of the message would be sent to email@example.com, and another would be added to the file /home/lemuel/mail/archive, if all went well.
The actions themselves are not attempted while testing a filter file in this way; there is no check, for example, that any forwarding addresses are valid. For an Exim filter, if you want to know why a particular action is being taken, add the -v option to the command. This causes Exim to output the results of any conditional tests and to indent its output according to the depth of nesting of if commands. Further additional output from a filter test can be generated by the testprint command, which is described below.
When Exim is outputting a list of the actions it would take, if any text strings are included in the output, non-printing characters therein are converted to escape sequences. In particular, if any text string contains a newline character, this is shown as “\n” in the testing output.
When testing a filter in this way, Exim makes up an “envelope” for the message. The recipient is by default the user running the command, and so is the sender, but the command can be run with the -f option to supply a different sender. For example,
/usr/sbin/sendmail -bf myfilter \ -f firstname.lastname@example.org <test-message
Alternatively, if the -f option is not used, but the first line of the supplied message is a “From ” separator from a message folder file (not the same thing as a From: header line), the sender is taken from there. If -f is present, the contents of any “From ” line are ignored.
The “return path” is the same as the envelope sender, unless the message contains a Return-path: header, in which case it is taken from there. You need not worry about any of this unless you want to test out features of a filter file that rely on the sender address or the return path.
It is possible to change the envelope recipient by specifying further options. The -bfd option changes the domain of the recipient address, while the -bfl option changes the “local part”, that is, the part before the @ sign. An adviser could make use of these to test someone else’s filter file.
The -bfp and -bfs options specify the prefix or suffix for the local part. These are relevant only when support for multiple personal mailboxes is implemented; see the description in section 3.31 below.
4. Installing a filter file
A filter file is normally installed under the name .forward in your home directory – it is distinguished from a conventional .forward file by its first line (described below). However, the file name is configurable, and some system administrators may choose to use some different name or location for filter files.
5. Testing an installed filter file
Testing a filter file before installation cannot find every potential problem; for example, it does not actually run commands to which messages are piped. Some “live” tests should therefore also be done once a filter is installed.
If at all possible, test your filter file by sending messages from some other account. If you send a message to yourself from the filtered account, and delivery fails, the error message will be sent back to the same account, which may cause another delivery failure. It won’t cause an infinite sequence of such messages, because delivery failure messages do not themselves generate further messages. However, it does mean that the failure won’t be returned to you, and also that the postmaster will have to investigate the stuck message.
If you have to test an Exim filter from the same account, a sensible precaution is to include the line
if error_message then finish endif
as the first filter command, at least while testing. This causes filtering to be abandoned for a delivery failure message, and since no destinations are generated, the message goes on to be delivered to the original address. Unless there is a good reason for not doing so, it is recommended that the above test be left in all Exim filter files. (This does not apply to Sieve files.)
6. Details of filtering commands
The filtering commands for Sieve and Exim filters are completely different in syntax and semantics. The Sieve mechanism is defined in RFC 3028; in the next chapter we describe how it is integrated into Exim. The subsequent chapter covers Exim filtering commands in detail.