2 # Copyright 2006 Sun Microsystems, Inc. All rights reserved.
3 # Use is subject to license terms.
5 # ident "%Z%%M% %I% %E% SMI"
8 The sendmail Mail Filter API (Milter) is designed to allow third-party
9 programs access to mail messages as they are being processed in order to
10 filter meta-information and content.
12 This README file describes the steps needed to compile and run a filter,
13 through reference to a sample filter which is attached at the end of this
16 Note: if you want to write a milter in Java, then see
17 http://sendmail-jilter.sourceforge.net/
23 Note: we strongly recommend not to run any milter as root. Libmilter
24 does not need root access to communicate with sendmail. It is a
25 good security practice to run a program only with root privileges
26 if really necessary. A milter should probably check first whether
27 it runs as root and refuse to start in that case. libmilter will
28 not unlink a socket when running as root.
34 The following command presumes that the sample code from the end of this
35 README is saved to a file named 'sample.c'.
37 cc -D_REENTRANT -o sample sample.c -lmilter
39 Filters must be thread-safe!
41 Note that since filters use threads, it may be necessary to alter per
42 process limits in your filter. For example, you might look at using
43 setrlimit() to increase the number of open file descriptors if your filter
47 +----------------------------------------+
48 | SPECIFYING FILTERS IN SENDMAIL CONFIGS |
49 +----------------------------------------+
51 Filters are specified with a key letter ``X'' (for ``eXternal'').
55 Xfilter1, S=local:/var/run/f1.sock, F=R
56 Xfilter2, S=inet6:999@localhost, F=T, T=C:10m;S:1s;R:1s;E:5m
57 Xfilter3, S=inet:3333@localhost
59 specifies three filters. Filters can be specified in your .mc file using
62 INPUT_MAIL_FILTER(`filter1', `S=local:/var/run/f1.sock, F=R')
63 INPUT_MAIL_FILTER(`filter2', `S=inet6:999@localhost, F=T, T=C:10m;S:1s;R:1s;E:5m')
64 INPUT_MAIL_FILTER(`filter3', `S=inet:3333@localhost')
66 The first attaches to a Unix-domain socket in the /var/run directory; the
67 second uses an IPv6 socket on port 999 of localhost, and the third uses an
68 IPv4 socket on port 3333 of localhost. The current flags (F=) are:
70 R Reject connection if filter unavailable
71 T Temporary fail connection if filter unavailable
72 4 Shut down connection if filter unavailable
73 (with a 421 temporary error).
75 If none of these is specified, the message is passed through sendmail
76 in case of filter errors as if the failing filters were not present.
78 Finally, you can override the default timeouts used by sendmail when
79 talking to the filters using the T= equate. There are four fields inside
83 C Timeout for connecting to a filter (if 0, use system timeout)
84 S Timeout for sending information from the MTA to a filter
85 R Timeout for reading reply from the filter
86 E Overall timeout between sending end-of-message to filter
87 and waiting for the final acknowledgment
89 Note the separator between each is a ';' as a ',' already separates equates
90 and therefore can't separate timeouts. The default values (if not set in
93 T=C:5m;S:10s;R:10s;E:5m
95 where 's' is seconds and 'm' is minutes.
97 Which filters are invoked and their sequencing is handled by the
98 InputMailFilters option. Note: if InputMailFilters is not defined no filters
101 O InputMailFilters=filter1, filter2, filter3
103 This is is set automatically according to the order of the
104 INPUT_MAIL_FILTER commands in your .mc file. Alternatively, you can
105 reset its value by setting confINPUT_MAIL_FILTERS in your .mc file.
106 This options causes the three filters to be called in the same order
107 they were specified. It allows for possible future filtering on output
108 (although this is not intended for this release).
110 Also note that a filter can be defined without adding it to the input
111 filter list by using MAIL_FILTER() instead of INPUT_MAIL_FILTER() in your
114 To test sendmail with the sample filter, the following might be added (in
115 the appropriate locations) to your .mc file:
117 INPUT_MAIL_FILTER(`sample', `S=local:/var/run/f1.sock')
124 Once you have compiled a filter, modified your .mc file and restarted
125 the sendmail process, you will want to test that the filter performs as
128 The sample filter takes one argument -p, which indicates the local port
129 on which to create a listening socket for the filter. Maintaining
130 consistency with the suggested options for sendmail.cf, this would be the
131 UNIX domain socket located in /var/run/f1.sock.
133 % ./sample -p local:/var/run/f1.sock
135 If the sample filter returns immediately to a command line, there was either
136 an error with your command or a problem creating the specified socket.
137 Further logging can be captured through the syslogd daemon. Using the
138 'netstat -a' command can ensure that your filter process is listening on
139 the appropriate local socket.
141 Email messages must be injected via SMTP to be filtered. There are two
142 simple means of doing this; either using the 'sendmail -bs' command, or
143 by telnetting to port 25 of the machine configured for milter. Once
144 connected via one of these options, the session can be continued through
145 the use of standard SMTP commands.
148 220 test.sendmail.com ESMTP Sendmail 8.14.0/8.14.0; Thu, 22 Jun 2006 13:05:23 -0500 (EST)
150 250 test.sendmail.com Hello testy@localhost, pleased to meet you
152 250 2.1.0 <testy>... Sender ok
154 250 2.1.5 <root>... Recipient ok
156 354 Enter mail, end with "." on a line by itself
157 From: testy@test.sendmail.com
158 To: root@test.sendmail.com
159 Subject: testing sample filter
163 250 2.0.0 dB73Zxi25236 Message accepted for delivery
165 221 2.0.0 test.sendmail.com closing connection
167 In the above example, the lines beginning with numbers are output by the
168 mail server, and those without are your input. If everything is working
169 properly, you will find a file in /tmp by the name of msg.XXXXXXXX (where
170 the Xs represent any combination of letters and numbers). This file should
171 contain the message body and headers from the test email entered above.
173 If the sample filter did not log your test email, there are a number of
174 methods to narrow down the source of the problem. Check your system
175 logs written by syslogd and see if there are any pertinent lines. You
176 may need to reconfigure syslogd to capture all relevant data. Additionally,
177 the logging level of sendmail can be raised with the LogLevel option.
178 See the sendmail(8) manual page for more information.
181 $Revision: 8.42 $, Last updated $Date: 2006/06/29 17:10:16 $