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