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