courierfilter - Courier mail filters
[[start] | [stop] | [restart]]
[[start] | [stop]] [ filter]
commands install or uninstall global mail filter
Global mail filters are used to selectively block unwanted mail. More than one
mail filter can be enabled at the same time. Three filters -
(8) - are provided as examples for writing
runs all mail filters that have been installed by
. courierfilter stop
shuts down all running mail
filters. After courierfilter start
, any filterctl
effect immediately. After courierfilter stop
commands will take effect at the next courierfilter start
signals the running courierfilter
its configuration files. This is normally done automatically, by
If any mail filter is installed, the mail filter must be running in order for
any mail to be processed. Mail filters are assumed to be empowered to enforce
system-wide mail policies, so if an installed mail filter is not running then
mail will not be accepted by the system. Note that mail will not be rejected,
if possible. Every attempt will be made to send a temporary error code to an
external mail system, asking it to try again later.
For this reason, you should modify your system boot script to run
as soon as possible, and run courierfilter
during the final portion of your system shutdown script. It is not
necessary to run courierfilter
if you do not install a mail filter with
This section explains how mail filters are implemented, and how to write a new
global mail filter.
Available mail filter binaries are located in the directory
/usr/lib/courier/filters. The filterctl
script looks in this directory
to see which mail filters are available to be installed. Installing a mail
filter consists of simply creating a soft link from the directory
/etc/courier/filters/active to its corresponding binary in
/usr/lib/courier/filters. The courierfilter start command simply reads
/etc/courier/filters/active and runs every program in this directory.
script sends a HUP signal to courierfilter
installing or uninstalling a filter. courierfilter
will reread the
contents of /etc/courier/filters/active then start or stop individual mail
After starting, an individual mail filter must create a filesystem domain socket
in one of two directories: /var/lib/courier/filters or
/var/lib/courier/allfilters. The name of the socket should be the same as a
name of the filter, and the mail filter must make sure to remove any socket by
the same name in the other directory. For various silly reasons, the
recommended implementation is to create /var/lib/courier/filters/. NAME
or /var/lib/courier/allfilters/. NAME
(after making sure that it
doesn't exist) then rename .NAME
After initializing the socket, the mail filter must then close its file
descriptor #3. File descriptor 3 is inherited by every mail filter that's
executed by the courierfilter start
command. The mail filter's file
descriptor 3 is connected to the write
end of a pipe, which may be
relevant to certain ways of implementing the closing of the file descriptor,
for instance in Perl where you may be forced to pseudo-open the descriptor (in
write mode) before closing it. The courierfilter start
command will not
exit until every started mail filter closes its file descriptor 3. This allows
for all mail filters to orderly initialize themselves before courierfilter
All mail filters also inherit a pipe on standard input, and must terminate when
the pipe is closed. Mail filters must simultaneously listen for new
connections on the mail filter socket, and for their standard input to close.
The mail filter receives a new connection on its socket for every message that
needs to be filtered. After establishing a connection, the mail filter will
immediately read the following information from the new socket:
A pathname to a file containing the contents of the message.
One or more pathnames to control files for this message.
Each pathname is terminated by a single newline character. The last pathname is
followed by a second newline character. The pathnames may either be relative
pathnames to /usr or absolute pathnames, depending on the system
The mail filter is free to judge the message's worthiness by reading its
contents and/or control file(s) as soon as a second consecutive newline
character is received. The final verdict is rendered by writing back a result
code on the same socket. The result code follows the same format as regular
SMTP replies (even though the message may not have been received via SMTP),
and can be used to communicate acceptance, temporary failure, or a permanent
failure. If it's a failure, then the text portion of the result code will be
used, if possible. The result code may be a multiline response, just like a
regular SMTP reply. The mail filter must immediately close the connection
after writing the result code. After closing the socket the mail filter must
then proceed to wait for another connection request on the original listening
The mail filter can be multithreaded or multitasked, and can accept multiple
connections simultaneously. When its standard input is closed the mail filter
should stop accepting new connections and wait for any existing connections to
be closed, prior to exiting.
Global mail filters must be EXTREMELY resilient to runtime failures. Since mail
will not be processed if an installed mail filter is not running, if a mail
filter crashes it will effectively shut down the mail server. Currently
does not attempt to restart mail filters which crash.
The system administrator defines what mail gets filtered by editing the contents
of the enablefiltering configuration file in /etc/courier. This configuration
file contains a list of mail sources that should be filtered, like esmtp or
local. See courier
(8) for more information. A default
/etc/courier/enablefiltering file is installed that specifies only the esmtp
mail source as subject to filtering.
A message is not subject to filtering if its source is not listed in
/etc/courier/enablefiltering. Otherwise the following rules apply.
Certain mail destinations have the ability to selectively whitelist arbitrary
messages. For example, local mail recipients have the ability to selectively
whitelist individual messages, provided that a local mail filter (independent
of any global mail filter) is installed that implements the maildrop
New messages are filtered by connecting to every socket in
/var/lib/courier/filters and/or /var/lib/courier/allfilters, one at a time.
All mail filters must accept the message, for it to be accepted by Courier. If
a socket exists but a connection cannot be established then the message is not
accepted, and a temporary failure indication is returned. That's why no mail
will be accepted unless all installed mail filters are running.
Mail recipients that did not whitelist the sender, via the maildrop API, will
have their mail filtered against everything in /var/lib/courier/filters and
/var/lib/courier/allfilters. Mail to recipients that whitelisted the sender,
or mail to destinations that do not use a maildrop API-compatible filter, will
be filtered only against the contents of /var/lib/courier/allfilters.
This gives system administrators a choice whether to install selective, or
mandatory mail filters, or a combination of both.
Many filesystem domain socket implementation are buggy.
Handling of crashed mail filters could be improved.
Available mail filters.
Miscellaneous configuration files.
Installed mail filters.
Which mail sources to filter.
- maildrop filtering API