1<!doctype html public "-//W3C//DTD HTML 4.01 Transitional//EN"
2        "http://www.w3.org/TR/html4/loose.dtd">
3
4<html>
5
6<head>
7
8<title>Postfix before-queue Milter support </title>
9
10<meta http-equiv="Content-Type" content="text/html; charset=us-ascii">
11
12</head>
13
14<body>
15
16<h1><img src="postfix-logo.jpg" width="203" height="98" ALT="">Postfix before-queue Milter support </h1>
17
18<hr>
19
20<h2>Introduction</h2>
21
22<p> Postfix implements support for the Sendmail version 8 Milter
23(mail filter) protocol. This protocol is used by applications that
24run outside the MTA to inspect SMTP events (CONNECT, DISCONNECT),
25SMTP commands (HELO, MAIL FROM, etc.) as well as mail content
26(headers and body).  All this happens before mail is queued.  </p>
27
28<p> The reason for adding Milter support to Postfix is that there
29exists a large collection of applications, not only to block unwanted
30mail, but also to verify authenticity (examples: <a
31href="http://www.opendkim.org/">OpenDKIM</a>, <a
32href="http://sourceforge.net/projects/dkim-milter/">DomainKeys
33Identified Mail (DKIM)</a>, <a
34href="http://sourceforge.net/projects/sid-milter/">SenderID+SPF</a> and
35<a href="http://sourceforge.net/projects/dk-milter/">DomainKeys</a>)
36or to digitally sign mail (examples: <a
37href="http://www.opendkim.org/">OpenDKIM</a>, <a
38href="http://sourceforge.net/projects/dkim-milter/">DomainKeys
39Identified Mail (DKIM)</a>, <a
40href="http://sourceforge.net/projects/dk-milter/">DomainKeys</a>).
41Having yet another Postfix-specific version of all that software
42is a poor use of human and system resources. </p>
43
44<p> The Milter protocol has evolved over time, and different Postfix
45versions implement different feature sets.  See the <a
46href="#workarounds">workarounds</a> and <a
47href="#limitations">limitations</a> sections at the end of this
48document for differences between Postfix and Sendmail implementations.
49</p>
50
51<p> This document provides information on the following topics: </p>
52
53<ul>
54
55<li><a href="#plumbing">How Milter applications plug into Postfix </a>
56
57<li><a href="#building">Building Milter applications</a>
58
59<li><a href="#running">Running Milter applications</a>
60
61<li><a href="#config">Configuring Postfix</a>
62
63<li><a href="#workarounds">Workarounds</a>
64
65<li><a href="#limitations">Limitations</a>
66
67</ul>
68
69<h2><a name="plumbing">How Milter applications plug into Postfix </a> </h2>
70
71<p> The Postfix Milter implementation uses two different lists of
72mail filters: one list of filters for SMTP mail only,
73and one list of filters for non-SMTP mail. The two
74lists have different capabilities, which is unfortunate.  Avoiding
75this would require major restructuring of Postfix. </p>
76
77<ul>
78
79<li> <p> The SMTP-only filters handle mail that arrives via the
80Postfix smtpd(8) server. They are typically used to filter unwanted
81mail and to sign mail from authorized SMTP clients. You specify
82SMTP-only Milter applications with the smtpd_milters parameter as
83described in a later section.  Mail that arrives via the Postfix
84smtpd(8) server is not filtered by the non-SMTP filters that are
85described next. </p>
86
87<li> <p> The non-SMTP filters handle mail that arrives via the
88Postfix sendmail(1) command-line or via the Postfix qmqpd(8) server.
89They are typically used to digitally sign mail only. Although
90non-SMTP filters can be used to filter unwanted mail, they have
91limitations compared to the SMTP-only filters. You specify non-SMTP
92Milter applications with the non_smtpd_milters parameter as described
93in a later section.  </p>
94
95</ul>
96
97<p> For those who are familiar with the Postfix architecture, the
98figure below shows how Milter applications plug into Postfix.  Names
99followed by a number are Postfix commands or server programs, while
100unnumbered names inside shaded areas represent Postfix queues.  To
101avoid clutter, the path for local submission is simplified (the
102OVERVIEW document has a more complete description of the Postfix
103architecture).  </p>
104
105<blockquote>
106
107<table>
108
109<tr> 
110
111<td colspan="2"> </td> 
112
113<td align="center"> SMTP-only <br> filters </td> 
114
115<td> </td> 
116
117<td align="center"> non-SMTP <br> filters </td> 
118
119</tr>
120
121<tr> 
122
123<td colspan="2"> </td> 
124
125<td align="center"> <table> <tr> <td align="center">
126^<br> <tt> | </tt> </td> <td align="center"> <tt> |<br> v </tt>
127</td> </tr> </table> </td>
128
129<td rowspan="2"> </td>
130
131<td rowspan="3" align="center"> <table> <tr> <td align="center">
132^<br> <tt> |<br> |<br> | </tt> </td> <td align="center"> <tt> |<br>
133|<br> |<br> v </tt> </td> </tr> </table> </td>
134
135</tr>
136
137<tr>
138
139<td> Network </td> <td> <tt> -&gt; </tt> </td>
140
141<td bgcolor="#f0f0ff" align="center" valign="middle"> smtpd(8)
142</td>
143
144</tr>
145
146<tr>
147
148<td colspan="3"> </td> <td> <tt> \ </tt> </td>
149
150</tr>
151
152<tr>
153
154<td> Network </td> <td> <tt> -&gt; </tt> </td>
155
156<td bgcolor="#f0f0ff" align="center" valign="middle"> qmqpd(8)
157</td>
158
159<td> <tt> -&gt; </tt> </td>
160
161<td bgcolor="#f0f0ff" align="center" valign="middle"> cleanup(8)
162</td>
163
164<td> <tt> -&gt; </tt> </td>
165
166<td bgcolor="#f0f0ff" align="center" valign="middle"> <a
167href="QSHAPE_README.html#incoming_queue"> incoming </a> </td>
168
169</tr>
170
171<tr>
172
173<td colspan="3"> </td> <td> <tt> / </tt> </td>
174
175</tr>
176
177<tr>
178
179<td colspan="2"> </td>
180
181<td bgcolor="#f0f0ff" align="center" valign="middle"> pickup(8)
182</td>
183
184</tr>
185
186<tr> <td colspan="2"> </td> <td align="center"> : </td> </tr>
187
188<tr>
189
190<td> Local </td> <td> <tt> -&gt; </tt> </td>
191
192<td bgcolor="#f0f0ff" align="center" valign="middle"> sendmail(1)
193</td>
194
195</tr>
196
197</table>
198
199</blockquote>
200
201<h2><a name="building">Building Milter applications</a></h2>
202
203<p> Milter applications have been written in C, JAVA and Perl, but
204this document deals with C applications only.   For these, you need
205an object library that implements the Sendmail 8 Milter protocol.
206Postfix currently does not provide such a library, but Sendmail
207does. </p>
208
209<ul>
210
211<li> <p> The first option is to use a pre-compiled library. Some
212systems install the Sendmail libmilter library by default.  With
213other systems, libmilter may be provided by a package (called
214"sendmail-devel" on some Linux systems).  </p>
215
216<p> Once libmilter is installed, applications such as <a
217href="http://www.opendkim.org/">OpenDKIM</a>, <a
218href="http://sourceforge.net/projects/dkim-milter/">dkim-milter</a> and
219<a href="http://sourceforge.net/projects/sid-milter/">sid-milter</a>
220build out of the box without requiring any tinkering:</p>
221
222<blockquote>
223<pre>
224$ <b>gzcat opendkim-<i>x.y.z</i>.tar.gz | tar xf -</b>
225$ <b>cd opendkim-<i>x.y.z</i></b>
226$ <b>/configure ...<i>options</i>...</b>
227$ <b>make</b>
228[...<i>lots of output omitted</i>...]
229$ <b>make install</b>
230</pre>
231</blockquote>
232
233<blockquote>
234<pre>
235$ <b>gzcat dkim-milter-<i>x.y.z</i>.tar.gz | tar xf -</b>
236$ <b>cd dkim-milter-<i>x.y.z</i></b>
237$ <b>make</b>
238[...<i>lots of output omitted</i>...]
239</pre>
240</blockquote>
241
242<li> <p> The other option is to build the libmilter library from
243Sendmail source code: </p>
244
245<blockquote>
246<pre>
247$ <b>gzcat sendmail-<i>x.y.z</i>.tar.gz | tar xf -</b>
248$ <b>cd sendmail-<i>x.y.z</i>/libmilter</b>
249$ <b>make</b>
250[...<i>lots of output omitted</i>...]
251</pre>
252</blockquote>
253
254<p> After building your own libmilter library, follow the installation
255instructions in the Milter application source distribution to specify
256the location of the libmilter include files and object library.
257Typically, these settings are configured in a file named
258<tt>sid-filter/Makefile.m4</tt> or similar:
259
260<blockquote>
261<pre>
262APPENDDEF(`confINCDIRS', `-I/some/where/sendmail-x.y.z/include')
263APPENDDEF(`confLIBDIRS', `-L/some/where/sendmail-x.y.z/obj.<i>systemtype</i>/libmilter')
264</pre>
265</blockquote>
266
267<p>Then build the Milter application. </p>
268
269</ul>
270
271<h2><a name="running">Running Milter applications</a></h2>
272
273<p> To run a Milter application, see the documentation of the filter
274for options.  A typical command looks like this:</p>
275
276<blockquote>
277<pre>
278# <b>/some/where/dkim-filter -u <i>userid</i> -p inet:<i>portnumber</i>@localhost ...<i>other options</i>...</b>
279</pre>
280</blockquote>
281
282<p> Please specify a <i>userid</i> value that isn't used for other
283applications (not "postfix", not "www", etc.). </p>
284
285<h2><a name="config">Configuring Postfix</a></h2>
286
287<p> Like Sendmail, Postfix has a lot of configuration options that
288control how it talks to Milter applications. With the initial Postfix
289Milter protocol implementation, many options are global, that is,
290they apply to all Milter applications. Future Postfix versions may
291support per-Milter timeouts, per-Milter error handling, etc. </p>
292
293<p> Information in this section: </p>
294
295<ul>
296
297<li><a href="#smtp-only-milters">SMTP-Only Milter applications </a>
298
299<li><a href="#non-smtp-milters">Non-SMTP Milter applications </a>
300
301<li><a href="#errors">Milter error handling </a>
302
303<li><a href="#version">Milter protocol version</a>
304
305<li><a href="#timeouts">Milter protocol timeouts</a>
306
307<li><a href="#macros">Sendmail macro emulation</a>
308
309</ul>
310
311<h3><a name="smtp-only-milters">SMTP-Only Milter applications</a></h3>
312
313<p>  The SMTP-only Milter applications handle mail that arrives via
314the Postfix smtpd(8) server. They are typically used to filter
315unwanted mail, and to sign mail from authorized SMTP clients.  Mail
316that arrives via the Postfix smtpd(8) server is not filtered by the
317non-SMTP filters that are described in the next section. </p>
318
319<p> NOTE: Do not use the header_checks(5) IGNORE action to remove
320Postfix's own Received: message header. This causes problems with
321mail signing filters. Instead, keep Postfix's own Received: message
322header and use the header_checks(5) REPLACE action to sanitize
323information. </p>
324
325<p> You specify SMTP-only Milter applications (there can be more
326than one) with the smtpd_milters parameter.  Each Milter application
327is identified by the name of its listening socket; other Milter
328configuration options will be discussed in later sections.  Milter
329applications are applied in the order as specified, and the first
330Milter application that rejects a command will override the responses
331from other Milter applications.  </p>
332
333<blockquote>
334<pre>
335/etc/postfix/main.cf:
336    # Milters for mail that arrives via the smtpd(8) server.
337    # See below for socket address syntax.
338    smtpd_milters = inet:localhost:<i>portnumber</i> ...<i>other filters</i>...
339</pre>
340</blockquote>
341
342<p> The general syntax for listening sockets is as follows: </p>
343
344<blockquote>
345
346<dl>
347
348<dt> <b>unix:</b><i>pathname</i> </dt> <dd><p>Connect to the local
349UNIX-domain server that is bound to the specified pathname. If the
350smtpd(8) or cleanup(8) process runs chrooted, an absolute pathname
351is interpreted relative to the Postfix queue directory.</p> </dd>
352
353<dt> <b> inet:</b><i>host</i><b>:</b><i>port</i> </dt> <dd> <p>
354Connect to the specified TCP port on the specified local or remote
355host.  The host and port can be specified in numeric or symbolic
356form.</p>
357
358<p> NOTE: Postfix syntax differs from Milter syntax which has the
359form <b>inet:</b><i>port</i><b>@</b><i>host</i>. </p>  </dd>
360
361</dl>
362
363</blockquote>
364
365<h3> <a name="non-smtp-milters">Non-SMTP Milter applications </a> </h3>
366
367<p> The non-SMTP Milter applications handle mail that arrives via
368the Postfix sendmail(1) command-line or via the Postfix qmqpd(8)
369server. They are typically used to digitally sign mail. Although
370non-SMTP filters can be used to filter unwanted mail, there are
371limitations as discussed later in this section.  Mail that arrives
372via the Postfix smtpd(8) server is not filtered by the non-SMTP
373filters.  </p>
374
375<p> NOTE: Do not use the header_checks(5) IGNORE action to remove
376Postfix's own Received: message header. This causes problems with
377mail signing filters. Instead, keep Postfix's own Received: message
378header and use the header_checks(5) REPLACE action to sanitize
379information. </p>
380
381<p> You specify non-SMTP Milter applications with the non_smtpd_milters
382parameter. This parameter uses the same syntax as the smtpd_milters
383parameter in the previous section. As with the SMTP-only filters,
384you can specify more than one Milter application; they are applied
385in the order as specified, and the first Milter application that
386rejects a command will override the responses from the other
387applications.  </p>
388
389<blockquote>
390<pre>
391/etc/postfix/main.cf:
392    # Milters for non-SMTP mail.
393    # See below for socket address syntax.
394    non_smtpd_milters = inet:localhost:<i>portnumber</i> ...<i>other filters</i>...
395</pre>
396</blockquote>
397
398<p> There's one small complication when using Milter applications
399for non-SMTP mail: there is no SMTP session.  To keep Milter
400applications happy, the Postfix cleanup(8) server actually has to
401simulate the SMTP client CONNECT and DISCONNECT events, and the
402SMTP client EHLO, MAIL FROM, RCPT TO and DATA commands. </p>
403
404<ul>
405
406<li> <p> When new mail arrives via the sendmail(1) command line,
407the Postfix cleanup(8) server pretends that the mail arrives with
408ESMTP from "localhost" with IP address "127.0.0.1". The result is
409very similar to what happens with command line submissions in
410Sendmail version 8.12 and later, although Sendmail uses a different
411mechanism to achieve this result.  </p>
412
413<li> <p> When new mail arrives via the qmqpd(8) server, the Postfix
414cleanup(8) server pretends that the mail arrives with ESMTP, and
415uses the QMQPD client hostname and IP address. </p>
416
417<li> <p> When old mail is re-injected into the queue with "postsuper
418-r", the Postfix cleanup(8) server uses the same client information
419that was used when the mail arrived as new mail. </p>
420
421</ul>
422
423<p> This generally works as expected, with only one exception:
424non-SMTP filters must not REJECT or TEMPFAIL simulated RCPT TO
425commands.  When a non_smtpd_milters application REJECTs or TEMPFAILs
426a recipient, Postfix will report a configuration error, and mail
427will stay in the queue.  </p>
428
429<p> None of this is a problem for mail filters that digitally sign
430mail. </p>
431
432<h3><a name="errors">Milter error handling</a></h3>
433
434<p> The milter_default_action parameter specifies how Postfix handles
435Milter application errors. The default action is to respond with a
436temporary error status, so that the client will try again later.
437Specify "accept" if you want to receive mail as if the filter does
438not exist, and "reject" to reject mail with a permanent status.
439The "quarantine" action is like "accept" but freezes the message
440in the "hold" queue, and is available with Postfix 2.6 or later.
441</p>
442
443<blockquote>
444<pre>
445/etc/postfix/main.cf:
446    # What to do in case of errors? Specify accept, reject, tempfail,
447    # or quarantine (Postfix 2.6 or later).
448    milter_default_action = tempfail
449</pre>
450</blockquote>
451
452<h3><a name="version">Milter protocol version</a></h3>
453
454<p> As Postfix is not built with the Sendmail libmilter library,
455you may need to configure the Milter protocol version that Postfix
456should use.  The default version is 6 (before Postfix 2.6 the default
457version is 2). </p>
458
459<blockquote>
460<pre>
461/etc/postfix/main.cf:
462    # Postfix &ge; 2.6
463    milter_protocol = 6
464    # 2.3 &le; Postfix &le; 2.5
465    milter_protocol = 2
466</pre>
467</blockquote>
468
469<p> If the Postfix milter_protocol setting specifies a too low
470version, the libmilter library will log an error message like this:
471</p>
472
473<blockquote>
474<pre>
475<i>application name</i>: st_optionneg[<i>xxxxx</i>]: 0x<i>yy</i> does not fulfill action requirements 0x<i>zz</i>
476</pre>
477</blockquote>
478
479<p> The remedy is to increase the Postfix milter_protocol version
480number.  See, however, the <a href="#limitations">limitations</a>
481section below for features that aren't supported by Postfix. </p>
482
483<p> With Postfix 2.7 and earlier, if the Postfix milter_protocol
484setting specifies a too high
485version, the libmilter library simply hangs up without logging a
486warning, and you see a Postfix warning message like one of the
487following: </p>
488
489<blockquote>
490<pre>
491warning: milter inet:<i>host</i>:<i>port</i>: can't read packet header: Unknown error : 0
492warning: milter inet:<i>host</i>:<i>port</i>: can't read packet header: Success
493warning: milter inet:<i>host</i>:<i>port</i>: can't read SMFIC_DATA reply packet header: No such file or directory
494</pre>
495</blockquote>
496
497<p> The remedy is to lower the Postfix milter_protocol version
498number. Postfix 2.8 and later will automatically turn off protocol
499features that the application's libmilter library does not expect.
500</p>
501
502<h3><a name="timeouts">Milter protocol timeouts</a></h3>
503
504<p> Postfix uses different time limits at different Milter protocol
505stages. The table shows the timeout settings and the corresponding
506protocol stages
507(EOH = end of headers; EOM = end of message).  </p>
508
509<blockquote>
510
511<table border="1">
512
513<tr> <th> Postfix parameter </th> <th> Time limit </th> <th> Milter
514protocol stage</th> </tr>
515
516<tr> <td> milter_connect_timeout </td> <td> 30s </td> <td> CONNECT
517</td> </tr>
518
519<tr> <td> milter_command_timeout </td> <td> 30s </td> <td> HELO,
520MAIL, RCPT, DATA, UNKNOWN </td> </tr>
521
522<tr> <td> milter_content_timeout </td> <td> 300s </td> <td> HEADER,
523EOH, BODY, EOM </td> </tr>
524
525</table>
526
527</blockquote>
528
529<p> Beware: 30s may be too short for Milter applications that do
530lots of DNS lookups.  However, if you increase the above timeouts
531too much, remote SMTP clients may hang up and mail may be delivered
532multiple times. This is an inherent problem with before-queue
533filtering. </p>
534
535<h3><a name="macros">Sendmail macro emulation</a></h3>
536
537<p> Postfix emulates a limited number of Sendmail macros, as shown
538in the table. Some macro values depend on whether a recipient is
539rejected (rejected recipients are available on request by the Milter
540application). Different macros are available at different Milter
541protocol stages (EOH = end-of-header, EOM = end-of-message); their
542availability is not
543always the same as in Sendmail. See the <a
544href="#workarounds">workarounds</a> section below for solutions.
545</p>
546
547<blockquote>
548
549<table border="1">
550
551<tr> <th> Sendmail macro </th> <th> Milter protocol stage </th>
552<th> Description </th> </tr>
553
554<tr> <td> i </td> <td> DATA, EOH, EOM </td> <td> Queue ID, also
555Postfix queue file name </td> </tr>
556
557<tr> <td> j </td> <td> Always </td> <td> Value of myhostname </td>
558</tr>
559
560<tr> <td> _ </td> <td> Always </td> <td> The validated client name
561and address </td> </tr>
562
563<tr> <td> {auth_authen} </td> <td> MAIL, DATA, EOH, EOM </td> <td> SASL
564login name </td> </tr>
565
566<tr> <td> {auth_author} </td> <td> MAIL, DATA, EOH, EOM </td> <td> SASL
567sender </td> </tr>
568
569<tr> <td> {auth_type} </td> <td> MAIL, DATA, EOH, EOM </td> <td> SASL
570login method </td> </tr>
571
572<tr> <td> {client_addr} </td> <td> Always </td> <td> Client IP
573address </td> </tr>
574
575<tr> <td> {client_connections} </td> <td> CONNECT </td> <td>
576Connection concurrency for this client (zero if the client is
577excluded from all smtpd_client_* limits). </td> </tr>
578
579<tr> <td> {client_name} </td> <td> Always </td> <td> Client hostname
580<br> When address &rarr; name lookup or name &rarr; address
581verification fails: "unknown" </td> </tr>
582
583<tr> <td> {client_port} </td> <td> Always (Postfix &ge;2.5) </td>
584<td> Client TCP port </td> </tr>
585
586<tr> <td> {client_ptr} </td> <td> CONNECT, HELO, MAIL, DATA </td>
587<td> Client name from address &rarr; name lookup <br> When address
588&rarr; name lookup fails: "unknown" </td> </tr>
589
590<tr> <td> {cert_issuer} </td> <td> HELO, MAIL, DATA, EOH, EOM </td> <td>
591TLS client certificate issuer </td> </tr>
592
593<tr> <td> {cert_subject} </td> <td> HELO, MAIL, DATA, EOH, EOM </td>
594<td> TLS client certificate subject </td> </tr>
595
596<tr> <td> {cipher_bits} </td> <td> HELO, MAIL, DATA, EOH, EOM </td> <td>
597TLS session key size </td> </tr>
598
599<tr> <td> {cipher} </td> <td> HELO, MAIL, DATA, EOH, EOM </td> <td> TLS
600cipher </td> </tr>
601
602<tr> <td> {daemon_name} </td> <td> Always </td> <td> value of
603milter_macro_daemon_name </td> </tr>
604
605<tr> <td> {mail_addr} </td> <td> MAIL </td> <td> Sender address
606</td> </tr>
607
608<tr> <td> {mail_host} </td> <td> MAIL (Postfix &ge; 2.6, only with
609smtpd_milters) </td> <td> Sender next-hop destination </td> </tr>
610
611<tr> <td> {mail_mailer} </td> <td> MAIL (Postfix &ge; 2.6, only with
612smtpd_milters) </td> <td> Sender mail delivery transport </td> </tr>
613
614<tr> <td> {rcpt_addr} </td> <td> RCPT </td> <td> Recipient address
615<br> With rejected recipient: descriptive text </td> </tr>
616
617<tr> <td> {rcpt_host} </td> <td> RCPT (Postfix &ge; 2.6, only with
618smtpd_milters) </td> <td> Recipient next-hop destination <br> With
619rejected recipient: enhanced status code </td> </tr>
620
621<tr> <td> {rcpt_mailer} </td> <td> RCPT (Postfix &ge; 2.6, only with
622smtpd_milters) </td> <td> Recipient mail delivery transport <br>
623With rejected recipient: "error" </td> </tr>
624
625<tr> <td> {tls_version} </td> <td> HELO, MAIL, DATA, EOH, EOM </td>
626<td> TLS protocol version </td> </tr>
627
628<tr> <td> v </td> <td> Always </td> <td> value of milter_macro_v
629</td> </tr>
630
631</table>
632
633</blockquote>
634
635<p> Postfix sends specific sets of macros at different Milter protocol
636stages.  The sets are configured with the parameters as described
637in the table (EOH = end of headers; EOM = end of message). The
638protocol version is a number that Postfix sends at the beginning
639of the Milter protocol handshake. </p>
640
641<p> As of Sendmail 8.14.0, Milter applications can specify what
642macros they want to receive at different Milter protocol stages.
643An application-specified list takes precedence over a Postfix-specified
644list. </p>
645
646<blockquote>
647
648<table border="1">
649
650<tr> <th> Postfix parameter </th> <th> Milter protocol version </th>
651<th> Milter protocol stage </th> </tr>
652
653<tr> <td> milter_connect_macros </td> <td> 2 or higher </td> <td>
654CONNECT </td> </tr>
655
656<tr> <td> milter_helo_macros </td> <td> 2 or higher </td> <td>
657HELO/EHLO </td> </tr>
658
659<tr> <td> milter_mail_macros </td> <td> 2 or higher </td> <td> MAIL
660FROM </td> </tr>
661
662<tr> <td> milter_rcpt_macros </td> <td> 2 or higher </td> <td> RCPT
663TO </td> </tr>
664
665<tr> <td> milter_data_macros </td> <td> 4 or higher </td> <td> DATA
666</td> </tr>
667
668<tr> <td> milter_end_of_header_macros </td> <td> 6 or higher </td>
669<td> EOH </td> </tr>
670
671<tr> <td> milter_end_of_data_macros </td> <td> 2 or higher </td>
672<td> EOM </td> </tr>
673
674<tr> <td> milter_unknown_command_macros </td> <td> 3 or higher </td>
675<td> unknown command </td> </tr>
676
677</table>
678
679</blockquote>
680
681<h2><a name="workarounds">Workarounds</a></h2>
682
683<ul>
684
685<li> <p> To avoid breaking DKIM etc. signatures with an SMTP-based
686content filter, update the before-filter SMTP client in master.cf,
687and add a line with "-o disable_mime_output_conversion=yes" (note:
688no spaces around the "="). For details, see the <a
689href="FILTER_README.html#advanced_filter">advanced content filter</a>
690example. </p>
691
692<pre>
693/etc/postfix/master.cf:
694    # =============================================================
695    # service type  private unpriv  chroot  wakeup  maxproc command
696    #               (yes)   (yes)   (yes)   (never) (100)
697    # =============================================================
698    scan      unix  -       -       n       -       10      smtp
699        -o smtp_send_xforward_command=yes
700        -o disable_mime_output_conversion=yes
701        -o smtp_generic_maps=
702</pre>
703
704<li> <p> Some Milter applications use the "<tt>{if_addr}</tt>" macro
705to recognize local mail; this macro does not exist in Postfix.
706Workaround: use the "<tt>{client_addr}</tt>" macro instead. </p>
707
708<li> <p> Some Milter applications log a warning that looks like
709this: </p>
710
711<blockquote> <pre>
712sid-filter[36540]: WARNING: sendmail symbol 'i' not available
713</pre>
714</blockquote>
715
716<p> And they may insert an ugly message header with "unknown-msgid"
717like this: </p>
718
719<blockquote>
720<pre>
721X-SenderID: Sendmail Sender-ID Filter vx.y.z host.example.com &lt;unknown-msgid&gt;
722</pre>
723</blockquote>
724
725<p> The problem is that Milter applications expect that the queue
726ID is known <i>before</i> the MTA accepts the MAIL FROM (sender)
727command.  Postfix does not choose a queue ID, which is used as the
728queue file name, until <i>after</i> it accepts the first valid RCPT
729TO (recipient) command. </p>
730
731<p> If you experience the ugly header problem, see if a recent
732version of the Milter application fixes it. For example, current
733versions of dkim-filter and dk-filter already have code that looks
734up the Postfix queue ID at a later protocol stage, and sid-filter
735version 1.0.0 no longer includes the queue ID in the message header.
736</p>
737
738<p> To fix the ugly message header, you will need to add code that
739looks up the Postfix queue ID at some later point in time. The
740example below adds the lookup after the end-of-message.  </p>
741
742<ul>
743
744<li> <p> Edit the filter source file (typically named
745<tt>xxx-filter/xxx-filter.c</tt> or similar). </p>
746
747<li> <p> Look up the <tt>mlfi_eom()</tt> function and add code near
748the top shown as <b>bold</b> text below: </p>
749
750</ul>
751
752<blockquote>
753<pre>
754dfc = cc->cctx_msg;
755assert(dfc != NULL);
756<b>
757/* Determine the job ID for logging. */
758if (dfc->mctx_jobid == 0 || strcmp(dfc->mctx_jobid, JOBIDUNKNOWN) == 0) {
759        char *jobid = smfi_getsymval(ctx, "i");
760        if (jobid != 0)
761                dfc->mctx_jobid = jobid;
762}</b>
763</pre>
764</blockquote>
765
766<p> NOTES: </p>
767
768<ul>
769
770<li> <p> Different mail filters use slightly different names for
771variables. If the above code does not compile, look elsewhere in
772the mail filter source file for code that looks up the "i" macro
773value, and copy that code.  </p>
774
775<li> <p> This change fixes only the ugly message header, but not
776the WARNING message.  Fortunately, many Milters log that message
777only once. </p>
778
779</ul>
780
781</ul>
782
783<h2><a name="limitations">Limitations</a></h2>
784
785<p> This section lists limitations of the Postfix Milter implementation.
786Some limitations will be removed as the implementation is extended
787over time. Of course the usual limitations of before-queue filtering
788will always apply. See the CONTENT_INSPECTION_README document for
789a discussion. </p>
790
791<ul>
792
793<li> <p> The Milter protocol has evolved over time. Therefore,
794different Postfix versions implement different feature sets. </p>
795
796<table border="1">
797
798<tr> <th> Postfix </th> <th> Supported Milter requests </th>
799</tr>
800
801<tr> <td align="center"> 2.6 </td> <td> All Milter requests of
802Sendmail 8.14.0 (see notes below).  </td> </tr>
803
804<tr> <td align="center"> 2.5 </td> <td> All Milter requests of
805Sendmail 8.14.0, except: <br> SMFIP_RCPT_REJ (report rejected
806recipients to the mail filter), <br> SMFIR_CHGFROM (replace sender,
807with optional ESMTP parameters), <br> SMFIR_ADDRCPT_PAR (add
808recipient, with optional ESMTP parameters). </td> </tr>
809
810<tr> <td align="center"> 2.4 </td> <td> All Milter requests of
811Sendmail 8.13.0.  </td> </tr>
812
813<tr> <td align="center"> 2.3 </td> <td> All Milter requests of
814Sendmail 8.13.0, except: <br> SMFIR_REPLBODY (replace message body).
815
816</table>
817
818<li> <p> For Milter applications that are written in C, you need
819to use the Sendmail libmilter library. </p>
820
821<li> <p> Postfix has TWO sets of mail filters: filters that are used
822for SMTP mail only (specified with the smtpd_milters parameter),
823and filters for non-SMTP mail (specified with the non_smtpd_milters
824parameter).  The non-SMTP filters are primarily for local submissions.
825</p>
826
827<p> When mail is filtered by non_smtpd_milters, the Postfix cleanup(8)
828server has to simulate SMTP client requests.  This works as expected,
829with only one exception: non_smtpd_milters must not REJECT or
830TEMPFAIL simulated RCPT TO commands. When this rule is violated,
831Postfix will report a configuration error, and mail will stay in
832the queue.  </p>
833
834<li> <p> Postfix currently does not apply content filters to mail
835that is forwarded or aliased internally, or to mail that is generated
836internally such as bounces or Postmaster notifications. This may
837be a problem when you want to apply a signing Milter to such mail.
838</p>
839
840<li> <p> When you use the before-queue content filter for incoming
841SMTP mail (see SMTPD_PROXY_README), Milter applications have access
842only to the SMTP command information; they have no access to the
843message header or body, and cannot make modifications to the message
844or to the envelope. </p>
845
846<li> <p> Postfix 2.6 ignores the optional ESMTP parameters in
847requests to replace the sender (SMFIR_CHGFROM) or to append a
848recipient (SMFIR_ADDRCPT_PAR). Postfix logs a warning message when
849a Milter application supplies such ESMTP parameters: </p>
850
851<pre>
852warning: <i>queue-id</i>: cleanup_chg_from: ignoring ESMTP arguments "<i>whatever</i>"
853warning: <i>queue-id</i>: cleanup_add_rcpt: ignoring ESMTP arguments "<i>whatever</i>"
854</pre>
855
856<li> <p> Postfix 2.3 does not implement requests to replace the
857message body. Milter applications log a warning message when they
858need this unsupported operation: </p>
859
860<pre>
861st_optionneg[134563840]: 0x3d does not fulfill action requirements 0x1e
862</pre>
863
864<p> The solution is to use Postfix version 2.4 or later. </p>
865
866<li> <p> Most Milter configuration options are global. Future Postfix
867versions may support per-Milter timeouts, per-Milter error handling,
868etc. </p>
869
870</ul>
871
872</body>
873
874</html>
875