1 <!doctype html public
"-//W3C//DTD HTML 4.01 Transitional//EN"
2 "http://www.w3.org/TR/html4/loose.dtd">
8 <title>Postfix Before-Queue Content Filter
</title>
10 <meta http-equiv=
"Content-Type" content=
"text/html; charset=us-ascii">
16 <h1><img src=
"postfix-logo.jpg" width=
"203" height=
"98" ALT=
"">Postfix Before-Queue Content Filter
</h1>
22 <p> The before-queue content filtering feature described in
23 this document is suitable only for low-traffic sites. See the
"<a
24 href="#pros_cons
">Pros and Cons</a>" section below for details.
27 <h2>The Postfix before-queue content filter feature
</h2>
29 <p> As of version
2.1, the Postfix SMTP server can forward all
30 incoming mail to a content filtering proxy server that inspects all
31 mail BEFORE it is stored in the Postfix mail queue. It is roughly
32 equivalent in capabilities to the approach described in
<a href=
"MILTER_README.html">MILTER_README
</a>,
33 except that the latter uses a dedicated protocol instead of SMTP.
35 <p> The before-queue content filter is meant to be used as follows:
</p>
43 <td bgcolor=
"#f0f0ff" align=
"center" valign=
"middle"
44 width=
"10%"> Internet
</td>
46 <td align=
"center" valign=
"middle" width=
"5%"> <tt> -
> </tt> </td>
48 <td bgcolor=
"#f0f0ff" align=
"center" valign=
"middle"
49 width=
"10%"> <a href=
"smtpd.8.html">Postfix SMTP server
</a>
52 <td align=
"center" valign=
"middle" width=
"5%"> <tt> -
> </tt> </td>
54 <td bgcolor=
"#f0f0ff" align=
"center" valign=
"middle"
55 width=
"10%"> <b>Before
</b> <b>queue
</b> <b>filter
</b> </td>
57 <td align=
"center" valign=
"middle" width=
"5%"> <tt> -
> </tt> </td>
59 <td bgcolor=
"#f0f0ff" align=
"center" valign=
"middle"
60 width=
"10%"> <a href=
"smtpd.8.html">Postfix SMTP server
</a>
63 <td align=
"center" valign=
"middle" width=
"5%"> <tt> -
> </tt> </td>
65 <td bgcolor=
"#f0f0ff" align=
"center" valign=
"middle"
66 width=
"10%"> <a href=
"cleanup.8.html">Postfix cleanup
69 <td align=
"center" valign=
"middle" width=
"5%"> <tt> -
> </tt> </td>
71 <td bgcolor=
"#f0f0ff" align=
"center" valign=
"middle"
72 width=
"10%"> Postfix queue
</td>
74 <td align=
"center" valign=
"middle" width=
"5%"> <tt> -
< </tt> </td>
76 <td bgcolor=
"#f0f0ff" align=
"center" valign=
"middle"
77 width=
"10%"> <a href=
"smtp.8.html">smtp
</a><br> <a
78 href=
"local.8.html">local
</a><br> <a
79 href=
"virtual.8.html">virtual
</a> </td>
87 <p> The before-queue content filter is not to be confused with the
88 approach described in the
<a href=
"FILTER_README.html">FILTER_README
</a> document, where mail is
89 filtered AFTER it is stored in the Postfix mail queue.
</p>
91 <p> This document describes the following topics:
</p>
95 <li><a href=
"#principles">Principles of operation
</a>
97 <li><a href=
"#pros_cons">Pros and cons of before-queue content filtering
</a>
99 <li><a href=
"#config">Configuring the Postfix SMTP pass-through
102 <li><a href=
"#parameters">Configuration parameters
</a>
104 <li><a href=
"#protocol">How Postfix talks to the before-queue content
109 <h2><a name=
"principles">Principles of operation
</a></h2>
111 <p> The before-filter Postfix SMTP server accepts connections from the
112 Internet and does the usual relay access control, SASL authentication,
114 RBL lookups, rejecting non-existent sender or recipient addresses,
115 etc. The before-queue filter receives unfiltered mail content from
116 Postfix and does one of the following:
</p>
120 <li> <p> Re-inject the mail back into Postfix via SMTP, perhaps
121 after changing its content and/or destination.
</p>
123 <li> <p> Discard or quarantine the mail.
</p>
125 <li> <p> Reject the mail by sending a suitable SMTP status code
126 back to Postfix. Postfix passes the status back to the remote
127 SMTP client. This way, Postfix does not have to send a bounce
132 <p>The after-filter Postfix SMTP server receives mail from the
133 content filter. From then on Postfix processes the mail as usual.
</p>
135 <p> The before-queue content filter described here works just like
136 the after-queue content filter described in the
<a href=
"FILTER_README.html">FILTER_README
</a>
137 document. In many cases you can use the same software, within the
138 limitations as discussed in the
"<a href="#pros_cons
">Pros and
139 Cons</a>" section below.
</p>
141 <h2><a name=
"pros_cons">Pros and cons of before-queue content
146 <li> <p> Pro: Postfix can reject mail before the incoming SMTP mail
147 transfer completes, so that Postfix does not have to send rejected
148 mail back to the sender (which is usually forged anyway). Mail
149 that is not accepted remains the responsibility of the remote SMTP
152 <li> <p> Con: The remote SMTP client expects an SMTP reply within
153 a deadline. As the system load increases, fewer and fewer CPU
154 cycles remain available to answer within the deadline, and eventually
155 you either have to stop accepting mail or you have to stop filtering
156 mail. It is for this reason that the before-queue content filter
157 can be used only on low-traffic sites.
</p>
159 <li> <p> Con: Content filtering software can use lots of memory
160 resources. In order to not run out of memory you have to reduce
161 the number of before-filter SMTP server processes so that a burst
162 of mail will not drive your system into the ground with too many
163 content filter processes. This, in turn, means that SMTP clients
164 have to wait for a long time before they receive service.
</p>
168 <h2><a name=
"config">Configuring the Postfix SMTP pass-through
169 proxy feature
</a></h2>
171 <p> In the following example, the before-filter Postfix SMTP server
172 gives mail to a content filter that listens on localhost port
10025.
173 The after-filter Postfix SMTP server receives mail from the content
174 filter via localhost port
10026. From then on mail is processed as
177 <p> The content filter itself is not described here. You can use
178 any filter that is SMTP enabled. For non-SMTP capable content
179 filtering software, Bennett Todd's SMTP proxy implements a nice
180 PERL/SMTP content filtering framework. See:
181 <a href=
"http://bent.latency.net/smtpprox/">http://bent.latency.net/smtpprox/
</a>.
</p>
189 <td bgcolor=
"#f0f0ff" align=
"center" valign=
"middle"
190 width=
"10%"> Internet
</td>
192 <td align=
"center" valign=
"middle" width=
"5%"> <tt> -
> </tt> </td>
194 <td bgcolor=
"#f0f0ff" align=
"center" valign=
"middle"
195 width=
"10%"> <a href=
"smtpd.8.html">Postfix SMTP server on
198 <td align=
"center" valign=
"middle" width=
"5%"> <tt> -
> </tt> </td>
200 <td bgcolor=
"#f0f0ff" align=
"center" valign=
"middle"
201 width=
"10%"> filter on localhost port
10025 </td>
203 <td align=
"center" valign=
"middle" width=
"5%"> <tt> -
> </tt> </td>
205 <td bgcolor=
"#f0f0ff" align=
"center" valign=
"middle"
206 width=
"10%"> <a href=
"smtpd.8.html">Postfix SMTP server on
207 localhost port
10026</a> </td>
209 <td align=
"center" valign=
"middle" width=
"5%"> <tt> -
> </tt> </td>
211 <td bgcolor=
"#f0f0ff" align=
"center" valign=
"middle"
212 width=
"10%"> <a href=
"cleanup.8.html">Postfix cleanup
215 <td align=
"center" valign=
"middle" width=
"5%"> <tt> -
> </tt> </td>
217 <td bgcolor=
"#f0f0ff" align=
"center" valign=
"middle"
218 width=
"10%"> Postfix
<a href=
"QSHAPE_README.html#incoming_queue">incoming queue
</a> </td>
226 <p> This is configured by editing the
<a href=
"master.5.html">master.cf
</a> file:
</p>
230 /etc/postfix/
<a href=
"master.5.html">master.cf
</a>:
231 # =============================================================
232 # service type private unpriv chroot wakeup maxproc command
233 # (yes) (yes) (yes) (never) (
100)
234 # =============================================================
236 # Before-filter SMTP server. Receive mail from the network and
237 # pass it to the content filter on localhost port
10025.
239 smtp inet n - n -
20 smtpd
240 -o
<a href=
"postconf.5.html#smtpd_proxy_filter">smtpd_proxy_filter
</a>=
127.0.0.1:
10025
241 -o
<a href=
"postconf.5.html#smtpd_client_connection_count_limit">smtpd_client_connection_count_limit
</a>=
10
243 # After-filter SMTP server. Receive mail from the content filter
244 # on localhost port
10026.
246 127.0.0.1:
10026 inet n - n - - smtpd
247 -o
<a href=
"postconf.5.html#smtpd_authorized_xforward_hosts">smtpd_authorized_xforward_hosts
</a>=
127.0.0.0/
8
248 -o
<a href=
"postconf.5.html#smtpd_client_restrictions">smtpd_client_restrictions
</a>=
249 -o
<a href=
"postconf.5.html#smtpd_helo_restrictions">smtpd_helo_restrictions
</a>=
250 -o
<a href=
"postconf.5.html#smtpd_sender_restrictions">smtpd_sender_restrictions
</a>=
251 -o
<a href=
"postconf.5.html#smtpd_recipient_restrictions">smtpd_recipient_restrictions
</a>=
<a href=
"postconf.5.html#permit_mynetworks">permit_mynetworks
</a>,reject
252 -o
<a href=
"postconf.5.html#smtpd_data_restrictions">smtpd_data_restrictions
</a>=
253 -o
<a href=
"postconf.5.html#mynetworks">mynetworks
</a>=
127.0.0.0/
8
254 -o
<a href=
"postconf.5.html#receive_override_options">receive_override_options
</a>=
<a href=
"postconf.5.html#no_unknown_recipient_checks">no_unknown_recipient_checks
</a>
258 <p> Note: do not specify spaces around the
"=" or
"," characters.
</p>
260 <p> The before-filter SMTP server entry is a modified version of the
261 default Postfix SMTP server entry that is normally configured at
262 the top of the
<a href=
"master.5.html">master.cf
</a> file:
</p>
266 <li> <p> The number of SMTP sessions is reduced from the default
267 100 to only
20. This prevents a burst of mail from running your
268 system into the ground with too many content filter processes.
</p>
270 <li> <p> The
"-o <a href="postconf
.5.html#smtpd_client_connection_count_limit
">smtpd_client_connection_count_limit</a>=10" prevents
271 one SMTP client from using up all
20 SMTP server processes.
272 This limit is not necessary if you receive all mail from a
273 trusted
<a href=
"postconf.5.html#relayhost">relay host
</a>.
</p>
275 <p> Note: this setting is available in Postfix version
2.2 and
276 later. Earlier Postfix versions will ignore it.
</p>
278 <li> <p> The
"-o <a href="postconf
.5.html#smtpd_proxy_filter
">smtpd_proxy_filter</a>=127.0.0.1:10025" tells the
279 before filter SMTP server that it should give incoming mail to
280 the content filter that listens on localhost TCP port
10025.
282 <li> <p> Postfix
2.3 supports both TCP and UNIX-domain filters.
283 The above filter could be specified as
"inet:127.0.0.1:10025".
284 To specify a UNIX-domain filter, specify
"unix:<i>pathname</i>".
285 A relative pathname is interpreted relative to the Postfix queue
290 <p> The after-filter SMTP server is a new
<a href=
"master.5.html">master.cf
</a> entry:
</p>
294 <li> <p> The
"127.0.0.1:10026" makes the after-filter SMTP
296 on the localhost address only, without exposing it to the
297 network. NEVER expose the after-filter SMTP server to the
300 <li> <p> The
"-o <a href="postconf
.5.html#smtpd_authorized_xforward_hosts
">smtpd_authorized_xforward_hosts</a>=127.0.0.0/8"
301 allows the after-filter SMTP server to receive remote SMTP
302 client information from the before filter SMTP server, so that
303 the after-filter Postfix daemons log the remote SMTP client
304 information instead of logging localhost[
127.0.0.1].
</p>
306 <li> <p> The other after-filter SMTP server settings avoid
307 duplication of work that is already done in the
"before filter"
312 <p> By default, the filter has
100 seconds to do its work. If it
313 takes longer then Postfix gives up and reports an error to the
314 remote SMTP client. You can increase this time limit (see configuration
315 parameter section below) but doing so is pointless because you
316 can't control when the remote SMTP client times out.
</p>
318 <h2><a name=
"parameters">Configuration parameters
</a></h2>
320 <p> Parameters that control proxying:
</p>
324 <li> <p> <a href=
"postconf.5.html#smtpd_proxy_filter">smtpd_proxy_filter
</a> (syntax: host:port): The host and TCP
325 port of the before-queue content filter. When no host or host:
326 is specified here, localhost is assumed.
</p>
328 <li> <p> <a href=
"postconf.5.html#smtpd_proxy_timeout">smtpd_proxy_timeout
</a> (default:
100s): Timeout for connecting
329 to the before-queue content filter and for sending and receiving
330 commands and data. All proxy errors are logged to the maillog
331 file. For privacy reasons, all the remote SMTP client sees is
"451
332 Error: queue file write error". It would not be right to disclose
333 internal details to strangers.
</p>
335 <li> <p> <a href=
"postconf.5.html#smtpd_proxy_ehlo">smtpd_proxy_ehlo
</a> (default: $
<a href=
"postconf.5.html#myhostname">myhostname
</a>): The hostname to
336 use when sending an EHLO command to the before-queue content filter.
341 <h2><a name=
"protocol">How Postfix talks to the before-queue content
344 <p> The before-filter Postfix SMTP server connects to the content
345 filter, delivers one message, and disconnects. While sending mail
346 into the content filter, Postfix speaks ESMTP but uses no command
347 pipelining. Postfix generates its own EHLO, XFORWARD (for logging
348 the remote client IP address instead of localhost[
127.0.0.1]), DATA
349 and QUIT commands, and forwards unmodified copies of all the MAIL
350 FROM and RCPT TO commands that the before-filter Postfix SMTP server
351 didn't reject itself.
352 Postfix sends no other SMTP commands.
</p>
354 <p> The content filter should accept the same MAIL FROM and RCPT
355 TO command syntax as the before-filter Postfix SMTP server, and
356 should forward the commands without modification to the after-filter
357 SMTP server. If the content filter or after-filter SMTP server
358 does not support all the ESMTP features that the before-filter
359 Postfix SMTP server supports, then the missing features must be
360 turned off in the before-filter Postfix SMTP server with the
361 <a href=
"postconf.5.html#smtpd_discard_ehlo_keywords">smtpd_discard_ehlo_keywords
</a> parameter.
</p>
363 <p> When the filter rejects content, it should send a negative SMTP
364 response back to the before-filter Postfix SMTP server, and it
365 should abort the connection with the after-filter Postfix SMTP
366 server without completing the SMTP conversation with the after-filter
367 Postfix SMTP server.
</p>