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> -> </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> -> </tt> </td> 155 156<td bgcolor="#f0f0ff" align="center" valign="middle"> qmqpd(8) 157</td> 158 159<td> <tt> -> </tt> </td> 160 161<td bgcolor="#f0f0ff" align="center" valign="middle"> cleanup(8) 162</td> 163 164<td> <tt> -> </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> -> </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 ≥ 2.6 463 milter_protocol = 6 464 # 2.3 ≤ Postfix ≤ 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 → name lookup or name → address 581verification fails: "unknown" </td> </tr> 582 583<tr> <td> {client_port} </td> <td> Always (Postfix ≥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 → name lookup <br> When address 588→ 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 ≥ 2.6, only with 609smtpd_milters) </td> <td> Sender next-hop destination </td> </tr> 610 611<tr> <td> {mail_mailer} </td> <td> MAIL (Postfix ≥ 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 ≥ 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 ≥ 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 <unknown-msgid> 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