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://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 <a href="smtpd.8.html">smtpd(8)</a> 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 <a href="postconf.5.html#smtpd_milters">smtpd_milters</a> parameter as
81described in a later section.  Mail that arrives via the Postfix
82<a href="smtpd.8.html">smtpd(8)</a> 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 <a href="sendmail.1.html">sendmail(1)</a> command-line or via the Postfix <a href="qmqpd.8.html">qmqpd(8)</a> 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 <a href="postconf.5.html#non_smtpd_milters">non_smtpd_milters</a> 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
100<a href="OVERVIEW.html">OVERVIEW</a> 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"> <a href="smtpd.8.html">smtpd(8)</a>
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"> <a href="qmqpd.8.html">qmqpd(8)</a>
155</td>
156
157<td> <tt> -&gt; </tt> </td>
158
159<td bgcolor="#f0f0ff" align="center" valign="middle"> <a href="cleanup.8.html">cleanup(8)</a>
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"> <a href="pickup.8.html">pickup(8)</a>
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"> <a href="sendmail.1.html">sendmail(1)</a>
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 <a href="smtpd.8.html">smtpd(8)</a> server. They are typically used to filter
301unwanted mail, and to sign mail from authorized SMTP clients.  Mail
302that arrives via the Postfix <a href="smtpd.8.html">smtpd(8)</a> 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 <a href="header_checks.5.html">header_checks(5)</a> 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 <a href="header_checks.5.html">header_checks(5)</a> REPLACE action to sanitize
309information. </p>
310
311<p> You specify SMTP-only Milter applications (there can be more
312than one) with the <a href="postconf.5.html#smtpd_milters">smtpd_milters</a> 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/<a href="postconf.5.html">main.cf</a>:
322    # Milters for mail that arrives via the <a href="smtpd.8.html">smtpd(8)</a> server.
323    # See below for socket address syntax.
324    <a href="postconf.5.html#smtpd_milters">smtpd_milters</a> = 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
336<a href="smtpd.8.html">smtpd(8)</a> or <a href="cleanup.8.html">cleanup(8)</a> 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 <a href="sendmail.1.html">sendmail(1)</a> command-line or via the Postfix <a href="qmqpd.8.html">qmqpd(8)</a>
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 <a href="smtpd.8.html">smtpd(8)</a> server is not filtered by the non-SMTP
359filters.  </p>
360
361<p> NOTE: Do not use the <a href="header_checks.5.html">header_checks(5)</a> 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 <a href="header_checks.5.html">header_checks(5)</a> REPLACE action to sanitize
365information. </p>
366
367<p> You specify non-SMTP Milter applications with the <a href="postconf.5.html#non_smtpd_milters">non_smtpd_milters</a>
368parameter. This parameter uses the same syntax as the <a href="postconf.5.html#smtpd_milters">smtpd_milters</a>
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/<a href="postconf.5.html">main.cf</a>:
378    # Milters for non-SMTP mail.
379    # See below for socket address syntax.
380    <a href="postconf.5.html#non_smtpd_milters">non_smtpd_milters</a> = 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 <a href="cleanup.8.html">cleanup(8)</a> 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 <a href="sendmail.1.html">sendmail(1)</a> command line,
393the Postfix <a href="cleanup.8.html">cleanup(8)</a> 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 <a href="qmqpd.8.html">qmqpd(8)</a> server, the Postfix
400<a href="cleanup.8.html">cleanup(8)</a> 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 <a href="cleanup.8.html">cleanup(8)</a> 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 <a href="postconf.5.html#non_smtpd_milters">non_smtpd_milters</a> 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 <a href="postconf.5.html#milter_default_action">milter_default_action</a> 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 "<a href="QSHAPE_README.html#hold_queue">hold" queue</a>, and is available with Postfix 2.6 or later.
427</p>
428
429<blockquote>
430<pre>
431/etc/postfix/<a href="postconf.5.html">main.cf</a>:
432    # What to do in case of errors? Specify accept, reject, tempfail,
433    # or quarantine (Postfix 2.6 or later).
434    <a href="postconf.5.html#milter_default_action">milter_default_action</a> = 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/<a href="postconf.5.html">main.cf</a>:
448    # Postfix &ge; 2.6
449    <a href="postconf.5.html#milter_protocol">milter_protocol</a> = 6
450    # 2.3 &le; Postfix &le; 2.5
451    <a href="postconf.5.html#milter_protocol">milter_protocol</a> = 2
452</pre>
453</blockquote>
454
455<p> If the Postfix <a href="postconf.5.html#milter_protocol">milter_protocol</a> 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 <a href="postconf.5.html#milter_protocol">milter_protocol</a> version
466number.  See, however, the <a href="#limitations">limitations</a>
467section below for features that aren't supported by Postfix. </p>
468
469<p> If the Postfix <a href="postconf.5.html#milter_protocol">milter_protocol</a> setting specifies a too high
470version, the libmilter library simply hangs up without logging a
471warning, and you see a Postfix warning message like one of the
472following: </p>
473
474<blockquote>
475<pre>
476warning: milter inet:<i>host</i>:<i>port</i>: can't read packet header: Unknown error : 0
477warning: milter inet:<i>host</i>:<i>port</i>: can't read packet header: Success
478warning: milter inet:<i>host</i>:<i>port</i>: can't read SMFIC_DATA reply packet header: No such file or directory
479</pre>
480</blockquote>
481
482<p> The remedy is to lower the Postfix <a href="postconf.5.html#milter_protocol">milter_protocol</a> version
483number. </p>
484
485<h3><a name="timeouts">Milter protocol timeouts</a></h3>
486
487<p> Postfix uses different time limits at different Milter protocol
488stages. The table shows the timeout settings and the corresponding
489protocol stages
490(EOH = end of headers; EOM = end of message).  </p>
491
492<blockquote>
493
494<table border="1">
495
496<tr> <th> Postfix parameter </th> <th> Time limit </th> <th> Milter
497protocol stage</th> </tr>
498
499<tr> <td> <a href="postconf.5.html#milter_connect_timeout">milter_connect_timeout</a> </td> <td> 30s </td> <td> CONNECT
500</td> </tr>
501
502<tr> <td> <a href="postconf.5.html#milter_command_timeout">milter_command_timeout</a> </td> <td> 30s </td> <td> HELO,
503MAIL, RCPT, DATA, UNKNOWN </td> </tr>
504
505<tr> <td> <a href="postconf.5.html#milter_content_timeout">milter_content_timeout</a> </td> <td> 300s </td> <td> HEADER,
506EOH, BODY, EOM </td> </tr>
507
508</table>
509
510</blockquote>
511
512<p> Beware: 30s may be too short for Milter applications that do
513lots of DNS lookups.  However, if you increase the above timeouts
514too much, remote SMTP clients may hang up and mail may be delivered
515multiple times. This is an inherent problem with before-queue
516filtering. </p>
517
518<h3><a name="macros">Sendmail macro emulation</a></h3>
519
520<p> Postfix emulates a limited number of Sendmail macros, as shown
521in the table. Some macro values depend on whether a recipient is
522rejected (rejected recipients are available on request by the Milter
523application). Different macros are available at different Milter
524protocol stages (EOH = end-of-header, EOM = end-of-message); their
525availability is not
526always the same as in Sendmail. See the <a
527href="#workarounds">workarounds</a> section below for solutions.
528</p>
529
530<blockquote>
531
532<table border="1">
533
534<tr> <th> Sendmail macro </th> <th> Milter protocol stage </th>
535<th> Description </th> </tr>
536
537<tr> <td> i </td> <td> DATA, EOH, EOM </td> <td> Queue ID, also
538Postfix queue file name </td> </tr>
539
540<tr> <td> j </td> <td> Always </td> <td> Value of <a href="postconf.5.html#myhostname">myhostname</a> </td>
541</tr>
542
543<tr> <td> _ </td> <td> Always </td> <td> The validated client name
544and address </td> </tr>
545
546<tr> <td> {auth_authen} </td> <td> MAIL, DATA, EOH, EOM </td> <td> SASL
547login name </td> </tr>
548
549<tr> <td> {auth_author} </td> <td> MAIL, DATA, EOH, EOM </td> <td> SASL
550sender </td> </tr>
551
552<tr> <td> {auth_type} </td> <td> MAIL, DATA, EOH, EOM </td> <td> SASL
553login method </td> </tr>
554
555<tr> <td> {client_addr} </td> <td> Always </td> <td> Client IP
556address </td> </tr>
557
558<tr> <td> {client_connections} </td> <td> CONNECT </td> <td>
559Connection concurrency for this client </td> </tr>
560
561<tr> <td> {client_name} </td> <td> Always </td> <td> Client hostname
562<br> When address &rarr; name lookup or name &rarr; address
563verification fails: "unknown" </td> </tr>
564
565<tr> <td> {client_port} </td> <td> Always (Postfix &ge;2.5) </td>
566<td> Client TCP port </td> </tr>
567
568<tr> <td> {client_ptr} </td> <td> CONNECT, HELO, MAIL, DATA </td>
569<td> Client name from address &rarr; name lookup <br> When address
570&rarr; name lookup fails: "unknown" </td> </tr>
571
572<tr> <td> {cert_issuer} </td> <td> HELO, MAIL, DATA, EOH, EOM </td> <td>
573TLS client certificate issuer </td> </tr>
574
575<tr> <td> {cert_subject} </td> <td> HELO, MAIL, DATA, EOH, EOM </td>
576<td> TLS client certificate subject </td> </tr>
577
578<tr> <td> {cipher_bits} </td> <td> HELO, MAIL, DATA, EOH, EOM </td> <td>
579TLS session key size </td> </tr>
580
581<tr> <td> {cipher} </td> <td> HELO, MAIL, DATA, EOH, EOM </td> <td> TLS
582cipher </td> </tr>
583
584<tr> <td> {daemon_name} </td> <td> Always </td> <td> value of
585<a href="postconf.5.html#milter_macro_daemon_name">milter_macro_daemon_name</a> </td> </tr>
586
587<tr> <td> {mail_addr} </td> <td> MAIL </td> <td> Sender address
588</td> </tr>
589
590<tr> <td> {mail_host} </td> <td> MAIL (Postfix &ge; 2.6, only with
591<a href="postconf.5.html#smtpd_milters">smtpd_milters</a>) </td> <td> Sender next-hop destination </td> </tr>
592
593<tr> <td> {mail_mailer} </td> <td> MAIL (Postfix &ge; 2.6, only with
594<a href="postconf.5.html#smtpd_milters">smtpd_milters</a>) </td> <td> Sender mail delivery transport </td> </tr>
595
596<tr> <td> {rcpt_addr} </td> <td> RCPT </td> <td> Recipient address
597<br> With rejected recipient: descriptive text </td> </tr>
598
599<tr> <td> {rcpt_host} </td> <td> RCPT (Postfix &ge; 2.6, only with
600<a href="postconf.5.html#smtpd_milters">smtpd_milters</a>) </td> <td> Recipient next-hop destination <br> With
601rejected recipient: enhanced status code </td> </tr>
602
603<tr> <td> {rcpt_mailer} </td> <td> RCPT (Postfix &ge; 2.6, only with
604<a href="postconf.5.html#smtpd_milters">smtpd_milters</a>) </td> <td> Recipient mail delivery transport <br>
605With rejected recipient: "error" </td> </tr>
606
607<tr> <td> {tls_version} </td> <td> HELO, MAIL, DATA, EOH, EOM </td>
608<td> TLS protocol version </td> </tr>
609
610<tr> <td> v </td> <td> Always </td> <td> value of <a href="postconf.5.html#milter_macro_v">milter_macro_v</a>
611</td> </tr>
612
613</table>
614
615</blockquote>
616
617<p> Postfix sends specific sets of macros at different Milter protocol
618stages.  The sets are configured with the parameters as described
619in the table (EOH = end of headers; EOM = end of message). The
620protocol version is a number that Postfix sends at the beginning
621of the Milter protocol handshake. </p>
622
623<p> As of Sendmail 8.14.0, Milter applications can specify what
624macros they want to receive at different Milter protocol stages.
625An application-specified list takes precedence over a Postfix-specified
626list. </p>
627
628<blockquote>
629
630<table border="1">
631
632<tr> <th> Postfix parameter </th> <th> Milter protocol version </th>
633<th> Milter protocol stage </th> </tr>
634
635<tr> <td> <a href="postconf.5.html#milter_connect_macros">milter_connect_macros</a> </td> <td> 2 or higher </td> <td>
636CONNECT </td> </tr>
637
638<tr> <td> <a href="postconf.5.html#milter_helo_macros">milter_helo_macros</a> </td> <td> 2 or higher </td> <td>
639HELO/EHLO </td> </tr>
640
641<tr> <td> <a href="postconf.5.html#milter_mail_macros">milter_mail_macros</a> </td> <td> 2 or higher </td> <td> MAIL
642FROM </td> </tr>
643
644<tr> <td> <a href="postconf.5.html#milter_rcpt_macros">milter_rcpt_macros</a> </td> <td> 2 or higher </td> <td> RCPT
645TO </td> </tr>
646
647<tr> <td> <a href="postconf.5.html#milter_data_macros">milter_data_macros</a> </td> <td> 4 or higher </td> <td> DATA
648</td> </tr>
649
650<tr> <td> <a href="postconf.5.html#milter_end_of_header_macros">milter_end_of_header_macros</a> </td> <td> 6 or higher </td>
651<td> EOH </td> </tr>
652
653<tr> <td> <a href="postconf.5.html#milter_end_of_data_macros">milter_end_of_data_macros</a> </td> <td> 2 or higher </td>
654<td> EOM </td> </tr>
655
656<tr> <td> <a href="postconf.5.html#milter_unknown_command_macros">milter_unknown_command_macros</a> </td> <td> 3 or higher </td>
657<td> unknown command </td> </tr>
658
659</table>
660
661</blockquote>
662
663<h2><a name="workarounds">Workarounds</a></h2>
664
665<ul>
666
667<li> <p> To avoid breaking DKIM etc. signatures with an SMTP-based
668content filter, update the before-filter SMTP client in <a href="master.5.html">master.cf</a>,
669and add a line with "-o <a href="postconf.5.html#disable_mime_output_conversion">disable_mime_output_conversion</a>=yes" (note:
670no spaces around the "="). For details, see the <a
671href="FILTER_README.html#advanced_filter">advanced content filter</a>
672example. </p>
673
674<pre>
675/etc/postfix/<a href="master.5.html">master.cf</a>:
676    # =============================================================
677    # service type  private unpriv  chroot  wakeup  maxproc command
678    #               (yes)   (yes)   (yes)   (never) (100)
679    # =============================================================
680    scan      unix  -       -       n       -       10      smtp
681        -o <a href="postconf.5.html#smtp_send_xforward_command">smtp_send_xforward_command</a>=yes
682        -o <a href="postconf.5.html#disable_mime_output_conversion">disable_mime_output_conversion</a>=yes
683        -o <a href="postconf.5.html#smtp_generic_maps">smtp_generic_maps</a>=
684</pre>
685
686<li> <p> Some Milter applications use the "<tt>{if_addr}</tt>" macro
687to recognize local mail; this macro does not exist in Postfix.
688Workaround: use the "<tt>{client_addr}</tt>" macro instead. </p>
689
690<li> <p> Some Milter applications log a warning that looks like
691this: </p>
692
693<blockquote> <pre>
694sid-filter[36540]: WARNING: sendmail symbol 'i' not available
695</pre>
696</blockquote>
697
698<p> And they may insert an ugly message header with "unknown-msgid"
699like this: </p>
700
701<blockquote>
702<pre>
703X-SenderID: Sendmail Sender-ID Filter vx.y.z host.example.com &lt;unknown-msgid&gt;
704</pre>
705</blockquote>
706
707<p> The problem is that Milter applications expect that the queue
708ID is known <i>before</i> the MTA accepts the MAIL FROM (sender)
709command.  Postfix does not choose a queue ID, which is used as the
710queue file name, until <i>after</i> it accepts the first valid RCPT
711TO (recipient) command. </p>
712
713<p> If you experience the ugly header problem, see if a recent
714version of the Milter application fixes it. For example, current
715versions of dkim-filter and dk-filter already have code that looks
716up the Postfix queue ID at a later protocol stage, and sid-filter
717version 1.0.0 no longer includes the queue ID in the message header.
718</p>
719
720<p> To fix the ugly message header, you will need to add code that
721looks up the Postfix queue ID at some later point in time. The
722example below adds the lookup after the end-of-message.  </p>
723
724<ul>
725
726<li> <p> Edit the filter source file (typically named
727<tt>xxx-filter/xxx-filter.c</tt> or similar). </p>
728
729<li> <p> Look up the <tt>mlfi_eom()</tt> function and add code near
730the top shown as <b>bold</b> text below: </p>
731
732</ul>
733
734<blockquote>
735<pre>
736dfc = cc->cctx_msg;
737assert(dfc != NULL);
738<b>
739/* Determine the job ID for logging. */
740if (dfc->mctx_jobid == 0 || strcmp(dfc->mctx_jobid, JOBIDUNKNOWN) == 0) {
741        char *jobid = smfi_getsymval(ctx, "i");
742        if (jobid != 0)
743                dfc->mctx_jobid = jobid;
744}</b>
745</pre>
746</blockquote>
747
748<p> NOTES: </p>
749
750<ul>
751
752<li> <p> Different mail filters use slightly different names for
753variables. If the above code does not compile, look elsewhere in
754the mail filter source file for code that looks up the "i" macro
755value, and copy that code.  </p>
756
757<li> <p> This change fixes only the ugly message header, but not
758the WARNING message.  Fortunately, many Milters log that message
759only once. </p>
760
761</ul>
762
763</ul>
764
765<h2><a name="limitations">Limitations</a></h2>
766
767<p> This section lists limitations of the Postfix Milter implementation.
768Some limitations will be removed as the implementation is extended
769over time. Of course the usual limitations of before-queue filtering
770will always apply. See the <a href="CONTENT_INSPECTION_README.html">CONTENT_INSPECTION_README</a> document for
771a discussion. </p>
772
773<ul>
774
775<li> <p> The Milter protocol has evolved over time. Therefore,
776different Postfix versions implement different feature sets. </p>
777
778<table border="1">
779
780<tr> <th> Postfix </th> <th> Supported Milter requests </th>
781</tr>
782
783<tr> <td align="center"> 2.6 </td> <td> All Milter requests of
784Sendmail 8.14.0 (see notes below).  </td> </tr>
785
786<tr> <td align="center"> 2.5 </td> <td> All Milter requests of
787Sendmail 8.14.0, except: <br> SMFIP_RCPT_REJ (report rejected
788recipients to the mail filter), <br> SMFIR_CHGFROM (replace sender,
789with optional ESMTP parameters), <br> SMFIR_ADDRCPT_PAR (add
790recipient, with optional ESMTP parameters). </td> </tr>
791
792<tr> <td align="center"> 2.4 </td> <td> All Milter requests of
793Sendmail 8.13.0.  </td> </tr>
794
795<tr> <td align="center"> 2.3 </td> <td> All Milter requests of
796Sendmail 8.13.0, except: <br> SMFIR_REPLBODY (replace message body).
797
798</table>
799
800<li> <p> For Milter applications that are written in C, you need
801to use the Sendmail libmilter library. </p>
802
803<li> <p> Postfix has TWO sets of mail filters: filters that are used
804for SMTP mail only (specified with the <a href="postconf.5.html#smtpd_milters">smtpd_milters</a> parameter),
805and filters for non-SMTP mail (specified with the <a href="postconf.5.html#non_smtpd_milters">non_smtpd_milters</a>
806parameter).  The non-SMTP filters are primarily for local submissions.
807</p>
808
809<p> When mail is filtered by <a href="postconf.5.html#non_smtpd_milters">non_smtpd_milters</a>, the Postfix <a href="cleanup.8.html">cleanup(8)</a>
810server has to simulate SMTP client requests.  This works as expected,
811with only one exception: <a href="postconf.5.html#non_smtpd_milters">non_smtpd_milters</a> must not REJECT or
812TEMPFAIL simulated RCPT TO commands. When this rule is violated,
813Postfix will report a configuration error, and mail will stay in
814the queue.  </p>
815
816<li> <p> Postfix currently does not apply content filters to mail
817that is forwarded or aliased internally, or to mail that is generated
818internally such as bounces or Postmaster notifications. This may
819be a problem when you want to apply a signing Milter to such mail.
820</p>
821
822<li> <p> When you use the before-queue content filter for incoming
823SMTP mail (see <a href="SMTPD_PROXY_README.html">SMTPD_PROXY_README</a>), Milter applications have access
824only to the SMTP command information; they have no access to the
825message header or body, and cannot make modifications to the message
826or to the envelope. </p>
827
828<li> <p> Postfix 2.6 ignores the optional ESMTP parameters in
829requests to replace the sender (SMFIR_CHGFROM) or to append a
830recipient (SMFIR_ADDRCPT_PAR). Postfix logs a warning message when
831a Milter application supplies such ESMTP parameters: </p>
832
833<pre>
834warning: <i>queue-id</i>: cleanup_chg_from: ignoring ESMTP arguments "<i>whatever</i>"
835warning: <i>queue-id</i>: cleanup_add_rcpt: ignoring ESMTP arguments "<i>whatever</i>"
836</pre>
837
838<li> <p> Postfix 2.3 does not implement requests to replace the
839message body. Milter applications log a warning message when they
840need this unsupported operation: </p>
841
842<pre>
843st_optionneg[134563840]: 0x3d does not fulfill action requirements 0x1e
844</pre>
845
846<p> The solution is to use Postfix version 2.4 or later. </p>
847
848<li> <p> Most Milter configuration options are global. Future Postfix
849versions may support per-Milter timeouts, per-Milter error handling,
850etc. </p>
851
852</ul>
853
854</body>
855
856</html>
857