xref: /netbsd-src/external/ibm-public/postfix/dist/proto/POSTSCREEN_README.html (revision 5f2f42719cd62ff11fd913b40b7ce19f07c4fd25)
1<!doctype html public "-//W3C//DTD HTML 4.01 Transitional//EN"
2        "http://www.w3.org/TR/html4/loose.dtd">
3
4<head>
5
6<title>Postfix Postscreen Howto</title>
7
8<meta http-equiv="Content-Type" content="text/html; charset=us-ascii">
9
10</head>
11
12<body>
13
14<h1><img src="postfix-logo.jpg" width="203" height="98" ALT="">Postfix Postscreen Howto</h1>
15
16<hr>
17
18<h2> <a name="intro">Introduction</a> </h2>
19
20<p> This document describes features that are available in Postfix
212.8 and later. </p>
22
23<p> The Postfix postscreen(8) daemon provides additional protection
24against mail server overload. One postscreen(8) process handles
25multiple inbound SMTP connections, and decides which clients may
26talk to a Postfix SMTP server process.  By keeping spambots away,
27postscreen(8) leaves more SMTP server processes available for
28legitimate clients, and delays the onset of <a
29href="STRESS_README.html">server overload</a> conditions. </p>
30
31<p> postscreen(8) should not be used on SMTP ports that receive
32mail from end-user clients (MUAs). In a typical deployment,
33postscreen(8) handles the MX service on TCP port 25, while MUA
34clients submit mail via the submission service on TCP port 587 which
35requires client authentication. Alternatively, a site could set up
36a dedicated, non-postscreen, "port 25" server that provides submission
37service and client authentication, but no MX service.  </p>
38
39<p> postscreen(8) maintains a temporary whitelist for clients that
40pass its tests; by allowing whitelisted clients to skip tests,
41postscreen(8) minimizes its impact on legitimate email traffic.
42</p>
43
44<p> postscreen(8) is part of a multi-layer defense. <p>
45
46<ul>
47
48<li> <p> As the first layer, postscreen(8) blocks connections from
49zombies and other spambots that are responsible for about 90% of
50all spam.  It is implemented as a single process to make this defense
51as inexpensive as possible. </p>
52
53<li> <p> The second layer implements more complex SMTP-level access
54checks with <a href="SMTPD_ACCESS_README.html">Postfix SMTP servers</a>,
55<a href="SMTPD_POLICY_README.html">policy daemons</a>, and
56<a href="MILTER_README.html">Milter applications</a>. </p>
57
58<li> <p> The third layer performs light-weight content inspection
59with the Postfix built-in header_checks and body_checks. This can
60block unacceptable attachments such as executable programs, and
61worms or viruses with easy-to-recognize signatures. </p>
62
63<li> <p> The fourth layer provides heavy-weight content inspection
64with external content filters. Typical examples are <a
65href="http://www.ijs.si/software/amavisd/">Amavisd-new</a>, <a
66href="http://spamassassin.apache.org/">SpamAssassin</a>, and <a
67href="MILTER_README.html">Milter applications</a>. </p>
68
69</ul>
70
71<p> Each layer reduces the spam volume. The general strategy is to
72use the less expensive defenses first, and to use the more expensive
73defenses only for the spam that remains. </p>
74
75<p> Topics in this document: </p>
76
77<ul>
78
79<li> <a href="#intro">Introduction</a>
80
81<li> <a href="#basic">The basic idea behind postscreen(8)</a>
82
83<li> <a href="#general"> General operation </a>
84
85<li> <a href="#quick">Quick tests before everything else</a>
86
87<li> <a href="#before_220"> Tests before the 220 SMTP server greeting </a>
88
89<li> <a href="#after_220">Tests after the 220 SMTP server greeting</a>
90
91<li> <a href="#other_error">Other errors</a>
92
93<li> <a href="#victory">When all tests succeed</a>
94
95<li> <a href="#config"> Configuring the postscreen(8) service</a>
96
97<li> <a href="#historical"> Historical notes and credits </a>
98
99</ul>
100
101<h2> <a name="basic">The basic idea behind postscreen(8)</a> </h2>
102
103<p> Most email is spam, and most spam is sent out by zombies (malware
104on compromised end-user computers).  Wietse expects that the zombie
105problem will get worse before things improve, if ever. Without a
106tool like postscreen(8) that keeps the zombies away, Postfix would be
107spending most of its resources not receiving email. </p>
108
109<p> The main challenge for postscreen(8) is to make an is-a-zombie
110decision based on a single measurement. This is necessary because
111many zombies try to fly under the radar and avoid spamming the same
112site repeatedly.  Once postscreen(8) decides that a client is
113not-a-zombie, it whitelists the client temporarily to avoid further
114delays for legitimate mail. </p>
115
116<p> Zombies have challenges too: they have only a limited amount
117of time to deliver spam before their IP address becomes blacklisted.
118To speed up spam deliveries, zombies make compromises in their SMTP
119protocol implementation.  For example, they speak before their turn,
120or they ignore responses from SMTP servers and continue sending
121mail even when the server tells them to go away. </p>
122
123<p> postscreen(8) uses a variety of measurements to recognize
124zombies.  First, postscreen(8) determines if the remote SMTP client
125IP address is blacklisted.  Second, postscreen(8) looks for protocol
126compromises that are made to speed up delivery.  These are good
127indicators for making is-a-zombie decisions based on single
128measurements.  </p>
129
130<p> postscreen(8) does not inspect message content. Message content
131can vary from one delivery to the next, especially with clients
132that (also) send legitimate email.  Content is not a good indicator
133for making is-a-zombie decisions based on single measurements,
134and that is the problem that postscreen(8) is focused on.  </p>
135
136<h2> <a name="general"> General operation </a> </h2>
137
138<p> For each connection from an SMTP client, postscreen(8) performs
139a number of tests
140in the order as described below.  Some tests introduce a delay of
141a few seconds.  postscreen(8) maintains a temporary whitelist for
142clients that pass its tests; by allowing whitelisted clients to
143skip tests, postscreen(8) minimizes its impact on legitimate email
144traffic.  </p>
145
146<p> By default, postscreen(8) hands off all connections to a Postfix
147SMTP server process after logging its findings. This mode is useful
148for non-destructive testing. </p>
149
150<p> In a typical production setting, postscreen(8) is configured
151to reject mail from clients that fail one or more tests, after
152logging the helo, sender and recipient information. </p>
153
154<p> Note: postscreen(8) is not an SMTP proxy; this is intentional.
155The purpose is to keep zombies away from Postfix, with minimal
156overhead for legitimate clients. </p>
157
158<h2> <a name="quick">Quick tests before everything else</a> </h2>
159
160<p> Before engaging in SMTP-level tests. postscreen(8) queries a
161number of local black and whitelists. These tests speed up the
162handling of known clients. </p>
163
164<ul>
165
166<li> <a href="#perm_white_black"> Permanent white/blacklist test </a>
167
168<li> <a href="#temp_white"> Temporary whitelist test </a>
169
170<li> <a href="#white_veto"> MX Policy test </a>
171
172</ul>
173
174<h3> <a name="perm_white_black"> Permanent white/blacklist test </a> </h3>
175
176<p> The postscreen_access_list parameter (default: permit_mynetworks)
177specifies a permanent access list for SMTP client IP addresses. Typically
178one would specify something that whitelists local networks, followed
179by a CIDR table for selective white- and blacklisting. </p>
180
181<p> Example: </p>
182
183<pre>
184/etc/postfix/main.cf:
185    postscreen_access_list = permit_mynetworks,
186        cidr:/etc/postfix/postscreen_access.cidr
187
188/etc/postfix/postscreen_access.cidr:
189   # Rules are evaluated in the order as specified.
190   # Blacklist 192.168.* except 192.168.0.1.
191   192.168.0.1          permit
192   192.168.0.0/16       reject
193</pre>
194
195<p> See the postscreen_access_list manpage documentation for more
196details.  </p>
197
198<p> When the SMTP client address matches a "permit" action,
199postscreen(8) logs this with the client address and port number as:
200</p>
201
202<pre>
203    <b>WHITELISTED</b> <i>[address]:port</i>
204</pre>
205
206<p> The whitelist action is not configurable: immediately hand off the
207connection to a Postfix SMTP server process. </p>
208
209<p> When the SMTP client address matches a "reject" action,
210postscreen(8) logs this with the client address and port number as:
211</p>
212
213<pre>
214    <b>BLACKLISTED</b> <i>[address]:port</i>
215</pre>
216
217<p> The postscreen_blacklist_action parameter specifies the action
218that is taken next.  See "<a href="#fail_before_220">When tests
219fail before the 220 SMTP server greeting</a>" below. </p>
220
221<h3> <a name="temp_white"> Temporary whitelist test </a> </h3>
222
223<p> The postscreen(8) daemon maintains a <i>temporary</i>
224whitelist for SMTP client IP addresses that have passed all
225the tests described below. The postscreen_cache_map parameter
226specifies the location of the temporary whitelist.  The
227temporary whitelist is not used for SMTP client addresses
228that appear on the <i>permanent</i> access list. </p>
229
230<p> By default the temporary whitelist is not shared with other
231postscreen(8) daemons. See <a href="#temp_white_sharing"> Sharing
232the temporary whitelist </a> below for alternatives. </p>
233
234<p> When the SMTP client address appears on the temporary
235whitelist, postscreen(8) logs this with the client address and port
236number as: </p>
237
238<pre>
239    <b>PASS OLD</b> <i>[address]:port</i>
240</pre>
241
242<p> The action is not configurable: immediately hand off the
243connection to a Postfix SMTP server process.  The client is
244excluded from further tests until its temporary whitelist
245entry expires, as controlled with the postscreen_*_ttl
246parameters.  Expired entries are silently renewed if possible. </p>
247
248<h3> <a name="white_veto"> MX Policy test </a> </h3>
249
250<p> When the remote SMTP client is not on the static access list
251or temporary whitelist, postscreen(8) can implement a number of
252whitelist tests, before it grants the client a temporary whitelist
253status that allows it to talk to a Postfix SMTP server process. </p>
254
255<p> When postscreen(8) is configured to monitor all primary and
256backup MX addresses, it can refuse to whitelist clients that connect
257to a backup MX address only (an old spammer trick to take advantage
258of backup MX hosts with weaker anti-spam policies than primary MX
259hosts). </p>
260
261<blockquote> <p> NOTE: The following solution is for small sites.
262Larger sites would have to share the postscreen(8) cache between
263primary and backup MTAs, which would introduce a common point of
264failure.  </p> </blockquote>
265
266<ul>
267
268<li> <p> First, configure the host to listen on both primary and
269backup MX addresses. Use the appropriate <tt>ifconfig</tt> command
270for the local operating system, or update the appropriate configuration
271files and "refresh" the network protocol stack. </p>
272
273<p> <p> Second, configure Postfix to listen on the new IP address
274(this step is needed when you have specified inet_interfaces in
275main.cf). </p>
276
277<li> <p> Then, configure postscreen(8) to deny the temporary whitelist
278status on the backup MX address(es).  An example for Wietse's
279server is: </p>
280
281<pre>
282/etc/postfix/main.cf:
283    postscreen_whitelist_interfaces = !168.100.189.8 static:all
284</pre>
285
286<p> Translation: allow clients to obtain the temporary whitelist
287status on all server IP addresses except 168.100.189.8, which is a
288backup MX address.  </p>
289
290</ul>
291
292<p> When a non-whitelisted client connects the backup MX address,
293postscreen(8) logs this with the client address and port number as:
294</p>
295
296<pre>
297    <b>CONNECT from</b> <i>[address]:port</i> <b>to [168.100.189.8]:25</b>
298    <b>WHITELIST VETO</b> <i>[address]:port</i>
299</pre>
300
301<p> Translation: the client at <i>[address]:port</i> connected to
302the backup MX address 168.100.189.8 while it was not whitelisted.
303The client will not be granted the temporary whitelist status, even
304if passes all the whitelist tests described below. </p>
305
306<h2> <a name="before_220"> Tests before the 220 SMTP server greeting </a> </h2>
307
308<p> The postscreen_greet_wait parameter specifies a short time
309interval before the "220 <i>text</i>..." server greeting, where
310postscreen(8) can run a number of tests in parallel. </p>
311
312<p> When a good client passes these tests, and no "<a
313href="#after_220">deep protocol tests</a>" are configured, postscreen(8)
314adds the client to the temporary whitelist and hands off the "live"
315connection to a Postfix SMTP server process.  The client can then
316continue as if postscreen(8) never even existed (except of course
317for the short postscreen_greet_wait delay).  </p>
318
319<ul>
320
321<li> <a href="#pregreet"> Pregreet test </a>
322
323<li> <a href="#dnsbl"> DNS White/blacklist test </a>
324
325<li> <a href="#fail_before_220">When tests fail before the 220 SMTP server greeting</a>
326
327</ul>
328
329<h3> <a name="pregreet"> Pregreet test </a> </h3>
330
331<p> The SMTP protocol is a classic example of a protocol where the
332server speaks before the client. postscreen(8) detects zombies
333that are in a hurry and that speak before their turn. This test is
334enabled by default. </p>
335
336<p> The postscreen_greet_banner parameter specifies the <i>text</i>
337portion of a "220-<i>text</i>..." teaser banner (default: $smtpd_banner).
338Note that this becomes the first part of a multi-line server greeting.
339The postscreen(8) daemon sends this before the postscreen_greet_wait
340timer is started.  The purpose of the teaser banner is to confuse
341zombies so that they speak before their turn. It has no effect on
342SMTP clients that correctly implement the protocol.  </p>
343
344<p> To avoid problems with poorly-implemented SMTP engines in network
345appliances or network testing tools, either exclude them from all
346tests with the postscreen_access_list feature or else specify
347an empty teaser banner: </p>
348
349<pre>
350/etc/postfix/main.cf:
351    # Exclude broken clients by whitelisting. Clients in mynetworks
352    # should always be whitelisted.
353    postscreen_access_list = permit_mynetworks,
354        cidr:/etc/postfix/postscreen_access.cidr
355
356/etc/postfix/postscreen_access.cidr:
357    192.168.254.0/24 permit
358</pre>
359
360<pre>
361/etc/postfix/main.cf:
362    # Disable the teaser banner (try whitelisting first if you can).
363    postscreen_greet_banner =
364</pre>
365
366<p> When an SMTP client sends a command before the
367postscreen_greet_wait time has elapsed, postscreen(8) logs this as:
368</p>
369
370<pre>
371    <b>PREGREET</b> <i>count</i> <b>after</b> <i>time</i> <b>from</b> <i>[address]:port text...</i>
372</pre>
373
374<p> Translation: the client at <i>[address]:port</i> sent <i>count</i>
375bytes before its turn to speak. This happened <i>time</i> seconds
376after the postscreen_greet_wait timer was started.  The <i>text</i>
377is what the client sent (truncated to 100 bytes, and with non-printable
378characters replaced with C-style escapes such as \r for carriage-return
379and \n for newline). </p>
380
381<p> The postscreen_greet_action parameter specifies the action that
382is taken next.  See "<a href="#fail_before_220">When tests fail
383before the 220 SMTP server greeting</a>" below. </p>
384
385<h3> <a name="dnsbl"> DNS White/blacklist test </a> </h3>
386
387<p> The postscreen_dnsbl_sites parameter (default: empty) specifies
388a list of DNS blocklist servers with optional filters and weight
389factors (positive weights for blacklisting, negative for whitelisting).
390These servers will be queried in parallel with the reverse client
391IP address.  This test is disabled by default. </p>
392
393<blockquote>
394<p>
395CAUTION: when postscreen rejects mail, its SMTP reply contains the
396DNSBL domain name. Use the postscreen_dnsbl_reply_map feature to
397hide "password" information in DNSBL domain names.
398</p>
399</blockquote>
400
401<p> When the postscreen_greet_wait time has elapsed, and the combined
402DNSBL score is equal to or greater than the postscreen_dnsbl_threshold
403parameter value, postscreen(8) logs this as: </p>
404
405<pre>
406    <b>DNSBL rank</b> <i>count</i> <b>for</b> <i>[address]:port</i>
407</pre>
408
409<p> Translation: the SMTP client at <i>[address]:port</i> has a combined
410DNSBL score of <i>count</i>. </p>
411
412<p> The postscreen_dnsbl_action parameter specifies the action that
413is taken when the combined DNSBL score is equal to or greater than
414the threshold.  See "<a href="#fail_before_220">When tests fail
415before the 220 SMTP server greeting</a>" below. </p>
416
417<h3> <a name="fail_before_220">When tests fail before the 220 SMTP server greeting</a> </h3>
418
419<p> When the client address matches the permanent blacklist, or
420when the client fails the pregreet or DNSBL tests, the action is
421specified with postscreen_blacklist_action, postscreen_greet_action,
422or postscreen_dnsbl_action, respectively. </p>
423
424<dl>
425
426<dt> <b>ignore</b> (default) </dt>
427
428<dd> Ignore the failure of this test. Allow other tests to complete.
429Repeat this test the next time the client connects.  This option
430is useful for testing and collecting statistics without blocking
431mail. </dd>
432
433<dt> <b>enforce</b> </dt>
434
435<dd> Allow other tests to complete.  Reject attempts to deliver mail
436with a 550 SMTP reply, and log the helo/sender/recipient information.
437Repeat this test the next time the client connects. </dd>
438
439<dt> <b>drop</b> </dt>
440
441<dd> Drop the connection immediately with a 521 SMTP reply.  Repeat
442this test the next time the client connects. </dd>
443
444</dl>
445
446<h2> <a name="after_220">Tests after the 220 SMTP server greeting</a> </h2>
447
448<p> In this phase of the protocol, postscreen(8) implements a
449number of "deep protocol" tests. These tests use an SMTP protocol
450engine that is built into the postscreen(8) server. </p>
451
452<p> Important note: these protocol tests are disabled by default.
453They are more intrusive than the pregreet and DNSBL tests, and they
454have limitations as discussed next. </p>
455
456<ul>
457
458<li> <p> The main limitation of "after 220 greeting" tests is that
459a new client must disconnect after passing these tests (reason:
460postscreen is not a proxy).  Then the client must reconnect from
461the same IP address before it can deliver mail.  The following
462measures may help to avoid email delays: </p>
463
464<ul>
465
466<li> <p> Allow "good" clients to skip tests with the
467postscreen_dnsbl_whitelist_threshold feature (Postfix 2.11 and
468later). This is especially effective for sites such as Google that
469never retry immediately from the same IP address. </p>
470
471<li> <p> Small sites: Configure postscreen(8) to listen on multiple
472IP addresses, published in DNS as different IP addresses for the
473same MX hostname or for different MX hostnames. This avoids mail
474delivery delays with clients that reconnect immediately from the
475same IP address.  </p>
476
477<li> <p> Large sites: Share the postscreen(8) cache between different
478Postfix MTAs with a large-enough memcache_table(5). Again, this
479avoids mail delivery delays with clients that reconnect immediately
480from the same IP address. </p>
481
482</ul>
483
484<li> <p> postscreen(8)'s built-in SMTP engine does not implement the
485AUTH, XCLIENT, and XFORWARD features. If you need to make these
486services available on port 25, then do not enable the tests after
487the 220 server greeting. </p>
488
489<li> <p> End-user clients should connect directly to the submission
490service, so that they never have to deal with postscreen(8)'s tests.
491</p>
492
493</ul>
494
495<p> The following "after 220 greeting" tests are available: </p>
496
497<ul>
498
499<li> <a href="#pipelining">Command pipelining test</a>
500
501<li> <a href="#non_smtp">Non-SMTP command test</a>
502
503<li> <a href="#barelf">Bare newline test</a>
504
505<li> <a href="#fail_after_220">When tests fail after the 220 SMTP server greeting</a>
506
507</ul>
508
509<h3> <a name="pipelining">Command pipelining test</a> </h3>
510
511<p> By default, SMTP is a half-duplex protocol: the sender and
512receiver send one command and one response at a time.  Unlike the
513Postfix SMTP server, postscreen(8) does not announce support
514for ESMTP command pipelining.  Therefore, clients are not allowed
515to send multiple commands. postscreen(8)'s <a href="#after_220">deep
516protocol test</a> for this is disabled by default. </p>
517
518<p> With "postscreen_pipelining_enable = yes", postscreen(8) detects
519zombies that send multiple commands, instead of sending one command
520and waiting for the server to reply.  </p>
521
522<p> This test is opportunistically enabled when postscreen(8) has
523to use the built-in SMTP engine anyway. This is to make postscreen(8)
524logging more informative. </p>
525
526<p> When a client sends multiple commands, postscreen(8) logs this
527as: </p>
528
529<pre>
530    <b>COMMAND PIPELINING from</b> <i>[address]:port</i> <b>after</b> <i>command</i>: <i>text</i>
531</pre>
532
533<p> Translation: the SMTP client at <i>[address]:port</i> sent
534multiple SMTP commands, instead of sending one command and then
535waiting for the server to reply. This happened after the client
536sent <i>command</i>. The <i>text</i> shows part of the input that
537was sent too early; it is not logged with Postfix 2.8. </p>
538
539<p> The postscreen_pipelining_action parameter specifies the action
540that is taken next.  See "<a href="#fail_after_220">When tests fail
541after the 220 SMTP server greeting</a>" below. </p>
542
543<h3> <a name="non_smtp">Non-SMTP command test</a> </h3>
544
545<p> Some spambots send their mail through open proxies. A symptom
546of this is the usage of commands such as CONNECT and other non-SMTP
547commands. Just like the Postfix SMTP server's smtpd_forbidden_commands
548feature, postscreen(8) has an equivalent postscreen_forbidden_commands
549feature to block these clients. postscreen(8)'s <a href="#after_220">deep
550protocol test</a> for this is disabled by default.  </p>
551
552<p> With "postscreen_non_smtp_command_enable = yes", postscreen(8)
553detects zombies that send commands specified with the
554postscreen_forbidden_commands parameter. This also detects commands
555with the syntax of a message header label. The latter is a symptom
556that the client is sending message content after ignoring all the
557responses from postscreen(8) that reject mail. </p>
558
559<p> This test is opportunistically enabled when postscreen(8) has
560to use the built-in SMTP engine anyway. This is to make postscreen(8)
561logging more informative.  </p>
562
563<p> When a client sends non-SMTP commands, postscreen(8) logs this
564as: </p>
565
566<pre>
567    <b>NON-SMTP COMMAND from</b> <i>[address]:port</i> <b>after</b> <i>command: text</i>
568</pre>
569
570<p> Translation: the SMTP client at <i>[address]:port</i> sent a
571command that matches the postscreen_forbidden_commands
572parameter, or that has the syntax of a message header label (text
573followed by optional space and ":").
574The "<tt><b>after</b> <i>command</i></tt>" portion is logged with
575Postfix 2.10 and later. </p>
576
577<p> The postscreen_non_smtp_command_action parameter specifies
578the action that is taken next.  See "<a href="#fail_after_220">When
579tests fail after the 220 SMTP server greeting</a>" below. </p>
580
581<h3> <a name="barelf">Bare newline test</a> </h3>
582
583<p> SMTP is a line-oriented protocol: lines have a limited length,
584and are terminated with &lt;CR&gt;&lt;LF&gt;. Lines ending in a
585"bare" &lt;LF&gt;, that is newline not preceded by carriage return,
586are not allowed in SMTP.  postscreen(8)'s <a href="#after_220">deep
587protocol test</a> for this is disabled by default.  </p>
588
589<p> With "postscreen_bare_newline_enable = yes", postscreen(8)
590detects clients that send lines ending in bare newline characters.
591</p>
592
593<p> This test is opportunistically enabled when postscreen(8) has
594to use the built-in SMTP engine anyway. This is to make postscreen(8)
595logging more informative.  </p>
596
597<p> When a client sends bare newline characters, postscreen(8) logs
598this as:
599</p>
600
601<pre>
602    <b>BARE NEWLINE from</b> <i>[address]:port</i> <b>after</b> <i>command</i>
603</pre>
604
605<p> Translation: the SMTP client at <i>[address]:port</i> sent a bare
606newline character, that is newline not preceded by carriage
607return.
608The "<tt><b>after</b> <i>command</i></tt>" portion is logged with
609Postfix 2.10 and later. </p>
610
611<p> The postscreen_bare_newline_action parameter specifies the
612action that is taken next.  See "<a href="#fail_after_220">When
613tests fail after the 220 SMTP server greeting</a>" below. </p>
614
615<h3> <a name="fail_after_220">When tests fail after the 220 SMTP server greeting</a> </h3>
616
617<p> When the client fails the pipelining, non-SMTP command or bare
618newline tests, the action is specified with postscreen_pipelining_action,
619postscreen_non_smtp_command_action or postscreen_bare_newline_action,
620respectively. </p>
621
622<dl>
623
624<dt> <b>ignore</b> (default for bare newline) </dt>
625
626<dd> Ignore the failure of this test. Allow other tests to complete.
627Do NOT repeat this test before the result from some other test
628expires.
629
630This option is useful for testing and collecting statistics without
631blocking mail permanently. </dd>
632
633<dt> <b>enforce</b> (default for pipelining) </dt>
634
635<dd> Allow other tests to complete.  Reject attempts to deliver
636mail with a 550 SMTP reply, and log the helo/sender/recipient
637information.  Repeat this test the next time the client connects.
638</dd>
639
640<dt> <b>drop</b> (default for non-SMTP commands) </dt>
641
642<dd> Drop the connection immediately with a 521 SMTP reply.  Repeat
643this test the next time the client connects.  This action is
644compatible with the Postfix SMTP server's smtpd_forbidden_commands
645feature. </dd>
646
647</dl>
648
649<h2> <a name="other_error">Other errors</a> </h2>
650
651<p> When an SMTP client hangs up unexpectedly, postscreen(8) logs
652this as: </p>
653
654<pre>
655    <b>HANGUP after</b> <i>time</i> <b>from</b> <i>[address]:port</i> <b>in</b> <i>test name</i>
656</pre>
657
658<p> Translation: the SMTP client at <i>[address]:port</i> disconnected
659unexpectedly, <i>time</i> seconds after the start of the
660test named <i>test name</i>. </p>
661
662<p> There is no punishment for hanging up. A client that hangs up
663without sending the QUIT command can still pass all postscreen(8)
664tests. </p>
665
666<!--
667
668<p> While an unexpired penalty is in effect, an SMTP client is not
669allowed to pass any tests, and  postscreen(8) logs each connection
670with the remaining amount of penalty time as: </p>
671
672<pre>
673    <b>PENALTY</b> <i>time</i> <b>for</b> <i>[address]:port</i>
674</pre>
675
676<p> During this time, all attempts by the client to deliver mail
677will be deferred with a 450 SMTP status.  </p>
678
679-->
680
681<p> The following errors are reported by the built-in SMTP engine.
682This engine never accepts mail, therefore it has per-session limits
683on the number of commands and on the session length. </p>
684
685<pre>
686    <b>COMMAND TIME LIMIT</b> <b>from</b> <i>[address]:port</i> <b>after</b> <i>command</i>
687</pre>
688
689<p> Translation: the SMTP client at <i>[address]:port</i> reached the
690per-command time limit as specified with the postscreen_command_time_limit
691parameter.  The session is terminated immediately.
692The "<tt><b>after</b> <i>command</i></tt>" portion is logged with
693Postfix 2.10 and later. </p>
694
695<pre>
696    <b>COMMAND COUNT LIMIT from</b> <i>[address]:port</i> <b>after</b> <i>command</i>
697</pre>
698
699<p> Translation: the SMTP client at <i>[address]:port</i> reached the
700per-session command count limit as specified with the
701postscreen_command_count_limit parameter.  The session is terminated
702immediately.
703The "<tt><b>after</b> <i>command</i></tt>" portion is logged with
704Postfix 2.10 and later. </p>
705
706<pre>
707    <b>COMMAND LENGTH LIMIT from</b> <i>[address]:port</i> <b>after</b> <i>command</i>
708</pre>
709
710<p> Translation: the SMTP client at <i>[address]:port</i> reached the
711per-command length limit, as specified with the line_length_limit
712parameter.  The session is terminated immediately.
713The "<tt><b>after</b> <i>command</i></tt>" portion is logged with
714Postfix 2.10 and later. </p>
715
716<p> When an SMTP client makes too many connections at the same time,
717postscreen(8) rejects the connection with a 421 status code and logs: </p>
718
719<pre>
720    <b>NOQUEUE: reject: CONNECT from</b> <i>[address]:port</i><b>: too many connections</b>
721</pre>
722
723<p> The postscreen_client_connection_count_limit parameter controls this limit. </p>
724
725<p> When an SMTP client connects after postscreen(8) has reached a
726connection count limit, postscreen(8) rejects the connection with
727a 421 status code and logs: </p>
728
729<pre>
730    <b>NOQUEUE: reject: CONNECT from</b> <i>[address]:port</i><b>: all screening ports busy</b>
731    <b>NOQUEUE: reject: CONNECT from</b> <i>[address]:port</i><b>: all server ports busy</b>
732</pre>
733
734<p> The postscreen_pre_queue_limit and postscreen_post_queue_limit
735parameters control these limits.  </p>
736
737<h2> <a name="victory">When all tests succeed</a> </h2>
738
739<p> When a new SMTP client passes all tests (i.e. it is not whitelisted
740via some mechanism), postscreen(8) logs this as: </p>
741
742<pre>
743    <b>PASS NEW</b> <i>[address]:port</i>
744</pre>
745
746<p> Where <i>[address]:port</i> are the client IP address and port.
747Then, postscreen(8)
748creates a temporary whitelist entry that excludes the client IP
749address from further tests until the temporary whitelist entry
750expires, as controlled with the postscreen_*_ttl parameters. </p>
751
752<p> When no "<a href="#after_220">deep protocol tests</a>" are
753configured, postscreen(8) hands off the "live" connection to a Postfix
754SMTP server process.  The client can then continue as if postscreen(8)
755never even existed (except for the short postscreen_greet_wait delay).
756</p>
757
758<p> When any "<a href="#after_220">deep protocol tests</a>" are
759configured, postscreen(8) cannot hand off the "live" connection to
760a Postfix SMTP server process in the middle of the session.  Instead,
761postscreen(8) defers mail delivery attempts with a 4XX status, logs
762the helo/sender/recipient information, and waits for the client to
763disconnect.  The next time the client connects it will be allowed
764to talk to a Postfix SMTP server process to deliver its mail.
765postscreen(8) mitigates the impact of this limitation by giving
766<a href="#after_220">deep protocol tests</a> a long expiration
767time. </p>
768
769<h2> <a name="config"> Configuring the postscreen(8) service</a>
770</h2>
771
772<p> postscreen(8) has been tested on FreeBSD [4-8], Linux 2.[4-6]
773and Solaris 9 systems. </p>
774
775<ul>
776
777<li> <a href="#enable"> Turning on postscreen(8) without blocking
778mail</a>
779
780<li> <a href="#starttls"> postscreen(8) TLS configuration </a>
781
782<li> <a href="#blocking"> Blocking mail with postscreen(8) </a>
783
784<li> <a href="#turnoff"> Turning off postscreen(8) </a>
785
786<li> <a href="#temp_white_sharing"> Sharing the temporary whitelist
787</a>
788
789</ul>
790
791<h3> <a name="enable"> Turning on postscreen(8) without blocking mail</a> </h3>
792
793<p> To enable the postscreen(8) service and log client information
794without blocking mail: </p>
795
796<ol>
797
798<li> <p> Make sure that local clients and systems with non-standard
799SMTP implementations are excluded from any postscreen(8) tests. The
800default is to exclude all clients in mynetworks. To exclude additional
801clients, for example, third-party performance monitoring tools (these
802tend to have broken SMTP implementations): </p>
803
804<pre>
805/etc/postfix/main.cf:
806    # Exclude broken clients by whitelisting. Clients in mynetworks
807    # should always be whitelisted.
808    postscreen_access_list = permit_mynetworks,
809        cidr:/etc/postfix/postscreen_access.cidr
810
811/etc/postfix/postscreen_access.cidr:
812    192.168.254.0/24 permit
813</pre>
814
815<li> <p> Comment out the "<tt>smtp  inet ... smtpd</tt>" service
816in master.cf, including any "<tt>-o parameter=value</tt>" entries
817that follow.  </p>
818
819<pre>
820/etc/postfix/master.cf:
821    #smtp      inet  n       -       n       -       -       smtpd
822    #    -o parameter=value ...
823</pre>
824
825<li> <p> Uncomment the new "<tt>smtpd pass ... smtpd</tt>" service
826in master.cf, and duplicate any "<tt>-o parameter=value</tt>" entries
827from the smtpd service that was commented out in the previous step.
828</p>
829
830<pre>
831/etc/postfix/master.cf:
832    smtpd     pass  -       -       n       -       -       smtpd
833        -o parameter=value ...
834</pre>
835
836<li> <p> Uncomment the new "<tt>smtp inet ... postscreen</tt>"
837service in master.cf. </p>
838
839<pre>
840/etc/postfix/master.cf:
841    smtp      inet  n       -       n       -       1       postscreen
842</pre>
843
844<li> <p> Uncomment the new "<tt>tlsproxy unix ... tlsproxy</tt>"
845service in master.cf.  This service implements STARTTLS support for
846postscreen(8). </p>
847
848<pre>
849/etc/postfix/master.cf:
850    tlsproxy  unix  -       -       n       -       0       tlsproxy
851</pre>
852
853<li> <p> Uncomment the new "<tt>dnsblog  unix ... dnsblog</tt>"
854service in master.cf.  This service does DNSBL lookups for postscreen(8)
855and logs results. </p>
856
857<pre>
858/etc/postfix/master.cf:
859    dnsblog   unix  -       -       n       -       0       dnsblog
860</pre>
861
862<li> <p> To enable DNSBL lookups, list some DNS blocklist sites in
863main.cf, separated by whitespace. Different sites can have different
864weights. For example:
865
866<pre>
867/etc/postfix/main.cf:
868    postscreen_dnsbl_threshold = 2
869    postscreen_dnsbl_sites = zen.spamhaus.org*2
870        bl.spamcop.net*1 b.barracudacentral.org*1
871</pre>
872
873<p> Note: if your DNSBL queries have a "secret" in the domain name,
874you must censor this information from the postscreen(8) SMTP replies.
875For example: </p>
876
877<pre>
878/etc/postfix/main.cf:
879    postscreen_dnsbl_reply_map = texthash:/etc/postfix/dnsbl_reply
880</pre>
881
882<pre>
883/etc/postfix/dnsbl_reply:
884    # Secret DNSBL name           Name in postscreen(8) replies
885    secret.zen.dq.spamhaus.net    zen.spamhaus.org
886</pre>
887
888<p> The texthash: format is similar to hash: except that there is
889no need to run postmap(1) before the file can be used, and that it
890does not detect changes after the file is read. It is new with
891Postfix version 2.8. </p>
892
893<li> <p> Read the new configuration with "<tt>postfix reload</tt>".
894</p>
895
896</ol>
897
898<p> Notes: </p>
899
900<ul>
901
902<li> <p> Some postscreen(8) configuration parameters implement
903stress-dependent behavior. This is supported only when the default
904value is stress-dependent (that is, "postconf -d <i>parametername</i>"
905output shows "<i>parametername</i> =
906${stress?<i>something</i>}${stress:<i>something</i>}").
907Other parameters always evaluate as if the stress value is the empty
908string. </p>
909
910<li> <p> See "<a href="#before_220">Tests before the 220 SMTP server
911greeting</a>" for details about the logging from these postscreen(8)
912tests. </p>
913
914<li> <p> If you run Postfix 2.6 or earlier you must stop and start
915the master daemon ("<tt>postfix stop; postfix start</tt>").  This
916is needed because the Postfix "pass" master service type did not
917work reliably on all systems. </p>
918
919</ul>
920
921<h3> <a name="starttls"> postscreen(8) TLS configuration </a> </h3>
922
923<p> postscreen(8) TLS support is available for remote SMTP clients
924that aren't whitelisted, including clients that need to renew their
925temporary whitelist status.  When a remote SMTP client requests TLS
926service, postscreen(8) invisibly hands off the connection to a
927tlsproxy(8) process. Then, tlsproxy(8) encrypts and decrypts the
928traffic between postscreen(8) and the remote SMTP client. One
929tlsproxy(8) process can handle multiple SMTP sessions. The number
930of tlsproxy(8) processes slowly increases with server load, but it
931should always be much smaller than the number of postscreen(8) TLS
932sessions.  </p>
933
934<p> TLS support for postscreen(8) and tlsproxy(8) uses the same
935parameters as with smtpd(8). We recommend that you keep the relevant
936configuration parameters in main.cf.  If you must specify "-o
937smtpd_mumble=value" parameter overrides in master.cf for a
938postscreen-protected smtpd(8) service, then you should specify those
939same parameter overrides for the postscreen(8) and tlsproxy(8)
940services. </p>
941
942<h3> <a name="blocking"> Blocking mail with postscreen(8) </a> </h3>
943
944<p> For compatibility with smtpd(8), postscreen(8) implements the
945soft_bounce safety feature. This causes Postfix to reject mail with
946a "try again" reply code. </p>
947
948<ul>
949
950<li> <p> To turn this on for all of Postfix, specify "<tt>soft_bounce
951= yes</tt>" in main.cf. </p>
952
953<li> <p> To turn this on for postscreen(8) only, append "<tt>-o
954soft_bounce=yes</tt>" (note: NO SPACES around '=') to the postscreen
955entry in master.cf. <p>
956
957</ul>
958
959<p> Execute "<tt>postfix reload</tt>" to make the change effective. </p>
960
961<p> After testing, do not forget to remove the soft_bounce feature,
962otherwise senders won't receive their non-delivery notification
963until many days later.  </p>
964
965<p> To use the postscreen(8) service to block mail, edit main.cf and
966specify one or more of: </p>
967
968<ul>
969
970<li> <p> "<tt>postscreen_dnsbl_action = enforce</tt>", to reject
971clients that are on DNS blocklists, and to log the helo/sender/recipient
972information. With good DNSBLs this reduces the amount of load on
973Postfix SMTP servers dramatically.  </p>
974
975<li> <p> "<tt>postscreen_greet_action = enforce</tt>", to reject
976clients that talk before their turn, and to log the helo/sender/recipient
977information. This stops over half of all known-to-be illegitimate
978connections to Wietse's mail server. It is backup protection for
979zombies that haven't yet been blacklisted. </p>
980
981<li> <p> You can also enable "<a href="#after_220">deep protocol
982tests</a>", but these are more intrusive than the pregreet or DNSBL
983tests. </p>
984
985<p> When a good client passes the "<a href="#after_220">deep
986protocol tests</a>", postscreen(8) adds the client to the temporary
987whitelist but it cannot hand off the "live" connection to a Postfix
988SMTP server process in the middle of the session. Instead, postscreen(8)
989defers mail delivery attempts with a 4XX status, logs the
990helo/sender/recipient information, and waits for the client to
991disconnect. </p>
992
993<p> When the good client comes back in a later session, it is allowed
994to talk directly to a Postfix SMTP server.  See "<a href="#after_220">Tests
995after the 220 SMTP server greeting</a>" above for limitations with
996AUTH and other features that clients may need.  </p>
997
998<p> An unexpected benefit from "<a href="#after_220">deep protocol
999tests</a>" is that some "good" clients don't return after the 4XX
1000reply; these clients were not so good after all. </p>
1001
1002<p> Unfortunately, some senders will retry requests from different
1003IP addresses, and may never get whitelisted.  For this reason,
1004Wietse stopped using "<a href="#after_220">deep protocol tests</a>"
1005on his own internet-facing mail server.  </p>
1006
1007<li> <p> There is also support for permanent blacklisting and
1008whitelisting; see the description of the postscreen_access_list
1009parameter for details. </p>
1010
1011</ul>
1012
1013<h3> <a name="turnoff"> Turning off postscreen(8) </a> </h3>
1014
1015<p> To turn off postscreen(8) and handle mail directly with Postfix
1016SMTP server processes: </p>
1017
1018<ol>
1019
1020<li> <p> Comment out the "<tt>smtp inet ... postscreen</tt>" service
1021in master.cf, including any "<tt>-o parameter=value</tt>" entries
1022that follow. </p>
1023
1024<pre>
1025/etc/postfix/master.cf:
1026    #smtp      inet  n       -       n       -       1       postscreen
1027    #    -o parameter=value ...
1028</pre>
1029
1030<li> <p> Comment out the "<tt>dnsblog  unix ... dnsblog</tt>" service
1031in master.cf.  </p>
1032
1033<pre>
1034/etc/postfix/master.cf:
1035    #dnsblog   unix  -       -       n       -       0       dnsblog
1036</pre>
1037
1038<li> <p> Comment out the "<tt>smtpd pass ... smtpd</tt>" service
1039in master.cf, including any "<tt>-o parameter=value</tt>" entries
1040that follow. </p>
1041
1042<pre>
1043/etc/postfix/master.cf:
1044    #smtpd     pass  -       -       n       -       -       smtpd
1045    #    -o parameter=value ...
1046</pre>
1047
1048<li> <p> Comment out the "<tt>tlsproxy unix ... tlsproxy</tt>"
1049service in master.cf, including any "<tt>-o parameter=value</tt>"
1050entries that follow. </p>
1051
1052<pre>
1053/etc/postfix/master.cf:
1054    #tlsproxy  unix  -       -       n       -       0       tlsproxy
1055    #    -o parameter=value ...
1056</pre>
1057
1058<li> <p> Uncomment the "<tt>smtp  inet ... smtpd</tt>" service in
1059master.cf, including any "<tt>-o parameter=value</tt>" entries that
1060may follow.  </p>
1061
1062<pre>
1063/etc/postfix/master.cf:
1064    smtp       inet  n       -       n       -       -       smtpd
1065        -o parameter=value ...
1066</pre>
1067
1068<li> <p> Read the new configuration with "<tt>postfix reload</tt>".
1069</p>
1070
1071</ol>
1072
1073<h3> <a name="temp_white_sharing"> Sharing the temporary whitelist </a> </h3>
1074
1075<p> By default, the temporary whitelist is not shared between
1076multiple postscreen(8) daemons.  To enable sharing, choose one
1077of the following options: </p>
1078
1079<ul>
1080
1081<li> <p> A non-persistent memcache: temporary whitelist can be shared
1082    between postscreen(8) daemons on the same host or different
1083    hosts.  Disable cache cleanup (postscreen_cache_cleanup_interval
1084    = 0) in all postscreen(8) daemons because memcache: has no
1085    first-next API (but see example 4 below for memcache: with
1086    persistent backup). This requires Postfix 2.9 or later. </p>
1087
1088    <pre>
1089    # Example 1: non-persistent memcache: whitelist.
1090    /etc/postfix/main.cf:
1091	postscreen_cache_map = memcache:/etc/postfix/postscreen_cache
1092	postscreen_cache_cleanup_interval = 0
1093
1094    /etc/postfix/postscreen_cache:
1095	memcache = inet:127.0.0.1:11211
1096	key_format = postscreen:%s
1097    </pre>
1098
1099<li> <p>
1100    A persistent lmdb: temporary whitelist can be shared between
1101    postscreen(8) daemons that run under the same master(8) daemon,
1102    or under different master(8) daemons on the same host.  Disable
1103    cache cleanup (postscreen_cache_cleanup_interval = 0) in all
1104    postscreen(8) daemons except one that is responsible for cache
1105    cleanup. This requires Postfix 2.11 or later. </p>
1106
1107    <pre>
1108    # Example 2: persistent lmdb: whitelist.
1109    /etc/postfix/main.cf:
1110	postscreen_cache_map = lmdb:$data_directory/postscreen_cache
1111	# See note 1 below.
1112	# postscreen_cache_cleanup_interval = 0
1113    </pre>
1114
1115<li> <p> Other kinds of persistent temporary whitelist can be shared
1116    only between postscreen(8) daemons that run under the same
1117    master(8) daemon. In this case, temporary whitelist access must
1118    be shared through the proxymap(8) daemon. This requires Postfix
1119    2.9 or later. </p>
1120
1121    <pre>
1122    # Example 3: proxied btree: whitelist.
1123    /etc/postfix/main.cf:
1124	postscreen_cache_map =
1125	    proxy:btree:/var/lib/postfix/postscreen_cache
1126	# See note 1 below.
1127	# postscreen_cache_cleanup_interval = 0
1128
1129    # Example 4: proxied btree: whitelist with memcache: accelerator.
1130    /etc/postfix/main.cf:
1131	postscreen_cache_map = memcache:/etc/postfix/postscreen_cache
1132	proxy_write_maps =
1133	    proxy:btree:/var/lib/postfix/postscreen_cache
1134	    ... other proxied tables ...
1135	# See note 1 below.
1136	# postscreen_cache_cleanup_interval = 0
1137
1138    /etc/postfix/postscreen_cache:
1139	# Note: the $data_directory macro is not defined in this context.
1140	memcache = inet:127.0.0.1:11211
1141	backup = proxy:btree:/var/lib/postfix/postscreen_cache
1142	key_format = postscreen:%s
1143    </pre>
1144
1145    <p> Note 1: disable cache cleanup (postscreen_cache_cleanup_interval
1146    = 0) in all postscreen(8) daemons except one that is responsible
1147    for cache cleanup. </p>
1148
1149    <p> Note 2: postscreen(8) cache sharing via proxymap(8) requires Postfix
1150    2.9 or later; earlier proxymap(8) implementations don't support
1151    cache cleanup.  </p>
1152
1153</ul>
1154
1155<h2> <a name="historical"> Historical notes and credits </a> </h2>
1156
1157<p> Many ideas in postscreen(8) were explored in earlier work by
1158Michael Tokarev, in OpenBSD spamd, and in MailChannels Traffic
1159Control. </p>
1160
1161<p> Wietse threw together a crude prototype with pregreet and dnsbl
1162support in June 2009, because he needed something new for a Mailserver
1163conference presentation in July. Ralf Hildebrandt ran this code on
1164several servers to collect real-world statistics. This version used
1165the dnsblog(8) ad-hoc DNS client program. </p>
1166
1167<p> Wietse needed new material for a LISA conference presentation
1168in November 2010, so he added support for DNSBL weights and filters
1169in August, followed by a major code rewrite, deep protocol tests,
1170helo/sender/recipient logging, and stress-adaptive behavior in
1171September. Ralf Hildebrandt ran this code on several servers to
1172collect real-world statistics. This version still used the embarrassing
1173dnsblog(8) ad-hoc DNS client program.  </p>
1174
1175<p> Wietse added STARTTLS support in December 2010. This makes
1176postscreen(8) usable for sites that require TLS support.  The
1177implementation introduces the tlsproxy(8) event-driven TLS proxy
1178that decrypts/encrypts the sessions for multiple SMTP clients. </p>
1179
1180<p> The tlsproxy(8) implementation led to the discovery of a "new"
1181class of vulnerability (<a
1182href="http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2011-0411"
1183>CVE-2011-0411</a>) that affected multiple implementations of SMTP,
1184POP, IMAP, NNTP, and FTP over TLS. </p>
1185
1186<p> postscreen(8) was officially released as part of the Postfix
11872.8 stable release in January 2011.</p>
1188
1189</body>
1190
1191</html>
1192
1193