1 <!doctype html public
"-//W3C//DTD HTML 4.01 Transitional//EN"
2 "http://www.w3.org/TR/html4/loose.dtd">
6 <title>Postfix Postscreen Howto
</title>
8 <meta http-equiv=
"Content-Type" content=
"text/html; charset=us-ascii">
14 <h1><img src=
"postfix-logo.jpg" width=
"203" height=
"98" ALT=
"">Postfix Postscreen Howto
</h1>
18 <h2> <a name=
"intro">Introduction
</a> </h2>
20 <p> The Postfix
<a href=
"postscreen.8.html">postscreen(
8)
</a> server performs triage on multiple
21 inbound SMTP connections at the same time. While a single
<a href=
"postscreen.8.html">postscreen(
8)
</a>
22 process keeps zombies away from Postfix SMTP server processes, more
23 Postfix SMTP server processes remain available for legitimate
26 <p> <a href=
"postscreen.8.html">postscreen(
8)
</a> maintains a temporary whitelist for clients that
27 pass its tests; by allowing whitelisted clients to skip tests,
28 <a href=
"postscreen.8.html">postscreen(
8)
</a> minimizes its impact on legitimate email traffic.
31 <p> <a href=
"postscreen.8.html">postscreen(
8)
</a> should not be used on SMTP ports that receive
32 mail from end-user clients (MUAs). In a typical deployment,
33 <a href=
"postscreen.8.html">postscreen(
8)
</a> is used on the
"port 25" service, while MUA clients
34 submit mail via the submission service.
</p>
36 <p> <a href=
"postscreen.8.html">postscreen(
8)
</a> is part of a multi-layer defense.
<p>
40 <li> <p> As the first layer,
<a href=
"postscreen.8.html">postscreen(
8)
</a> blocks connections from
41 zombies and other spambots that are responsible for about
90% of
42 all spam. It is implemented as a single process to make this defense
43 as cheap as possible.
</p>
45 <li> <p> The second layer implements more complex SMTP-level access
46 checks with Postfix SMTP servers, policy daemons, and Milter
49 <li> <p> The third layer performs light-weight content inspection
50 with the Postfix built-in
<a href=
"postconf.5.html#header_checks">header_checks
</a> and
<a href=
"postconf.5.html#body_checks">body_checks
</a>. This can
51 block unacceptable attachments such as executable programs, and
52 worms or viruses with easy-to-recognize signatures.
</p>
54 <li> <p> The fourth layer provides heavy-weight content inspection
55 with external content filters. Typical examples are Amavisd-new,
56 SpamAssassin, and Milter applications.
</p>
60 <p> Each layer reduces the spam volume. The general strategy is to
61 use the less expensive defenses first, and to use the more expensive
62 defenses for the spam that remains.
</p>
64 <p> Topics in this document:
</p>
68 <li> <a href=
"#intro">Introduction
</a>
70 <li> <a href=
"#basic">The basic idea behind postscreen(
8)
</a>
72 <li> <a href=
"#general"> General operation
</a>
74 <li> <a href=
"#quick">Quick tests before everything else
</a>
76 <li> <a href=
"#before_220"> Tests before the
220 SMTP server greeting
</a>
78 <li> <a href=
"#after_220">Tests after the
220 SMTP server greeting
</a>
80 <li> <a href=
"#other_error">Other errors
</a>
82 <li> <a href=
"#victory">When all tests succeed
</a>
84 <li> <a href=
"#config"> Configuring the postscreen(
8) service
</a>
86 <li> <a href=
"#historical"> Historical notes and credits
</a>
90 <h2> <a name=
"basic">The basic idea behind postscreen(
8)
</a> </h2>
92 <p> Most email is spam, and most spam is sent out by zombies (malware
93 on compromised end-user computers). Wietse expects that the zombie
94 problem will get worse before things improve, if ever. Without a
95 tool like
<a href=
"postscreen.8.html">postscreen(
8)
</a> that keeps the zombies away, Postfix would be
96 spending most of its resources not receiving email.
</p>
98 <p> The main challenge for
<a href=
"postscreen.8.html">postscreen(
8)
</a> is to make an is-it-a-zombie
99 decision based on a single measurement. This is necessary because
100 many zombies try to fly under the radar and avoid spamming the same
101 site repeatedly. Once
<a href=
"postscreen.8.html">postscreen(
8)
</a> decides that a client is
102 not-a-zombie, it whitelists the client temporarily to avoid further
103 delays for legitimate mail.
</p>
105 <p> Zombies have challenges too: they have only a limited amount
106 of time to deliver spam before their IP address becomes blacklisted.
107 To speed up spam deliveries, zombies make compromises in their SMTP
108 protocol implementation. For example, they speak before their turn,
109 or they ignore responses from SMTP servers and continue sending
110 mail even when the server tells them to go away.
</p>
112 <p> <a href=
"postscreen.8.html">postscreen(
8)
</a> uses a variety of measurements to recognize
113 zombies. First,
<a href=
"postscreen.8.html">postscreen(
8)
</a> determines if the remote SMTP client
114 IP address is blacklisted. Second,
<a href=
"postscreen.8.html">postscreen(
8)
</a> looks for protocol
115 compromises that are made to speed up delivery. These are good
116 indicators for making is-it-a-zombie decisions based on single
119 <p> <a href=
"postscreen.8.html">postscreen(
8)
</a> does not inspect message content. Message content
120 can vary from one delivery to the next, especially with clients
121 that (also) send legitimate email. Content is not a good indicator
122 for making is-it-a-zombie decisions based on single measurements,
123 and that is the problem that
<a href=
"postscreen.8.html">postscreen(
8)
</a> is focused on.
</p>
125 <h2> <a name=
"general"> General operation
</a> </h2>
127 <p> The
<a href=
"postscreen.8.html">postscreen(
8)
</a> triage process involves a number of tests,
128 in the order as described below. Some tests introduce a delay of
129 a few seconds.
<a href=
"postscreen.8.html">postscreen(
8)
</a> maintains a temporary whitelist for
130 clients that pass its tests; by allowing whitelisted clients to
131 skip tests,
<a href=
"postscreen.8.html">postscreen(
8)
</a> minimizes its impact on legitimate email
134 <p> By default,
<a href=
"postscreen.8.html">postscreen(
8)
</a> hands off all connections to a Postfix
135 SMTP server process after logging its findings. This mode is useful
136 for non-destructive testing.
</p>
138 <p> In a typical production setting,
<a href=
"postscreen.8.html">postscreen(
8)
</a> is configured
139 to reject mail from clients that fail one or more tests, after
140 logging the helo, sender and recipient information.
</p>
142 <p> Note:
<a href=
"postscreen.8.html">postscreen(
8)
</a> is not an SMTP proxy; this is intentional.
143 The purpose is to keep zombies away from Postfix, with minimal
144 overhead for legitimate clients.
</p>
146 <h2> <a name=
"quick">Quick tests before everything else
</a> </h2>
148 <p> Before engaging in SMTP-level tests.
<a href=
"postscreen.8.html">postscreen(
8)
</a> queries a
149 number of local black and whitelists. These tests speed up the
150 handling of known clients.
</p>
154 <li> <a href=
"#perm_white_black"> Permanent white/blacklist test
</a>
156 <li> <a href=
"#temp_white"> Temporary whitelist test
</a>
158 <li> <a href=
"#white_veto"> MX Policy test
</a>
162 <h3> <a name=
"perm_white_black"> Permanent white/blacklist test
</a> </h3>
164 <p> The
<a href=
"postconf.5.html#postscreen_access_list">postscreen_access_list
</a> parameter (default:
<a href=
"postconf.5.html#permit_mynetworks">permit_mynetworks
</a>)
165 specifies a permanent access list for SMTP client IP addresses. Typically
166 one would specify something that whitelists local networks, followed
167 by a CIDR table for selective white- and blacklisting.
</p>
172 /etc/postfix/
<a href=
"postconf.5.html">main.cf
</a>:
173 <a href=
"postconf.5.html#postscreen_access_list">postscreen_access_list
</a> =
<a href=
"postconf.5.html#permit_mynetworks">permit_mynetworks
</a>,
174 <a href=
"cidr_table.5.html">cidr
</a>:/etc/postfix/postscreen_access.cidr
176 /etc/postfix/postscreen_access.
<a href=
"cidr_table.5.html">cidr
</a>:
177 # Rules are evaluated in the order as specified.
178 # Blacklist
192.168.* except
192.168.0.1.
180 192.168.0.0/
16 reject
183 <p> See the
<a href=
"postconf.5.html#postscreen_access_list">postscreen_access_list
</a> manpage documentation for more
186 <p> When the SMTP client address matches a
"permit" action,
187 <a href=
"postscreen.8.html">postscreen(
8)
</a> logs this with the client address and port number as:
191 <b>WHITELISTED
</b> <i>[address]:port
</i>
194 <p> The whitelist action is not configurable: immediately hand off the
195 connection to a Postfix SMTP server process.
</p>
197 <p> When the SMTP client address matches a
"reject" action,
198 <a href=
"postscreen.8.html">postscreen(
8)
</a> logs this with the client address and port number as:
202 <b>BLACKLISTED
</b> <i>[address]:port
</i>
205 <p> The
<a href=
"postconf.5.html#postscreen_blacklist_action">postscreen_blacklist_action
</a> parameter specifies the action
206 that is taken next. See
"<a href="#fail_before_220
">When tests
207 fail before the 220 SMTP server greeting</a>" below.
</p>
209 <h3> <a name=
"temp_white"> Temporary whitelist test
</a> </h3>
211 <p> The
<a href=
"postscreen.8.html">postscreen(
8)
</a> daemon maintains a
<i>temporary
</i>
212 whitelist for SMTP client IP addresses that have passed all
213 the tests described below. The
<a href=
"postconf.5.html#postscreen_cache_map">postscreen_cache_map
</a> parameter
214 specifies the location of the temporary whitelist. The
215 temporary whitelist is not used for SMTP client addresses
216 that appear on the
<i>permanent
</i> access list.
</p>
218 <p> When the SMTP client address appears on the temporary
219 whitelist,
<a href=
"postscreen.8.html">postscreen(
8)
</a> logs this with the client address and port
223 <b>PASS OLD
</b> <i>[address]:port
</i>
226 <p> The action is not configurable: immediately hand off the
227 connection to a Postfix SMTP server process. The client is
228 excluded from further tests until its temporary whitelist
229 entry expires, as controlled with the postscreen_*_ttl
230 parameters. Expired entries are silently renewed if possible.
</p>
232 <h3> <a name=
"white_veto"> MX Policy test
</a> </h3>
234 <p> When the remote SMTP client is not on the static access list
235 or temporary whitelist,
<a href=
"postscreen.8.html">postscreen(
8)
</a> can implement a number of
236 whitelist tests before it grants the client a temporary whitelist
237 status to talk to a Postfix SMTP server process.
</p>
239 <p> By listening on both primary and backup MX addresses,
<a href=
"postscreen.8.html">postscreen(
8)
</a>
240 can deny the temporary whitelist status to clients that connect
241 only to backup MX hosts (an old trick to take advantage of backup
242 MX hosts with weaker anti-spam policies).
</p>
244 <p> Note
1: The status of this feature is still experimental, and
245 implementation details are likely to change.
</p>
247 <p> Note
2: MX policy enforcement is currently supported only for
248 domains with one Postfix MTA. Support for domains with multiple
249 Postfix MTAs will have to wait until Postfix has a database client
250 that can update a shared
<a href=
"postscreen.8.html">postscreen(
8)
</a> database.
</p>
254 <li> <p> First, configure the host to listen on both primary and
255 backup MX addresses. Use the appropriate
<tt>ifconfig
</tt> command
256 for the local operating system, or update the appropriate configuration
257 files and
"refresh" the network protocol stack.
</p>
259 <li> <p> Then, configure
<a href=
"postscreen.8.html">postscreen(
8)
</a> to deny the temporary whitelist
260 status on the backup MX address(es). An example for Wietse's
264 /etc/postfix/
<a href=
"postconf.5.html">main.cf
</a>:
265 <a href=
"postconf.5.html#postscreen_whitelist_interfaces">postscreen_whitelist_interfaces
</a> = !
168.100.189.8 <a href=
"DATABASE_README.html#types">static
</a>:all
268 <p> Translation: allow clients to obtain the temporary whitelist
269 status on all server IP addresses except
168.100.189.8, which is a
270 backup MX address.
</p>
274 <p> When a non-whitelisted client connects the backup MX address,
275 <a href=
"postscreen.8.html">postscreen(
8)
</a> logs this with the client address and port number as:
279 <b>CONNECT from
</b> <i>[address]:port
</i> <b>to [
168.100.189.8]:
25</b>
280 <b>WHITELIST VETO
</b> <i>[address]:port
</i>
283 <p> Translation: the client at
<i>[address]:port
</i> connected to
284 the backup MX address
168.100.189.8 while it was not whitelisted.
285 The client will not be granted the temporary whitelist status, even
286 if passes all the whitelist tests described below.
</p>
288 <h2> <a name=
"before_220"> Tests before the
220 SMTP server greeting
</a> </h2>
290 <p> The
<a href=
"postconf.5.html#postscreen_greet_wait">postscreen_greet_wait
</a> parameter specifies a short time
291 interval before the
"220 <i>text</i>..." server greeting, where
292 <a href=
"postscreen.8.html">postscreen(
8)
</a> can run a number of tests in parallel.
</p>
294 <p> When a good client passes these tests, and no
"<a
295 href="#after_220
">deep protocol tests</a>" are configured, postscreen(
8)
296 adds the client to the temporary whitelist and hands off the
"live"
297 connection to a Postfix SMTP server process. The client can then
298 continue as if
<a href=
"postscreen.8.html">postscreen(
8)
</a> never even existed (except of course
299 for the short
<a href=
"postconf.5.html#postscreen_greet_wait">postscreen_greet_wait
</a> delay).
</p>
303 <li> <a href=
"#pregreet"> Pregreet test
</a>
305 <li> <a href=
"#dnsbl"> DNS White/blacklist test
</a>
307 <li> <a href=
"#fail_before_220">When tests fail before the
220 SMTP server greeting
</a>
311 <h3> <a name=
"pregreet"> Pregreet test
</a> </h3>
313 <p> The SMTP protocol is a classic example of a protocol where the
314 server speaks before the client.
<a href=
"postscreen.8.html">postscreen(
8)
</a> detects zombies
315 that are in a hurry and that speak before their turn. This test is
316 enabled by default.
</p>
318 <p> The
<a href=
"postconf.5.html#postscreen_greet_banner">postscreen_greet_banner
</a> parameter specifies the
<i>text
</i>
319 portion of a
"220-<i>text</i>..." teaser banner (default: $
<a href=
"postconf.5.html#smtpd_banner">smtpd_banner
</a>).
320 Note that this becomes the first part of a multi-line server greeting.
321 The
<a href=
"postscreen.8.html">postscreen(
8)
</a> daemon sends this before the
<a href=
"postconf.5.html#postscreen_greet_wait">postscreen_greet_wait
</a>
322 timer is started. The purpose of the teaser banner is to confuse
323 zombies so that they speak before their turn. It has no effect on
324 SMTP clients that correctly implement the protocol.
</p>
326 <p> To avoid problems with poorly-implemented SMTP engines in network
327 appliances or network testing tools, either exclude them from all
328 tests with the
<a href=
"postconf.5.html#postscreen_access_list">postscreen_access_list
</a> feature or else specify
329 an empty teaser banner:
</p>
332 /etc/postfix/
<a href=
"postconf.5.html">main.cf
</a>:
333 # Exclude broken clients by whitelisting. Clients in
<a href=
"postconf.5.html#mynetworks">mynetworks
</a>
334 # should always be whitelisted.
335 <a href=
"postconf.5.html#postscreen_access_list">postscreen_access_list
</a> =
<a href=
"postconf.5.html#permit_mynetworks">permit_mynetworks
</a>,
336 <a href=
"cidr_table.5.html">cidr
</a>:/etc/postfix/postscreen_access.cidr
338 /etc/postfix/postscreen_access.
<a href=
"cidr_table.5.html">cidr
</a>:
339 192.168.254.0/
24 permit
343 /etc/postfix/
<a href=
"postconf.5.html">main.cf
</a>:
344 # Disable the teaser banner (try whitelisting first if you can).
345 <a href=
"postconf.5.html#postscreen_greet_banner">postscreen_greet_banner
</a> =
348 <p> When an SMTP client sends a command before the
349 <a href=
"postconf.5.html#postscreen_greet_wait">postscreen_greet_wait
</a> time has elapsed,
<a href=
"postscreen.8.html">postscreen(
8)
</a> logs this as:
353 <b>PREGREET
</b> <i>count
</i> <b>after
</b> <i>time
</i> <b>from
</b> <i>[address]:port text...
</i>
356 <p> Translation: the client at
<i>[address]:port
</i> sent
<i>count
</i>
357 bytes before its turn to speak. This happened
<i>time
</i> seconds
358 after the
<a href=
"postconf.5.html#postscreen_greet_wait">postscreen_greet_wait
</a> timer was started. The
<i>text
</i>
359 is what the client sent (truncated to
100 bytes, and with non-printable
360 characters replaced with C-style escapes such as \r for carriage-return
361 and \n for newline).
</p>
363 <p> The
<a href=
"postconf.5.html#postscreen_greet_action">postscreen_greet_action
</a> parameter specifies the action that
364 is taken next. See
"<a href="#fail_before_220
">When tests fail
365 before the 220 SMTP server greeting</a>" below.
</p>
367 <h3> <a name=
"dnsbl"> DNS White/blacklist test
</a> </h3>
369 <p> The
<a href=
"postconf.5.html#postscreen_dnsbl_sites">postscreen_dnsbl_sites
</a> parameter (default: empty) specifies
370 a list of DNS blocklist servers with optional filters and weight
371 factors (positive weights for blacklisting, negative for whitelisting).
372 These servers will be queried in parallel with the reverse client
373 IP address. This test is disabled by default.
</p>
377 CAUTION: when postscreen rejects mail, its SMTP reply contains the
378 DNSBL domain name. Use the
<a href=
"postconf.5.html#postscreen_dnsbl_reply_map">postscreen_dnsbl_reply_map
</a> feature to
379 hide
"password" information in DNSBL domain names.
383 <p> When the
<a href=
"postconf.5.html#postscreen_greet_wait">postscreen_greet_wait
</a> time has elapsed, and the combined
384 DNSBL score is equal to or greater than the
<a href=
"postconf.5.html#postscreen_dnsbl_threshold">postscreen_dnsbl_threshold
</a>
385 parameter value,
<a href=
"postscreen.8.html">postscreen(
8)
</a> logs this as:
</p>
388 <b>DNSBL rank
</b> <i>count
</i> <b>for
</b> <i>[address]:port
</i>
391 <p> Translation: the SMTP client at
<i>[address]:port
</i> has a combined
392 DNSBL score of
<i>count
</i>.
</p>
394 <p> The
<a href=
"postconf.5.html#postscreen_dnsbl_action">postscreen_dnsbl_action
</a> parameter specifies the action that
395 is taken when the combined DNSBL score is equal to or greater than
396 the threshold. See
"<a href="#fail_before_220
">When tests fail
397 before the 220 SMTP server greeting</a>" below.
</p>
399 <h3> <a name=
"fail_before_220">When tests fail before the
220 SMTP server greeting
</a> </h3>
401 <p> When the client address matches the permanent blacklist, or
402 when the client fails the pregreet or DNSBL tests, the action is
403 specified with
<a href=
"postconf.5.html#postscreen_blacklist_action">postscreen_blacklist_action
</a>,
<a href=
"postconf.5.html#postscreen_greet_action">postscreen_greet_action
</a>,
404 or
<a href=
"postconf.5.html#postscreen_dnsbl_action">postscreen_dnsbl_action
</a>, respectively.
</p>
408 <dt> <b>ignore
</b> (default)
</dt>
410 <dd> Ignore the failure of this test. Allow other tests to complete.
411 Repeat this test the next time the client connects. This option
412 is useful for testing and collecting statistics without blocking
415 <dt> <b>enforce
</b> </dt>
417 <dd> Allow other tests to complete. Reject attempts to deliver mail
418 with a
550 SMTP reply, and log the helo/sender/recipient information.
419 Repeat this test the next time the client connects.
</dd>
421 <dt> <b>drop
</b> </dt>
423 <dd> Drop the connection immediately with a
521 SMTP reply. Repeat
424 this test the next time the client connects.
</dd>
428 <h2> <a name=
"after_220">Tests after the
220 SMTP server greeting
</a> </h2>
430 <p> In this phase of the protocol,
<a href=
"postscreen.8.html">postscreen(
8)
</a> implements a
431 number of
"deep protocol" tests. These tests use an SMTP protocol
432 engine that is built into the
<a href=
"postscreen.8.html">postscreen(
8)
</a> server.
</p>
434 <p> Important note: deep protocol tests are disabled by default.
435 They are more intrusive than the pregreet and DNSBL tests, and they
436 have limitations as discussed next.
</p>
440 <li> <p> When a good client passes the
<a href=
"#after_220">deep
441 protocol tests
</a>, postscreen(
8) adds the client to the temporary
442 whitelist but it cannot hand off the
"live" connection to a Postfix
443 SMTP server process in the middle of the session. Instead,
<a href=
"postscreen.8.html">postscreen(
8)
</a>
444 defers mail delivery attempts with a
4XX status, logs the
445 helo/sender/recipient information, and waits for the client to
448 <p> The next time the client connects it will be allowed to talk
449 to a Postfix SMTP server process to deliver its mail. To minimize the
450 impact of this limitation,
<a href=
"postscreen.8.html">postscreen(
8)
</a> gives deep protocol tests
451 a relatively long expiration time.
</p>
453 <li> <p> <a href=
"postscreen.8.html">postscreen(
8)
</a>'s built-in SMTP engine does not implement
454 the AUTH, XCLIENT, and XFORWARD features. AUTH support may be added
455 in a future version. In the mean time, if you need to make these
456 services available on port
25, then do not enable the tests after
457 the
220 server greeting.
</p>
461 <p> End-user clients should connect directly to the submission
462 service, so that they never have to deal with
<a href=
"postscreen.8.html">postscreen(
8)
</a>'s tests.
467 <li> <a href=
"#pipelining">Command pipelining test
</a>
469 <li> <a href=
"#non_smtp">Non-SMTP command test
</a>
471 <li> <a href=
"#barelf">Bare newline test
</a>
473 <li> <a href=
"#fail_after_220">When tests fail after the
220 SMTP server greeting
</a>
477 <h3> <a name=
"pipelining">Command pipelining test
</a> </h3>
479 <p> By default, SMTP is a half-duplex protocol: the sender and
480 receiver send one command and one response at a time. Unlike the
481 Postfix SMTP server,
<a href=
"postscreen.8.html">postscreen(
8)
</a> does not announce support
482 for ESMTP command pipelining. Therefore, clients are not allowed
483 to send multiple commands. postscreen(
8)'s
<a href=
"#after_220">deep
484 protocol test
</a> for this is disabled by default.
</p>
486 <p> With
"<a href="postconf
.5.html#postscreen_pipelining_enable
">postscreen_pipelining_enable</a> = yes",
<a href=
"postscreen.8.html">postscreen(
8)
</a> detects
487 zombies that send multiple commands, instead of sending one command
488 and waiting for the server to reply.
</p>
490 <p> This test is opportunistically enabled when
<a href=
"postscreen.8.html">postscreen(
8)
</a> has
491 to use the built-in SMTP engine anyway. This is to make
<a href=
"postscreen.8.html">postscreen(
8)
</a>
492 logging more informative.
</p>
494 <p> When a client sends multiple commands,
<a href=
"postscreen.8.html">postscreen(
8)
</a> logs this
498 <b>COMMAND PIPELINING from
</b> <i>[address]:port
</i> <b>after
</b> <i>command
</i>:
<i>text
</i>
501 <p> Translation: the SMTP client at
<i>[address]:port
</i> sent
502 multiple SMTP commands, instead of sending one command and then
503 waiting for the server to reply. This happened after the client
504 sent
<i>command
</i>. The
<i>text
</i> shows part of the input that
505 was sent too early; it is not logged with Postfix
2.8.
</p>
507 <p> The
<a href=
"postconf.5.html#postscreen_pipelining_action">postscreen_pipelining_action
</a> parameter specifies the action
508 that is taken next. See
"<a href="#fail_after_220
">When tests fail
509 after the 220 SMTP server greeting</a>" below.
</p>
511 <h3> <a name=
"non_smtp">Non-SMTP command test
</a> </h3>
513 <p> Some spambots send their mail through open proxies. A symptom
514 of this is the usage of commands such as CONNECT and other non-SMTP
515 commands. Just like the Postfix SMTP server's
<a href=
"postconf.5.html#smtpd_forbidden_commands">smtpd_forbidden_commands
</a>
516 feature,
<a href=
"postscreen.8.html">postscreen(
8)
</a> has an equivalent
<a href=
"postconf.5.html#postscreen_forbidden_commands">postscreen_forbidden_commands
</a>
517 feature to block these clients. postscreen(
8)'s
<a href=
"#after_220">deep
518 protocol test
</a> for this is disabled by default.
</p>
520 <p> With
"<a href="postconf
.5.html#postscreen_non_smtp_command_enable
">postscreen_non_smtp_command_enable</a> = yes",
<a href=
"postscreen.8.html">postscreen(
8)
</a>
521 detects zombies that send commands specified with the
522 <a href=
"postconf.5.html#postscreen_forbidden_commands">postscreen_forbidden_commands
</a> parameter. This also detects commands
523 with the syntax of a message header label. The latter is a symptom
524 that the client is sending message content after ignoring all the
525 responses from
<a href=
"postscreen.8.html">postscreen(
8)
</a> that reject mail.
</p>
527 <p> This test is opportunistically enabled when
<a href=
"postscreen.8.html">postscreen(
8)
</a> has
528 to use the built-in SMTP engine anyway. This is to make
<a href=
"postscreen.8.html">postscreen(
8)
</a>
529 logging more informative.
</p>
531 <p> When a client sends non-SMTP commands,
<a href=
"postscreen.8.html">postscreen(
8)
</a> logs this
535 <b>NON-SMTP COMMAND from
</b> <i>[address]:port command
</i>
538 <p> Translation: the SMTP client at
<i>[address]:port
</i> sent a
539 <i>command
</i> that matches the
<a href=
"postconf.5.html#postscreen_forbidden_commands">postscreen_forbidden_commands
</a>
540 parameter, or that has the syntax of a message header label.
</p>
542 <p> The
<a href=
"postconf.5.html#postscreen_non_smtp_command_action">postscreen_non_smtp_command_action
</a> parameter specifies
543 the action that is taken next. See
"<a href="#fail_after_220
">When
544 tests fail after the 220 SMTP server greeting</a>" below.
</p>
546 <h3> <a name=
"barelf">Bare newline test
</a> </h3>
548 <p> SMTP is a line-oriented protocol: lines have a limited length,
549 and are terminated with
<CR
><LF
>. Lines ending in a
550 "bare" <LF
>, that is newline not preceded by carriage return,
551 are not allowed in SMTP. postscreen(
8)'s
<a href=
"#after_220">deep
552 protocol test
</a> for this is disabled by default.
</p>
554 <p> With
"<a href="postconf
.5.html#postscreen_bare_newline_enable
">postscreen_bare_newline_enable</a> = yes",
<a href=
"postscreen.8.html">postscreen(
8)
</a>
555 detects clients that send lines ending in bare newline characters.
558 <p> This test is opportunistically enabled when
<a href=
"postscreen.8.html">postscreen(
8)
</a> has
559 to use the built-in SMTP engine anyway. This is to make
<a href=
"postscreen.8.html">postscreen(
8)
</a>
560 logging more informative.
</p>
562 <p> When a client sends bare newline characters,
<a href=
"postscreen.8.html">postscreen(
8)
</a> logs
567 <b>BARE NEWLINE from
</b> <i>[address]:port
</i>
570 <p> Translation: the SMTP client at
<i>[address]:port
</i> sent a bare
571 newline character, that is newline not preceded by carriage
574 <p> The
<a href=
"postconf.5.html#postscreen_bare_newline_action">postscreen_bare_newline_action
</a> parameter specifies the
575 action that is taken next. See
"<a href="#fail_after_220
">When
576 tests fail after the 220 SMTP server greeting</a>" below.
</p>
578 <h3> <a name=
"fail_after_220">When tests fail after the
220 SMTP server greeting
</a> </h3>
580 <p> When the client fails the pipelining, non-SMTP command or bare
581 newline tests, the action is specified with
<a href=
"postconf.5.html#postscreen_pipelining_action">postscreen_pipelining_action
</a>,
582 <a href=
"postconf.5.html#postscreen_non_smtp_command_action">postscreen_non_smtp_command_action
</a> or
<a href=
"postconf.5.html#postscreen_bare_newline_action">postscreen_bare_newline_action
</a>,
587 <dt> <b>ignore
</b> (default for bare newline)
</dt>
589 <dd> Ignore the failure of this test. Allow other tests to complete.
590 Do NOT repeat this test before the result from some other test
593 This option is useful for testing and collecting statistics without
594 blocking mail permanently.
</dd>
596 <dt> <b>enforce
</b> (default for pipelining)
</dt>
598 <dd> Allow other tests to complete. Reject attempts to deliver
599 mail with a
550 SMTP reply, and log the helo/sender/recipient
600 information. Repeat this test the next time the client connects.
603 <dt> <b>drop
</b> (default for non-SMTP commands)
</dt>
605 <dd> Drop the connection immediately with a
521 SMTP reply. Repeat
606 this test the next time the client connects. This action is
607 compatible with the Postfix SMTP server's
<a href=
"postconf.5.html#smtpd_forbidden_commands">smtpd_forbidden_commands
</a>
612 <h2> <a name=
"other_error">Other errors
</a> </h2>
614 <p> When an SMTP client hangs up unexpectedly during any tests,
615 <a href=
"postscreen.8.html">postscreen(
8)
</a> logs this as:
</p>
618 <b>HANGUP after
</b> <i>time
</i> <b>from
</b> <i>[address]:port
</i> <b>in
</b> <i>test name
</i>
621 <p> Translation: the SMTP client at
<i>[address]:port
</i> disconnected
622 unexpectedly,
<i>time
</i> seconds after the start of the
623 test named
<i>test name
</i>.
</p>
625 <p> There is no punishment for hanging up. A client that hangs up
626 without sending the QUIT command can still pass all
<a href=
"postscreen.8.html">postscreen(
8)
</a>
631 <p> While an unexpired penalty is in effect, an SMTP client is not
632 allowed to pass any tests, and <a href="postscreen.8.html">postscreen(8)</a> logs each connection
633 with the remaining amount of penalty time as: </p>
636 <b>PENALTY</b> <i>time</i> <b>for</b> <i>[address]:port</i>
639 <p> During this time, all attempts by the client to deliver mail
640 will be deferred with a 450 SMTP status. </p>
644 <p> The following errors are reported by the built-in SMTP engine.
645 This engine never accepts mail, therefore it has per-session limits
646 on the number of commands and on the session length.
</p>
649 <b>COMMAND TIME LIMIT
</b> <b>from
</b> <i>[address]:port
</i>
652 <p> Translation: the SMTP client at
<i>[address]:port
</i> reached the
653 per-command time limit as specified with the
<a href=
"postconf.5.html#postscreen_command_time_limit">postscreen_command_time_limit
</a>
654 parameter. The session is terminated immediately.
</p>
657 <b>COMMAND COUNT LIMIT from
</b> <i>[address]:port
</i>
660 <p> Translation: the SMTP client at
<i>[address]:port
</i> reached the
661 per-session command count limit as specified with the
662 <a href=
"postconf.5.html#postscreen_command_count_limit">postscreen_command_count_limit
</a> parameter. The session is terminated
666 <b>COMMAND LENGTH LIMIT from
</b> <i>[address]:port
</i>
669 <p> Translation: the SMTP client at
<i>[address]:port
</i> reached the
670 per-command length limit, as specified with the
<a href=
"postconf.5.html#line_length_limit">line_length_limit
</a>
671 parameter. The session is terminated immediately.
</p>
673 <p> When an SMTP client makes too many connections at the same time,
674 or when all
<a href=
"postscreen.8.html">postscreen(
8)
</a> ports are busy,
<a href=
"postscreen.8.html">postscreen(
8)
</a> rejects the
675 connection with a
421 status code and logs:
</p>
678 <b>NOQUEUE: reject: CONNECT from
</b> <i>[address]:port
</i><b>: too many connections
</b>
679 <b>NOQUEUE: reject: CONNECT from
</b> <i>[address]:port
</i><b>: all server ports busy
</b>
682 <p> The
<a href=
"postconf.5.html#postscreen_client_connection_count_limit">postscreen_client_connection_count_limit
</a> and
683 <a href=
"postconf.5.html#postscreen_pre_queue_limit">postscreen_pre_queue_limit
</a> parameters control these limits.
</p>
685 <h2> <a name=
"victory">When all tests succeed
</a> </h2>
687 <p> When a new SMTP client passes all tests (i.e. it is not whitelisted
688 via some mechanism),
<a href=
"postscreen.8.html">postscreen(
8)
</a> logs this as:
</p>
691 <b>PASS NEW
</b> <i>[address]:port
</i>
694 <p> Where
<i>[address]:port
</i> are the client IP address and port.
695 Then,
<a href=
"postscreen.8.html">postscreen(
8)
</a>
696 creates a temporary whitelist entry that excludes the client IP
697 address from further tests until the temporary whitelist entry
698 expires, as controlled with the postscreen_*_ttl parameters.
</p>
700 <p> When no
"<a href="#after_220
">deep protocol tests</a>" are
701 configured,
<a href=
"postscreen.8.html">postscreen(
8)
</a> hands off the
"live" connection to a Postfix
702 SMTP server process. The client can then continue as if
<a href=
"postscreen.8.html">postscreen(
8)
</a>
703 never even existed (except for the short
<a href=
"postconf.5.html#postscreen_greet_wait">postscreen_greet_wait
</a> delay).
706 <p> When any
"<a href="#after_220
">deep protocol tests</a>" are
707 configured,
<a href=
"postscreen.8.html">postscreen(
8)
</a> cannot hand off the
"live" connection to
708 a Postfix SMTP server process in the middle of the session. Instead,
709 <a href=
"postscreen.8.html">postscreen(
8)
</a> defers mail delivery attempts with a
4XX status, logs
710 the helo/sender/recipient information, and waits for the client to
711 disconnect. The next time the client connects it will be allowed
712 to talk to a Postfix SMTP server process to deliver its mail.
713 <a href=
"postscreen.8.html">postscreen(
8)
</a> mitigates the impact of this limitation by giving
714 <a href=
"#after_220">deep protocol tests
</a> a long expiration
717 <h2> <a name=
"config"> Configuring the postscreen(
8) service
</a>
720 <p> <a href=
"postscreen.8.html">postscreen(
8)
</a> has been tested on FreeBSD [
4-
8], Linux
2.[
4-
6]
721 and Solaris
9 systems.
</p>
725 <li> <a href=
"#enable"> Turning on postscreen(
8) without blocking
728 <li> <a href=
"#starttls"> postscreen(
8) TLS configuration
</a>
730 <li> <a href=
"#blocking"> Blocking mail with postscreen(
8)
</a>
732 <li> <a href=
"#turnoff"> Turning off postscreen(
8)
</a>
736 <h3> <a name=
"enable"> Turning on postscreen(
8) without blocking mail
</a> </h3>
738 <p> To enable the
<a href=
"postscreen.8.html">postscreen(
8)
</a> service and log client information
739 without blocking mail:
</p>
743 <li> <p> Make sure that local clients and systems with non-standard
744 SMTP implementations are excluded from any
<a href=
"postscreen.8.html">postscreen(
8)
</a> tests. The
745 default is to exclude all clients in
<a href=
"postconf.5.html#mynetworks">mynetworks
</a>. To exclude additional
746 clients, for example, third-party performance monitoring tools (these
747 tend to have broken SMTP implementations):
</p>
750 /etc/postfix/
<a href=
"postconf.5.html">main.cf
</a>:
751 # Exclude broken clients by whitelisting. Clients in
<a href=
"postconf.5.html#mynetworks">mynetworks
</a>
752 # should always be whitelisted.
753 <a href=
"postconf.5.html#postscreen_access_list">postscreen_access_list
</a> =
<a href=
"postconf.5.html#permit_mynetworks">permit_mynetworks
</a>,
754 <a href=
"cidr_table.5.html">cidr
</a>:/etc/postfix/postscreen_access.cidr
756 /etc/postfix/postscreen_access.
<a href=
"cidr_table.5.html">cidr
</a>:
757 192.168.254.0/
24 permit
760 <li> <p> Comment out the
"<tt>smtp inet ... smtpd</tt>" service
761 in
<a href=
"master.5.html">master.cf
</a>, including any
"<tt>-o parameter=value</tt>" entries
765 /etc/postfix/
<a href=
"master.5.html">master.cf
</a>:
766 #smtp inet n - n - - smtpd
767 # -o parameter=value ...
770 <li> <p> Uncomment the new
"<tt>smtpd pass ... smtpd</tt>" service
771 in
<a href=
"master.5.html">master.cf
</a>, and duplicate any
"<tt>-o parameter=value</tt>" entries
772 from the smtpd service that was commented out in the previous step.
776 /etc/postfix/
<a href=
"master.5.html">master.cf
</a>:
777 smtpd pass - - n - - smtpd
778 -o parameter=value ...
781 <li> <p> Uncomment the new
"<tt>smtp inet ... postscreen</tt>"
782 service in
<a href=
"master.5.html">master.cf
</a>.
</p>
785 /etc/postfix/
<a href=
"master.5.html">master.cf
</a>:
786 smtp inet n - n -
1 postscreen
789 <li> <p> Uncomment the new
"<tt>tlsproxy unix ... tlsproxy</tt>"
790 service in
<a href=
"master.5.html">master.cf
</a>. This service implements STARTTLS support for
791 <a href=
"postscreen.8.html">postscreen(
8)
</a>.
</p>
794 /etc/postfix/
<a href=
"master.5.html">master.cf
</a>:
795 tlsproxy unix - - n -
0 tlsproxy
798 <li> <p> Uncomment the new
"<tt>dnsblog unix ... dnsblog</tt>"
799 service in
<a href=
"master.5.html">master.cf
</a>. This service does DNSBL lookups for
<a href=
"postscreen.8.html">postscreen(
8)
</a>
800 and logs results.
</p>
803 /etc/postfix/
<a href=
"master.5.html">master.cf
</a>:
804 dnsblog unix - - n -
0 dnsblog
807 <li> <p> To enable DNSBL lookups, list some DNS blocklist sites in
808 <a href=
"postconf.5.html">main.cf
</a>, separated by whitespace. Different sites can have different
809 weights. For example:
812 /etc/postfix/
<a href=
"postconf.5.html">main.cf
</a>:
813 <a href=
"postconf.5.html#postscreen_dnsbl_threshold">postscreen_dnsbl_threshold
</a> =
2
814 <a href=
"postconf.5.html#postscreen_dnsbl_sites">postscreen_dnsbl_sites
</a> = zen.spamhaus.org*
2
815 bl.spamcop.net*
1 b.barracudacentral.org*
1
818 <p> Note: if your DNSBL queries have a
"secret" in the domain name,
819 you must censor this information from the
<a href=
"postscreen.8.html">postscreen(
8)
</a> SMTP replies.
823 /etc/postfix/
<a href=
"postconf.5.html">main.cf
</a>:
824 <a href=
"postconf.5.html#postscreen_dnsbl_reply_map">postscreen_dnsbl_reply_map
</a> =
<a href=
"DATABASE_README.html#types">texthash
</a>:/etc/postfix/dnsbl_reply
828 /etc/postfix/dnsbl_reply:
829 # Secret DNSBL name Name in
<a href=
"postscreen.8.html">postscreen(
8)
</a> replies
830 secret.zen.spamhaus.org zen.spamhaus.org
833 <p> The
<a href=
"DATABASE_README.html#types">texthash
</a>: format is similar to hash: except that there is
834 no need to run
<a href=
"postmap.1.html">postmap(
1)
</a> before the file can be used, and that it
835 does not detect changes after the file is read. It is new with
836 Postfix version
2.8.
</p>
838 <li> <p> Read the new configuration with
"<tt>postfix reload</tt>".
847 <li> <p> Some
<a href=
"postscreen.8.html">postscreen(
8)
</a> configuration parameters implement
848 stress-dependent behavior. This is supported only when the default
849 value is stress-dependent (that is,
"postconf -d <i>parametername</i>"
850 output shows
"<i>parametername</i> =
851 ${stress?<i>something</i>}${stress:<i>something</i>}").
852 Other parameters always evaluate as if the stress value is the empty
855 <li> <p> See
"<a href="#before_220
">Tests before the 220 SMTP server
856 greeting</a>" for details about the logging from these postscreen(
8)
859 <li> <p> If you run Postfix
2.6 or earlier you must stop and start
860 the master daemon (
"<tt>postfix stop; postfix start</tt>"). This
861 is needed because the Postfix
"pass" master service type did not
862 work reliably on all systems.
</p>
866 <h3> <a name=
"starttls"> postscreen(
8) TLS configuration
</a> </h3>
868 <p> <a href=
"postscreen.8.html">postscreen(
8)
</a> TLS support is available for remote SMTP clients
869 that aren't whitelisted, including clients that need to renew their
870 temporary whitelist status. When a remote SMTP client requests TLS
871 service,
<a href=
"postscreen.8.html">postscreen(
8)
</a> invisibly hands off the connection to a
872 <a href=
"tlsproxy.8.html">tlsproxy(
8)
</a> process. Then,
<a href=
"tlsproxy.8.html">tlsproxy(
8)
</a> encrypts and decrypts the
873 traffic between
<a href=
"postscreen.8.html">postscreen(
8)
</a> and the remote SMTP client. One
874 <a href=
"tlsproxy.8.html">tlsproxy(
8)
</a> process can handle multiple SMTP sessions. The number
875 of
<a href=
"tlsproxy.8.html">tlsproxy(
8)
</a> processes slowly increases with server load, but it
876 should always be much smaller than the number of
<a href=
"postscreen.8.html">postscreen(
8)
</a> TLS
879 <p> TLS support for
<a href=
"postscreen.8.html">postscreen(
8)
</a> and
<a href=
"tlsproxy.8.html">tlsproxy(
8)
</a> uses the same
880 parameters as with
<a href=
"smtpd.8.html">smtpd(
8)
</a>. We recommend that you keep the relevant
881 configuration parameters in
<a href=
"postconf.5.html">main.cf
</a>. If you must specify
"-o
882 smtpd_mumble=value" parameter overrides in
<a href=
"master.5.html">master.cf
</a> for a
883 postscreen-protected
<a href=
"smtpd.8.html">smtpd(
8)
</a> service, then you should specify those
884 same parameter overrides for the
<a href=
"postscreen.8.html">postscreen(
8)
</a> and
<a href=
"tlsproxy.8.html">tlsproxy(
8)
</a>
887 <h3> <a name=
"blocking"> Blocking mail with postscreen(
8)
</a> </h3>
889 <p> For compatibility with
<a href=
"smtpd.8.html">smtpd(
8)
</a>,
<a href=
"postscreen.8.html">postscreen(
8)
</a> implements the
890 <a href=
"postconf.5.html#soft_bounce">soft_bounce
</a> safety feature. This causes Postfix to reject mail with
891 a
"try again" reply code.
</p>
895 <li> <p> To turn this on for all of Postfix, specify
"<tt><a href="postconf
.5.html#soft_bounce
">soft_bounce</a>
896 = yes</tt>" in
<a href=
"postconf.5.html">main.cf
</a>.
</p>
898 <li> <p> To turn this on for
<a href=
"postscreen.8.html">postscreen(
8)
</a> only, append
"<tt>-o
899 <a href="postconf
.5.html#soft_bounce
">soft_bounce</a>=yes</tt>" (note: NO SPACES around '=') to the postscreen
900 entry in
<a href=
"master.5.html">master.cf
</a>.
<p>
904 <p> Execute
"<tt>postfix reload</tt>" to make the change effective.
</p>
906 <p> After testing, do not forget to remove the
<a href=
"postconf.5.html#soft_bounce">soft_bounce
</a> feature,
907 otherwise senders won't receive their non-delivery notification
908 until many days later.
</p>
910 <p> To use the
<a href=
"postscreen.8.html">postscreen(
8)
</a> service to block mail, edit
<a href=
"postconf.5.html">main.cf
</a> and
911 specify one or more of:
</p>
915 <li> <p> "<tt><a href="postconf
.5.html#postscreen_dnsbl_action
">postscreen_dnsbl_action</a> = enforce</tt>", to reject
916 clients that are on DNS blocklists, and to log the helo/sender/recipient
917 information. With good DNSBLs this reduces the amount of load on
918 Postfix SMTP servers dramatically.
</p>
920 <li> <p> "<tt><a href="postconf
.5.html#postscreen_greet_action
">postscreen_greet_action</a> = enforce</tt>", to reject
921 clients that talk before their turn, and to log the helo/sender/recipient
922 information. This stops over half of all known-to-be illegitimate
923 connections to Wietse's mail server. It is backup protection for
924 zombies that haven't yet been blacklisted.
</p>
926 <li> <p> You can also enable
"<a href="#after_220
">deep protocol
927 tests</a>", but these are more intrusive than the pregreet or DNSBL
930 <p> When a good client passes the
"<a href="#after_220
">deep
931 protocol tests</a>", postscreen(
8) adds the client to the temporary
932 whitelist but it cannot hand off the
"live" connection to a Postfix
933 SMTP server process in the middle of the session. Instead,
<a href=
"postscreen.8.html">postscreen(
8)
</a>
934 defers mail delivery attempts with a
4XX status, logs the
935 helo/sender/recipient information, and waits for the client to
938 <p> When the good client comes back in a later session, it is allowed
939 to talk directly to a Postfix SMTP server. See
"after_220 <a
940 href="#after_220
">Tests after the 220 SMTP server greeting</a> above
941 for limitations with AUTH and other features that clients may need.
944 <p> An unexpected benefit from "<a href=
"#after_220">deep protocol
945 tests
</a>" is that some "good
" clients don't return after the 4XX
946 reply; these clients were not so good after all. Wietse enables
947 "<a href=
"#after_220">deep protocol tests
</a>" on his own internet-facing
950 <li> <p> There is also support for permanent blacklisting and
951 whitelisting; see the description of the <a href="postconf
.5.html#postscreen_access_list
">postscreen_access_list</a>
952 parameter for details. </p>
956 <h3> <a name="turnoff
"> Turning off postscreen(8) </a> </h3>
958 <p> To turn off <a href="postscreen
.8.html
">postscreen(8)</a> and handle mail directly with Postfix
959 SMTP server processes: </p>
963 <li> <p> Comment out the "<tt>smtp inet ... postscreen
</tt>" service
964 in <a href="master
.5.html
">master.cf</a>, including any "<tt>-o parameter=value
</tt>" entries
968 /etc/postfix/<a href="master
.5.html
">master.cf</a>:
969 #smtp inet n - n - 1 postscreen
970 # -o parameter=value ...
973 <li> <p> Comment out the "<tt>dnsblog unix ... dnsblog
</tt>" service
974 in <a href="master
.5.html
">master.cf</a>. </p>
977 /etc/postfix/<a href="master
.5.html
">master.cf</a>:
978 #dnsblog unix - - n - 0 dnsblog
981 <li> <p> Comment out the "<tt>smtpd pass ... smtpd
</tt>" service
982 in <a href="master
.5.html
">master.cf</a>, including any "<tt>-o parameter=value
</tt>" entries
986 /etc/postfix/<a href="master
.5.html
">master.cf</a>:
987 #smtpd pass - - n - - smtpd
988 # -o parameter=value ...
991 <li> <p> Comment out the "<tt>tlsproxy unix ... tlsproxy
</tt>"
992 service in <a href="master
.5.html
">master.cf</a>, including any "<tt>-o parameter=value
</tt>"
993 entries that follow. </p>
996 /etc/postfix/<a href="master
.5.html
">master.cf</a>:
997 #tlsproxy unix - - n - 0 tlsproxy
998 # -o parameter=value ...
1001 <li> <p> Uncomment the "<tt>smtp inet ... smtpd
</tt>" service in
1002 <a href="master
.5.html
">master.cf</a>, including any "<tt>-o parameter=value
</tt>" entries that
1006 /etc/postfix/<a href="master
.5.html
">master.cf</a>:
1007 smtp inet n - n - - smtpd
1008 -o parameter=value ...
1011 <li> <p> Read the new configuration with "<tt>postfix reload
</tt>".
1016 <h2> <a name="historical
"> Historical notes and credits </a> </h2>
1018 <p> Many ideas in <a href="postscreen
.8.html
">postscreen(8)</a> were explored in earlier work by
1019 Michael Tokarev, in OpenBSD spamd, and in MailChannels Traffic
1022 <p> Wietse threw together a crude prototype with pregreet and dnsbl
1023 support in June 2009, because he needed something new for a Mailserver
1024 conference presentation in July. Ralf Hildebrandt ran this code on
1025 several servers to collect real-world statistics. This version used
1026 the <a href="dnsblog
.8.html
">dnsblog(8)</a> ad-hoc DNS client program. </p>
1028 <p> Wietse needed new material for a LISA conference presentation
1029 in November 2010, so he added support for DNSBL weights and filters
1030 in August, followed by a major code rewrite, deep protocol tests,
1031 helo/sender/recipient logging, and stress-adaptive behavior in
1032 September. Ralf Hildebrandt ran this code on several servers to
1033 collect real-world statistics. This version still used the embarrassing
1034 <a href="dnsblog
.8.html
">dnsblog(8)</a> ad-hoc DNS client program. </p>
1036 <p> Wietse added STARTTLS support in December 2010. This makes
1037 <a href="postscreen
.8.html
">postscreen(8)</a> usable for sites that require TLS support. The
1038 implementation introduces the <a href="tlsproxy
.8.html
">tlsproxy(8)</a> event-driven TLS proxy
1039 that decrypts/encrypts the sessions for multiple SMTP clients. </p>